v0.14.0 - DSH integration + architecture deepening
v0.14.0 - DSH integration + architecture deepening
Released 2026-08-14.
Minor: DSH (DeepSeek Harness) plugin integration lands as a third install
surface alongside Claude Code and Codex. Six architecture deepenings
eliminate duplication across the preview and evidence runtimes.
DSH plugin integration (Issues #15-#20)
Three-phase integration: P0 skills softlink → P1 npm bundle → P2 MCP bridge
- commands. All three verified by real DSH boot smoke tests.
P1: npm bundle + skills provider (Issue #17)
packages/design-playbook/lib/index.js— Cordis plugin entry; registers
8 skills onctx.skillsviaregisterProvider()+__dirname(the
!!jsevaluation scope has norequire, socustomSkillDirscannot
point into package resources).packages/design-playbook/cordis.patch.yml— one bundle patch row
mounting the plugin by package name.packages/design-playbook/package.json— addsdsh.bundle.patch+
dsh-plugin/dsh-bundlekeywords +main+libinfiles[].
P2: MCP bridge (Issue #19)
packages/dsh-design-playbook/— thin npm bundle package depending on
design-playbook. Itscordis.patch.ymlbridges preview + evidence
MCP servers via@deepseek-ai/dsh-mcp-clientstdio.- Path resolution uses
process.getBuiltinModule('node:module') .createRequire(baseUrl).resolve(...)— DSH!!jsscope has no
requirebut exposesbaseUrl(profile dir), socreateRequire
resolvesdesign-playbookfrom the profile'snode_modules. - DSH smoke verified: both MCP tools register +
tools/callround-trip
passes (preview returns "summary is required"; evidence rejects
missingschemaVersionper ADR-0018 fail-closed).
P2: commands (Issue #20)
lib/index.jsextended:injectgrows to['skills', 'commands'];
apply()registers 6 slash commands (design-io,doctor,
run-review,run-status,ui-review,ux-spec).- Each handler loads
commands/<name>.md, substitutes$ARGUMENTS,
and injects viaagent.followup()(notinject()— slash commands
are explicit user actions that open a turn). - DSH smoke verified: 6 commands register;
/design-io <args>executes,
handler callsagent.followup()with the substituted prompt; frontmatter
stripped;$ARGUMENTSsubstituted; unknown commands rejected. - Full interactive round-trip verified: preview server starts on fixed
port, Chrome app window launches, HTTP POST auto-submits confirm form,
transaction returnsconfirmed=true+floor_pass=true, decision entry
written to disk.
Architecture deepening
Binding digest unification
compute_binding_digest()moves tointegrity.pyas the single source
for the binding shape (canonical JSON + SHA-256).transaction.py
write side andload_entry()read side both import it; G5 gate
_valid_decision_entry()consumes the same function. Three independent
implementations collapse to one.
Prototype resolution unification
_resolve_prototype()extracts the path/html resolution + digest
computation that was duplicated 3× intransaction.py. Pre-lock
binding and in-lock TOCTOU re-validation share one function.
Action dispatch registry
_run_actions75-line if/elif chain →_ACTION_HANDLERSdict mapping
do→ handler function. Each handler owns its validation + Playwright
call. Adding an action type adds a function + one entry, not an elif.
Evidence runtime-object validation
_validate_runtime_object()extracts url/type/state/actions validation
fromexecute_capture_planso the handler reads cleanly.
Preview server argument validation
_validate_preview_args()extracts the 6-field validation from
handle_preview_prototype.
Dead code + duplication cleanup
_log()duplication removed (capture_runtime.pyimports from
util.py). Dead_require_str()removed.type: ignorereplaced
withassert.