@mstar-harness/dsh 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.i18n.yaml +7 -0
  2. package/README.md +448 -0
  3. package/README.zh.md +221 -0
  4. package/bundle/README.md +312 -0
  5. package/bundle/cordis.patch.yml +17 -0
  6. package/dist/client/index.d.ts +14 -0
  7. package/dist/client/panel/PanelView.d.ts +67 -0
  8. package/dist/client/panel/TabNav.d.ts +28 -0
  9. package/dist/client/panel/graph/event-log.d.ts +76 -0
  10. package/dist/client/panel/graph/project-graph.d.ts +499 -0
  11. package/dist/client/panel/graph/schema.d.ts +224 -0
  12. package/dist/client/panel/guards.d.ts +12 -0
  13. package/dist/client/panel/locale.d.ts +134 -0
  14. package/dist/client/panel/pages/AgentCanvasPage.d.ts +363 -0
  15. package/dist/client/panel/pages/EventLogPage.d.ts +48 -0
  16. package/dist/client/panel/pages/IterationInfoSection.d.ts +80 -0
  17. package/dist/client/panel/pages/IterationTaskPage.d.ts +37 -0
  18. package/dist/client/panel/panel-meta.d.ts +18 -0
  19. package/dist/client/panel/plan-sort.d.ts +54 -0
  20. package/dist/client/panel/sidebar.d.ts +17 -0
  21. package/dist/client/panel/state-section.d.ts +23 -0
  22. package/dist/client/panel/use-mstar-engine-status.d.ts +42 -0
  23. package/dist/client/panel/zones/Legend.d.ts +18 -0
  24. package/dist/client/panel/zones/TaskBoard.d.ts +40 -0
  25. package/dist/client.d.ts +1 -0
  26. package/dist/client.js +4486 -0
  27. package/dist/gates/_shared.d.ts +198 -0
  28. package/dist/gates/adapter.d.ts +131 -0
  29. package/dist/gates/agent-flow.d.ts +320 -0
  30. package/dist/gates/catalog.d.ts +118 -0
  31. package/dist/gates/dispatch.d.ts +152 -0
  32. package/dist/gates/seams.d.ts +152 -0
  33. package/dist/gates/skill-lint.d.ts +87 -0
  34. package/dist/gates/status.d.ts +81 -0
  35. package/dist/gates/tools.d.ts +37 -0
  36. package/dist/index.d.ts +107 -0
  37. package/dist/index.js +5748 -0
  38. package/dist/invariant.d.ts +15 -0
  39. package/dist/invariant.js +29 -0
  40. package/dist/service.d.ts +96 -0
  41. package/dist/types.d.ts +241 -0
  42. package/harness-commands/codebase-audit.md +40 -0
  43. package/harness-commands/iteration-drive.md +129 -0
  44. package/harness-commands/iteration-loop.md +139 -0
  45. package/harness-commands/iteration-start.md +179 -0
  46. package/harness-skills/grill-me/SKILL.md +10 -0
  47. package/harness-skills/mstar-audit/SKILL.md +183 -0
  48. package/harness-skills/mstar-audit/references/audit-playbook.md +130 -0
  49. package/harness-skills/mstar-audit/references/finding-format.md +65 -0
  50. package/harness-skills/mstar-branch-worktree/SKILL.md +219 -0
  51. package/harness-skills/mstar-branch-worktree/references/parallel-writable-pre-dispatch.md +68 -0
  52. package/harness-skills/mstar-coding-behavior/SKILL.md +147 -0
  53. package/harness-skills/mstar-compound/SKILL.md +105 -0
  54. package/harness-skills/mstar-compound/assets/resolution-template.md +94 -0
  55. package/harness-skills/mstar-compound/references/category-mapping.md +37 -0
  56. package/harness-skills/mstar-compound/references/compound-workflow.md +155 -0
  57. package/harness-skills/mstar-compound/references/concepts-vocabulary.md +44 -0
  58. package/harness-skills/mstar-compound/references/schema.yaml +122 -0
  59. package/harness-skills/mstar-compound-refresh/SKILL.md +140 -0
  60. package/harness-skills/mstar-compound-refresh/references/project-knowledge-bootstrap.md +164 -0
  61. package/harness-skills/mstar-design-md/SKILL.md +142 -0
  62. package/harness-skills/mstar-design-md/references/completeness-checklist.md +181 -0
  63. package/harness-skills/mstar-design-md/references/design-md-spec.md +508 -0
  64. package/harness-skills/mstar-design-md/references/vercel-example.md +200 -0
  65. package/harness-skills/mstar-design-md/templates/DESIGN.dark.md.template +354 -0
  66. package/harness-skills/mstar-design-md/templates/DESIGN.md.template +474 -0
  67. package/harness-skills/mstar-dispatch-gates/SKILL.md +128 -0
  68. package/harness-skills/mstar-dispatch-gates/references/leaf-executor-checklist.md +23 -0
  69. package/harness-skills/mstar-harness-core/SKILL.md +180 -0
  70. package/harness-skills/mstar-host/SKILL.md +78 -0
  71. package/harness-skills/mstar-host/references/_shared/host-role-binding-core.md +51 -0
  72. package/harness-skills/mstar-host/references/_shared/plan-mode-bridge-core.md +91 -0
  73. package/harness-skills/mstar-host/references/codex.md +61 -0
  74. package/harness-skills/mstar-host/references/cursor-plan-mode-bridge.md +159 -0
  75. package/harness-skills/mstar-host/references/cursor.md +183 -0
  76. package/harness-skills/mstar-host/references/dsh.md +502 -0
  77. package/harness-skills/mstar-host/references/kimi-plan-mode-bridge.md +36 -0
  78. package/harness-skills/mstar-host/references/kimi.md +136 -0
  79. package/harness-skills/mstar-host/references/omp-plan-mode-bridge.md +32 -0
  80. package/harness-skills/mstar-host/references/omp.md +244 -0
  81. package/harness-skills/mstar-host/references/opencode.md +76 -0
  82. package/harness-skills/mstar-host/references/parallel-dispatch.md +68 -0
  83. package/harness-skills/mstar-host/references/zcode-plan-mode-bridge.md +36 -0
  84. package/harness-skills/mstar-host/references/zcode.md +129 -0
  85. package/harness-skills/mstar-iteration/SKILL.md +393 -0
  86. package/harness-skills/mstar-iteration/references/autonomous-direction-lock.md +90 -0
  87. package/harness-skills/mstar-iteration/references/iteration-artifact-boundaries.md +103 -0
  88. package/harness-skills/mstar-iteration/references/iteration-compass-template.md +142 -0
  89. package/harness-skills/mstar-iteration/references/iteration-corpus-hygiene.md +45 -0
  90. package/harness-skills/mstar-iteration/references/iteration-workspace-readme-template.md +27 -0
  91. package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +193 -0
  92. package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +95 -0
  93. package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +84 -0
  94. package/harness-skills/mstar-iteration/references/phase5-helper-discovery.md +24 -0
  95. package/harness-skills/mstar-phase-gates/SKILL.md +112 -0
  96. package/harness-skills/mstar-plan-artifacts/SKILL.md +46 -0
  97. package/harness-skills/mstar-plan-artifacts/references/done-compaction.md +88 -0
  98. package/harness-skills/mstar-plan-artifacts/references/knowledge-and-designs.md +100 -0
  99. package/harness-skills/mstar-plan-artifacts/references/plan-files-and-reports.md +99 -0
  100. package/harness-skills/mstar-plan-artifacts/references/plan-quality-bar.md +99 -0
  101. package/harness-skills/mstar-plan-artifacts/references/status-and-residuals.md +570 -0
  102. package/harness-skills/mstar-plan-artifacts/templates/README.md +9 -0
  103. package/harness-skills/mstar-plan-artifacts/templates/notes.empty.json +5 -0
  104. package/harness-skills/mstar-plan-artifacts/templates/plan.main.md +54 -0
  105. package/harness-skills/mstar-plan-artifacts/templates/plans-done.empty.json +3 -0
  106. package/harness-skills/mstar-plan-artifacts/templates/status.empty.json +7 -0
  107. package/harness-skills/mstar-plan-conventions/SKILL.md +165 -0
  108. package/harness-skills/mstar-plan-conventions/references/artifact-storage-paths.md +50 -0
  109. package/harness-skills/mstar-plan-conventions/references/effort-estimation.md +38 -0
  110. package/harness-skills/mstar-plan-conventions/references/harness-bootstrap-and-agents-layering.md +93 -0
  111. package/harness-skills/mstar-review-qc/SKILL.md +60 -0
  112. package/harness-skills/mstar-review-qc/references/review-responsibility-boundaries.md +54 -0
  113. package/harness-skills/mstar-roles/SKILL.md +86 -0
  114. package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +46 -0
  115. package/harness-skills/mstar-roles/references/architect.md +114 -0
  116. package/harness-skills/mstar-roles/references/code-reviewer.md +109 -0
  117. package/harness-skills/mstar-roles/references/frontend-dev.md +70 -0
  118. package/harness-skills/mstar-roles/references/fullstack-dev-shared.md +89 -0
  119. package/harness-skills/mstar-roles/references/ops-engineer.md +78 -0
  120. package/harness-skills/mstar-roles/references/product-manager.md +107 -0
  121. package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +198 -0
  122. package/harness-skills/mstar-roles/references/project-manager/plan-management.md +61 -0
  123. package/harness-skills/mstar-roles/references/project-manager/qa-trigger-matrix.md +56 -0
  124. package/harness-skills/mstar-roles/references/project-manager/qc-and-residuals.md +98 -0
  125. package/harness-skills/mstar-roles/references/project-manager/routing-and-dev-allocation.md +99 -0
  126. package/harness-skills/mstar-roles/references/project-manager.md +310 -0
  127. package/harness-skills/mstar-roles/references/prompt-engineer.md +71 -0
  128. package/harness-skills/mstar-roles/references/qa-engineer/acceptance-gate.md +62 -0
  129. package/harness-skills/mstar-roles/references/qa-engineer.md +79 -0
  130. package/harness-skills/mstar-roles/references/qc-specialist/deep-review-lenses.md +95 -0
  131. package/harness-skills/mstar-roles/references/qc-specialist/report-template.md +72 -0
  132. package/harness-skills/mstar-roles/references/qc-specialist/reviewer-checklist.md +44 -0
  133. package/harness-skills/mstar-roles/references/qc-specialist/reviewer-workflow.md +57 -0
  134. package/harness-skills/mstar-roles/references/qc-specialist-shared.md +128 -0
  135. package/harness-skills/mstar-roles/references/writing-specialist.md +59 -0
  136. package/harness-skills/mstar-sdd/SKILL.md +133 -0
  137. package/harness-skills/mstar-sdd/references/file-handoffs.md +83 -0
  138. package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +44 -0
  139. package/harness-skills/mstar-sdd/references/implementer-prompt.md +56 -0
  140. package/harness-skills/mstar-sdd/references/sticky-implementer-session.md +103 -0
  141. package/harness-skills/mstar-sdd/references/task-reviewer-prompt.md +53 -0
  142. package/harness-skills/mstar-skill-authoring/SKILL.md +162 -0
  143. package/harness-skills/mstar-skill-authoring/references/skillsbench-authoring.md +117 -0
  144. package/harness-skills/mstar-strategy/SKILL.md +130 -0
  145. package/harness-skills/pm/SKILL.md +40 -0
  146. package/package.json +92 -0
@@ -0,0 +1,7 @@
1
+ # Translation pairing record for the @mstar-harness/dsh package README pair.
2
+ # Blob hashes (git hash-object) of each side as of the last confirmation that
3
+ # both languages say the same thing (dsh i18n contract: a pair is three
4
+ # sibling files; editing either side obligates re-confirming and re-recording).
5
+ README.md: 434e59e4b73e42e21cd197e9a9fc82c2c33ffe48
6
+ README.zh.md: 5461cb3bd91b2189d867e3dc126519150c471830
7
+
package/README.md ADDED
@@ -0,0 +1,448 @@
1
+ # @mstar-harness/dsh
2
+
3
+ English | [中文](README.zh.md)
4
+
5
+ [Morning Star](https://github.com/btspoony/mstar-harness) as a first-class dsh (DeepSeek Harness) host — a cordis function plugin that mounts the mstar engine in-process, implements the engine `HostAdapter` (`host: 'dsh'`), guards `{HARNESS_DIR}/status.json` writes (validate + advisory; repair-escape under hard), blocks disallowed subagent dispatches when `Enforcement: hard` is on, lints `SKILL.md` writes under the mounted skill roots, mounts the mstar `skills/` mirror through the dsh skill-filesystem provider (single canonical mount), and appends a durable `mstar-engine-status` catalog row to every composed agent step. Boot with a dsh Loader app; everything acts through the seam's refusal/advisory channels, never by patching the tools.
6
+
7
+ ## Usage
8
+
9
+ How a dsh app consumes the plugin — install paths, configuration, what mounts at boot, and the enforcement semantics.
10
+
11
+ ### Install paths
12
+
13
+ The package ships as a workspace package (`workspaces: ["packages/*"]`) with the engine bundled into `dist/` at build time (`bun run build`; dist is gitignored). The install path is the **profile bundle**, added to the shipped `web` profile (`dsh --profile web` — the ready-made web app profile, `dsh web`), through the `dsh.bundle.patch` manifest — a patch layer mounted over the dsh-base defaults:
14
+
15
+ **(a) Registry install (published form)** — the npm package carries the built `dist/` (no build step on install):
16
+
17
+ ```sh
18
+ dsh plugin --profile web add @mstar-harness/dsh
19
+ ```
20
+
21
+ **(b) Local checkout install (dev)** — the package checkout itself, for iterating on the plugin:
22
+
23
+ ```sh
24
+ cd <repo>/packages/dsh
25
+ dsh plugin --profile web add .
26
+ ```
27
+
28
+ `dsh plugin --profile <name> add <spec>` initializes the profile on first use (`web` starts from the shipped template: `@deepseek-ai/dsh-base` + `@deepseek-ai/dsh-web-app`), forwards `<spec>` to pnpm in the profile directory, and reconciles the profile's `dsh.profile.bundles` layer list from the installed state: any dependency whose package.json declares `dsh.bundle` joins the layer stack. Relative specs (`.`, `file:`/`link:`) anchor to the invoking directory, so `add .` runs from the package checkout; pnpm must be on PATH. A local checkout needs a prior `bun run build` (the `prepare` script is intentionally NOT used — the monorepo builds packages explicitly, matching cli/opencode).
29
+
30
+ ### Configuration
31
+
32
+ | Key | Type | Default | Meaning |
33
+ | --- | --- | --- | --- |
34
+ | `harnessDir` | `string` | per-session workspace probe (`.mstar/` → `.agents/` → `.plans/` → `plans/`, from the session workspace root — **never the launch cwd**) | Explicit harness root; wins over engine probing. **Required for repos whose harness root is not a probed name** — e.g. this mstar-workflow repo itself uses `.harness/` (maintenance root, deliberately NOT probed); the probe starts from the session workspace root (never the launch cwd) and STOPS there — it never walks above the session workspace, so a harness dir above it (e.g. a global `~/.mstar`) is never adopted. |
35
+ | `enforcement` | `'hard' \| 'soft'` | compass, else warn-only | Per-deployment override. Precedence: Config wins; else the Assignment's own `**Enforcement**: hard` header flag (dispatch gate only); else the iteration compass frontmatter; else warn-only. Config `soft` is the ONLY local rollback — an Assignment-level `soft` does NOT override a hard compass. |
36
+ | `dispatchTools` | `string[]` | `['subagent']` | Delegation tool names the dispatch gate matches (the dsh subagent tool's `toolName` may rename instances). |
37
+ | `dispatchBinding` | `string` | unset (precheck skipped) | The dispatching agent's own harness role; an Assignment whose `Execute as` equals it is self-recursion. |
38
+ | `skillRoots` | `string[]` | unset (no custom-root registration) | Additional skill roots registered with the dsh skill-filesystem provider (`customSkillDirs` semantics — scanned before user roots). Dev-time: the mirror `<repo-root>/skills` absolute path. |
39
+ | `bundledSkillDir` | `string` | packaged `harness-skills/` mirror (package-relative) | Bundled skill root registered with the dsh skill-filesystem provider (`bundledSkillDir` semantics — scanned last, trusted). Defaults to the package's OWN `harness-skills/` mirror (synced by `bundle-assets`; gitignored) — package-relative, NOT cwd-anchored. An explicit value wins. |
40
+ | `catalogTtlMs` | `number` | `60000` | Pre-step catalog cache refresh interval (ms): how often the per-workspace unified `mstar-engine-status` catalog row (watermark + iteration gate + workspace-state digest) re-reads `status.json` / the compass / the knowledge index. The hot path is a timestamp compare + cache hit between refreshes; a mid-session plan/compass/residual change lands within one interval. |
41
+
42
+ `bundledSkillDir` defaults to the package's OWN `harness-skills/` mirror (see Skills mount) — an explicit Config value still wins. A relative override remains **cwd-anchored** (skill-filesystem `join()` semantics against the dsh process cwd), so deployments overriding the default should pass an **absolute path in the profile layer** (see `bundle/README.md`).
43
+
44
+ ### Composed row set
45
+
46
+ The profile bundle composes the following rows — the registry rows come from the `@deepseek-ai/dsh-base` layer, and this bundle's patch inserts the `mstar` row over them with neutral defaults (the row set the full-app e2e fixture boots):
47
+
48
+ ```yaml
49
+ - name: '@deepseek-ai/dsh-skill' # skill registry (ctx.skills) — dsh-base row
50
+ - name: '@deepseek-ai/dsh-tools' # tool registry (ctx.tools) — dsh-base row
51
+ - name: '@deepseek-ai/dsh-commands' # command registry (ctx.commands) — dsh-base row
52
+ - name: '@mstar-harness/dsh' # this bundle's patch insert (config: {} — plugin defaults apply)
53
+ ```
54
+
55
+ The registry rows mount before the plugin so `ctx.skills` / `ctx.tools` / `ctx.commands` exist when the mstar gates, seam tools, and bundled commands register.
56
+
57
+ ### What the plugin does when mounted
58
+
59
+ - **Status gate** — `fs/write-intent` + `fs/edit-intent` listeners validate `{HARNESS_DIR}/status.json` writes (engine `validateStatus` + per-plan `findingsCleanupGate` over the pre-write document).
60
+ - **Dispatch gate** — a `tools/pre-execute` listener on the delegation tool(s) validates subagent Assignment text through the engine's single `composeDispatchGate` composition (field gate, anti-recursion precheck, default-branch gate — opencode/omp/CLI parity, so violation codes are identical by construction) plus the dsh lease gate and worktree L1/L2 checks.
61
+ - **Skill-authoring lint** — `SKILL.md` writes under the configured skill roots run the engine skill-authoring lints (`lintFrontmatter` + `lintFiveQuestion`).
62
+ - **Seam lints** — `DESIGN.md` / audit-plan / knowledge-doc / roles-dir writes under the harness get their artifact-specific engine lints.
63
+ - **Model-facing tools** — `mstar_sdd_workspace`, `mstar_sdd_task_brief`, `mstar_iteration_gate`, `mstar_design_md_validate`, `mstar_audit_validate`, `mstar_compound_validate`, `mstar_roles_validate` register on `ctx.tools`.
64
+ - **Bundled commands** — `ctx.commands` registrations for `/iteration-start`, `/iteration-drive`, `/iteration-loop`, `/codebase-audit` (from the packaged `harness-commands/` mirror; each declares a frontmatter `input` hint so the web client claims `/name ` and waits for the user's follow-up args instead of executing immediately; handlers steer the command body + user args into the receiving agent).
65
+ - **Pre-step catalog row** — every composed agent step appends ONE unified `mstar-engine-status` catalog message: the watermark (unified mstar version, harness dir, enforcement), the iteration phase-gate section (when a steering compass resolves) and the workspace-state digest (plan registry, open residuals, branch/policy anchors, active leases, knowledge digest, compass direction — when the workspace has a `status.json`). The row is digest-gated (injected once per turn, re-injected only when it changed) and shares one TTL-cached per-workspace build (`catalogTtlMs`, default 60 s).
66
+
67
+ ### Enforcement semantics
68
+
69
+ Warn-only by default: gate violations log and emit advisory events (`mstar/status-gate`, `mstar/dispatch-gate`, `mstar/skill-lint`, seam advisories) and the action proceeds. `Enforcement: hard` — from the iteration compass frontmatter, the Assignment header, or the plugin Config (`enforcement: hard`) — escalates violations to a **real veto/deny** through the cordis refusal channels: subagent dispatch returns `PreToolDecision { kind: 'deny', reason }` without delegating; status/skill-lint writes are never hard-vetoed because the intent waterfall is content-blind — an already-invalid document is allowed as a **repair escape** (`hard: true, repair: true` advisory) so the repairing write can land. Config `soft` is the only local rollback; hard gates are never a global default.
70
+
71
+ ## Gates
72
+
73
+ ### Status gate
74
+
75
+ `fs/write-intent` + `fs/edit-intent` listeners (registered `prepend` so they run before dsh-fs-policy) gate writes to `{HARNESS_DIR}/status.json`: `validateStatus` + per-plan `findingsCleanupGate` over the current on-disk document (parsed exactly once — no TOCTOU double read). The gate **never throws**: every decision surfaces as the `mstar/status-gate` advisory and the intent waterfall is delegated via `next()`. Warn mode (default) logs + emits on violations. Hard mode allows an **already-invalid** document as a **repair escape** (error-level log + advisory with `hard: true, repair: true`) — the intent waterfall carries no incoming content, so a hard veto on an invalid document would deadlock the very write that repairs it. Unexpected internal errors degrade to allow in BOTH modes with a `degraded: true` advisory (error-containment envelope); the corrupting write itself cannot be vetoed on this seam (see Known Limitations).
76
+
77
+ ### Dispatch gate
78
+
79
+ `tools/pre-execute` listener on the delegation tool(s): parses the payload's Assignment text and runs the engine's SINGLE dispatch-gate composition (`composeDispatchGate` — shape guard, `validateAssignmentFields`, `antiRecursionPrecheck`, default-branch gate, header-region enforcement; the same composition the opencode/omp/CLI bindings use, so violation codes are identical by construction) over the header region, plus the dsh-side worktree L1/L2 checks and the lease gate. The refusal channel is `PreToolDecision { kind: 'deny', reason }` returned **without** calling `next()`; warn mode logs, emits `mstar/dispatch-gate`, and delegates. Non-Assignment prompts and non-delegation tools are inert. Engine failures degrade to allow in both modes **observably**: the catch path emits the plugin-owned advisory with `degraded: true` + an error log, so a hard deployment can detect a dead control instead of a silent pass. Registered `prepend` so an earlier-mounted decision can never…
80
+
81
+ ### Lease gate
82
+
83
+ Additive beyond the opencode field set: for writable dispatches whose Assignment declares `Execution mode: sdd` or whose plan row is `InProgress`, `verifyPlanExecutionLease` + dispatch-context comparisons (`holder`, `worktree_path`, `working_branch`) run against `{HARNESS_DIR}/status.json`. Violations use the dsh-side `lease.dispatch.*` namespace; read-only roles skip the check entirely. A **missing** `status.json` on an sdd dispatch is NOT a silent fail-open: it surfaces `lease.dispatch.unverifiable` (advisory in warn, deny under hard) — the execution_lease cannot be confirmed without the status file. Non-SDD dispatches keep the degrade-allow (no lease obligation). All Assignment field reads are scoped to the engine `assignmentHeaderRegion` (body-quoted examples never leak into header fields).
84
+
85
+ ### Skill lint gate
86
+
87
+ `fs/write-intent` listener scoped to `SKILL.md` files under the configured skill roots runs the engine skill-authoring lints (`lintFrontmatter` + `lintFiveQuestion` — the CLI `mstar skill lint` combination) on the pre-write on-disk document. The slot is **content-blind** (the intent waterfall carries only `(target, actor)`), so: missing file = first create = pass; clean on-disk doc = silent pass; violations in warn mode = advisory + delegate; violations in hard mode = **repair escape** — the document is ALREADY invalid, so this write may BE the repair (error-level log + `hard: true, repair: true` advisory with the enforced `hardBlocked` verdict). Enforcement resolves like the other gates (Config override, else the iteration compass, else warn-only). The gate never throws; read failures and unexpected errors degrade to allow with a `degraded: true` advisory. The typed hard veto (`SkillLintVetoError`, code `skill-lint.veto`) lives on the incoming-document branch (`lintSkillWrite`) — see Known Limitations for its current wiring.
88
+
89
+ ## Service
90
+
91
+ `apply` constructs `ctx.dshMstar` (engine-backed: `validateStatus`, `validateResidual`, `findingsCleanupGate`, `resolveCompassEnforcement`, `resolveHarnessDir`, `readHarnessVersion`, `applyEnforcement`). Layering: the P1 gates are co-located engine wrappers in this package importing the engine directly (same plugin, engine bundled at build time); `ctx.dshMstar` is the composition/test façade for inject consumers; the host adapter (below) is the host-facing facade. The engine is the single grammar for both paths. The companion entry `@mstar-harness/dsh/invariant` reserves package ownership with a documented no-op installer.
92
+
93
+ ## Host adapter
94
+
95
+ The plugin implements the engine `HostAdapter` contract (`host: 'dsh'`) as `DshHostAdapter`, exposed as the `ctx.dshHostAdapter` service. Detection: the engine `detectHost` maps the dsh delegation tool name — `ToolSignal` **`subagent`** (the model-facing dsh subagent tool) — to `'dsh'`, evaluated after omp and before kimi/zcode/codex; hybrid sessions lose to earlier rows by fixed order. The adapter routes through the SAME validation cores as the in-plugin gates (one code path): `beforeStatusWrite(path, doc)` validates the incoming document when the host provides it, else the on-disk fallback (missing file = first create = pass); `beforeDispatch(assignment)` runs the field + branch + anti-recursion gate with the enforced `hardBlocked` verdict (the lease gate stays listener-side — it binds the ToolExecution session context the hook does not carry); `beforeMerge(lease)` is a thin wrapper over the engine `validateIntegrationMergeLease` (the reservation write into `status.json` is a P3 seam). `log` defaults to the dsh ctx logger `mstar/host-adapter`.
96
+
97
+ The frozen skill-root form for dsh (engine `resolveSkillRoot('dsh', …)`) is **`$DSH_BUNDLED_SKILL_DIR/<name>[/<rel>]`** — the resolver defines the canonical form used by skill-relative path resolvers (`resolveAssetPath`); it does NOT mount the directory. Mounting is the plugin's job (next section).
98
+
99
+ ## Skills mount
100
+
101
+ The mstar skills mount through the dsh skill-filesystem provider as a **single canonical mount**: the plugin registers its configured roots as one provider (`providerName: 'mstar'`, `includeDefaultRoots: false` — isolated, it must never see the host app's own project/user skills), and the engine form above is the shared skill-root contract. Two Config paths populate it:
102
+
103
+ | Path | Mechanism | When |
104
+ | --- | --- | --- |
105
+ | Bundled default | `bundledSkillDir` defaults to the package's OWN `harness-skills/` mirror — the repo-root `skills/` (19 `mstar-*` + `pm`) synced by `bundle-assets` at build/postinstall (gitignored), resolved **package-relative** (not cwd-anchored — works from any launch cwd) | Published package / any deployment without an override |
106
+ | Custom roots | `skillRoots` / explicit `bundledSkillDir` → skill-filesystem `customSkillDirs` / `bundledSkillDir` entries (explicit values win) | Local development / tests / deployments with a different mirror |
107
+
108
+ The packaged mirror is a **single canonical mount**: skill content lives once in the repo-root `skills/` mirror and is synced into the package (like opencode's `harness-skills/`), so mstar skills stay standalone-usable everywhere. No double-loading: the opencode plugin ships the same skills in its own package, so dsh must mount them ONLY through this single skill-filesystem path.
109
+
110
+ Dev-time reality: the `@deepseek-ai/dsh-skill-filesystem` runtime is a peer-stub (contract-mirroring registration, no file watcher), so the mount is verified through real composition against the stub + the actual mirror `skills/` frontmatter (engine `lintSkillFrontmatter`); real-runtime composition (real seam packages, watcher, `$DSH_BUNDLED_SKILL_DIR` env flow) is the deployment target, not covered by this package's suite.
111
+
112
+ ## Commands
113
+
114
+ The plugin registers the bundled mstar commands (omp/opencode parity surface) on `ctx.commands`: `harness-commands/*.md` — the repo-root `commands/` mirror (`iteration-start`, `iteration-drive`, `iteration-loop`, `codebase-audit`) synced by `bundle-assets` at build/postinstall (gitignored). Each registration reads the command's `name`/`description`/`input` frontmatter; a declared `input` hint is advertised as `input.hint`, which flips the dsh web client's decision table from detached bare execution to a leadingInput **claim** — the menu pick inserts `/name ` into the composer (command-colored token, the hint as ghost text) and the line submits only on Enter, so the user can type follow-up args (the `/plan` / `/goal` / `/advisor` interaction). The handler **steers the command body into the receiving agent as a USER-source message** (the dsh-plan-mode command precedent — `source: { kind: 'user' }`, so the model treats the body as a task to execute, not injected context; the dsh-commands "explicitly schedule model-visible work through the receiving Agent" path), appending the user's typed args as a `## User input` section when present, and returns a success result. Registration is deferred with `ctx.inject(['commands'], …)` — the same optional-unit pattern as the tools — so the plugin boots without the commands service; an absent mirror (no `bundle-assets` run) registers nothing.
115
+
116
+ ## Engine seam mapping
117
+
118
+ Every engine module attaches to a dsh surface — delivered except the lint module's plan/tdd fs gates (deferred; see Known Limitations):
119
+
120
+ | Engine module | dsh seam | Status |
121
+ |---|---|---|
122
+ | core (applyEnforcement, GateResult/Severity) | cross-cutting veto/reject | delivered (P1) |
123
+ | path (resolveHarnessDir) | harness-dir probing + `{HARNESS_DIR}/status.json` target matching | delivered (P1) |
124
+ | status (validateStatus, validateResidual, findingsCleanupGate) | `fs/write-intent` + `fs/edit-intent` on status.json | delivered (P1) |
125
+ | lease (verifyPlanExecutionLease, validateIntegrationMergeLease) | exec lease: `tools/pre-execute` (inside the dispatch gate); merge lease: `HostAdapter.beforeMerge` | delivered (P1 exec / P3 merge) |
126
+ | dispatch (composeDispatchGate, isReadOnlyAssignmentRole, parseAssignmentFields) | `tools/pre-execute` on the subagent tool (`PreToolDecision.deny` to block); `agent/pre-step` advisory | delivered (P1) |
127
+ | host (resolveSkillRoot, HostAdapter) | engine host.ts detection row + plugin adapter (`host: 'dsh'`) | delivered (P2) |
128
+ | skill-authoring (lintFrontmatter, lintFiveQuestion) | skill-filesystem roots + `fs/write-intent` on SKILL.md | delivered (P2) |
129
+ | lint (lintSkillFrontmatter, planQualityBar, assertSddTddTriple) | not wired — plan/tdd fs gates are a deferral; `lintSkillFrontmatter` runs only in the skills-mount test suite | deferred |
130
+ | agent catalog | MessageSourceMap `mstar-engine-status` (model-visible ⟺ logged) | delivered (P2) |
131
+ | sdd (sddWorkspace, taskBrief) | `defineTool` wrappers registered on `ctx.tools` | delivered (P3) |
132
+ | iteration (evaluatePhaseGate, parseCompassFrontmatter) | `agent/pre-step` + iteration gate | delivered (P3) |
133
+ | worktree (l1PreDispatchCheck, l2PreDispatchCheck) | `tools/pre-execute` L1/L2 (inside the dispatch gate) | delivered (P3) |
134
+ | design-md / audit / compound / roles | `fs/write-intent` + `defineTool` wrappers on `ctx.tools` | delivered (P3) |
135
+
136
+ ## Engine-status catalog
137
+
138
+ An advisory `agent/pre-step` waterfall listener appends ONE **`mstar-engine-status`** catalog MessageSource to every composed step (the `kind`/`form: 'catalog'` contract, mirroring the dsh tool-skill precedent): the model-visible `<mstar_engine_status>` block renders the watermark fields — **mstar version** (plugin own manifest; the single-version invariant pins the bundled engine to the same version), **harness dir** (resolved `{HARNESS_DIR}`, `none` when absent), and **enforcement** (compass mode, `soft` / `hard (compass)`) — plus the **iteration phase-gate section** (when a steering compass + `status.json` resolve: iteration id, transition, all-plans-done, gate verdict + violation codes — the `mstar iteration gate` tool result shape) and the **workspace-state digest section** (when the workspace has a `status.json`): **plans** (`id(status)` registry), **residuals** (open counts by severity), **branch** (base → target, spec integration), **policy** (push policy, worktree mode, control root), **leases** (active plan execution leases: holder + worktree), **knowledge** (knowledge-index doc count + categories) and **direction** (the steering compass's problem-statement one-liner). The listener calls `next()` first and builds on the delegated decision — it never vetoes a step and never replaces the composed messages. Model-visible ⟺ logged: the durable `catalog`-form source records the facts it published beside the model-facing prose, so the session log reconstructs the row without re-parsing the block (dsh packages/AGENTS.md). Fiber disposal removes the listener (HMR-safe).
139
+
140
+ The row is **digest-gated**: per agent+workspace it is injected once per turn and re-injected only when its rendered text changed — a 20-step turn shows the catalog once, not 20 times. The source shares ONE per-workspace cache entry, built at boot for an explicit `harnessDir` (else on the workspace's first pre-step) and TTL-refreshed (`catalogTtlMs`, default 60 s) — the hot path is a timestamp compare + Map lookup between refreshes, and a mid-session plan/compass/residual change lands within one interval.
141
+
142
+ ## Web client plugin (workflow panel)
143
+
144
+ The package ships a browser client half for the dsh **web** profile, discovered
145
+ automatically on the already-installed `mstar` bundle row (package.json
146
+ `dsh.client` declaration + `exports["./client"]` → `dist/client.js` — the
147
+ upstream web `dsh.client` discovery scans loader entries and resolves each
148
+ client's `exports["./client"]` into the boot graph) — **no separate profile
149
+ layer or install step** (spec §6.1). The web app serves the bundle at
150
+ `/plugins/@mstar-harness/dsh/client.js` and loads it through the
151
+ closure-factory loader handoff (`window.__ModuleLoader__.load({ id, factory })`).
152
+
153
+ The client entry registers a **`conversation.view`** view-ring tab
154
+ (`id: 'mstar-workflow'`, `order: 20` — the trajectory precedent shape), labeled
155
+ **"MStar Workflow"** (en) / **"MStar 工作流"** (zh) through the `mstar-panel`
156
+ locale namespace. The panel is the **MStar Workflow layout**: a fixed 300px
157
+ right sidebar — plans (≤5, time-desc, `+N more`), open residual findings (≤10,
158
+ severity chips, overflow hint), policy (**enforcement first**, then push /
159
+ worktree / control worktree), leases, knowledge, direction — over a bottom
160
+ **fixed meta dock** (version + harness dir; small muted, does not scroll with
161
+ the sidebar digest; the former header row was removed), an **HTML/CSS zone
162
+ dashboard** as the main body, and a freshness footer (`last-updated
163
+ HH:MM:SS` + the catalog-re-emission refresh note). The branches block moved
164
+ out of the sidebar to the iteration zone (plan `20260810-panel-canvas-zones`).
165
+ Below 860px the sidebar stacks under the main area.
166
+
167
+ The canvas is a pure render of the latest `mstar-engine-status` catalog row
168
+ (from the `useSession` snapshot — refresh follows the snapshot, no polling):
169
+ the page fills the Tab (no page-level scrolling — the zone container is the
170
+ only scroll body) and the **zone dashboard** (replacing the react-flow cyclic
171
+ graph, plan `20260810-panel-canvas-zones`) lays out three zones — the
172
+ **iteration zone** (Step 1–5 as 5 equal full-width unit blocks with pure-number
173
+ badges + an `N/5` summary — no 步骤/Step wording, plan `20260811-panel-f2-quickfix`;
174
+ active-highlight / inactive dimmed states; the steps carry a FOUR-STATE machine —
175
+ `current` / `next` / `done` / `idle` (plan `20260812-panel-f5-iteration-zone-fix`
176
+ Task 1): every step BEFORE the current one projects `done`「已完成」(completed —
177
+ a finished Step 1 must not read as idle while Step 2 is current), `next` is the
178
+ single forward target, `idle` is schema-only — and the branch panel: iteration
179
+ base / target / spec integration, rendered only while active; the expanded
180
+ head is a LEFT-RIGHT SPLIT — branches (small left half, WIDTH-CAPPED —
181
+ `flex: 0 1 260px` + `max-width: 280px`, never stretches with the container; the
182
+ <860px column stack resets to content height) + steps (large right half,
183
+ `flex: 1 1 0` absorbing the remaining width) via `data-iteration-head-split`,
184
+ stacking on narrow widths, and NO
185
+ branch panel when there is no active iteration; the current step follows the
186
+ steering compass: `compassStatus: 'active'` (Phase 1 in flight) → Step 1
187
+ (iteration-start) is CURRENT with verdict `unknown` — no PASS/FAIL badge —
188
+ plan `20260811-panel-f4-iteration-zone`); the **iteration info section is
189
+ SHARED by the tasks AND agents tabs** (plan `20260812-panel-f5-design-system`
190
+ Task 8, user round-4 decision #4 — one `IterationInfoSection` component,
191
+ both tabs render the same `view.iteration` block: summary + steps +
192
+ branches); the **tasks zone** (5-column
193
+ kanban: Todo / InProgress / InReview / Done / `blocked-unknown` — the
194
+ Blocked state and the former unknown catch-all fold into ONE merged column
195
+ titled「受阻/未知」/「Blocked / Unknown」, plan `20260813-panel-quick-fixes`
196
+ Task 1 — with count badges; every column caps its rendered rows at
197
+ `PLAN_CAP` and shows a clickable 「更多」/「收起」 expand button
198
+ (`data-kanban-more` anchor) unfolding the full column — the projection
199
+ keeps ALL plan rows, the cap is a render concern never a discard) and the **agent-execution zone** (the four EXPECTED_ROLE_FLOW stage/phase
200
+ columns — review-edit-chain → sdd-implement → qc-tri → qa-gate (the
201
+ terminal stage; the former `sdd-task-review` stage is removed, its SDD L2
202
+ reviewer is now the pipeline role `code-reviewer`, v2.1.1) — a strict
203
+ FOUR-column layout with NO standalone unknown column (plan
204
+ `20260812-panel-f5-design-system` Task 5, user 2026-08-12 round-2 decision —
205
+ the former rightmost unknown column of plan `20260812-panel-f5-agent-layout`
206
+ is superseded): the `general` bucket sinks into an **unknown sub-partition
207
+ at the bottom of the `qa-gate` column** (a `data-sub-bucket="unknown"`
208
+ caption row 「unknown / 未匹配角色」 after the last qa-gate card, then the
209
+ general cards; the standalone on-demand column was already removed in the
210
+ agent-layout plan); `explore` is removed — no card, no column. The `sdd-implement`
211
+ column splits into **sub-buckets** by the projected `entity.bucket` (never
212
+ a render guess): the **implementor** partition above — flow roles in the
213
+ stage's original order (fullstack-dev / fullstack-dev-2 / frontend-dev),
214
+ then the on-demand roles (ops-engineer / prompt-engineer, carrying the
215
+ **on-demand badge** — no standalone on-demand column) — and the
216
+ **sdd-reviewer** partition below (code-reviewer, the SDD L2 task reviewer),
217
+ with implementor / sdd-reviewer caption labels; `zone: 'on-demand'` entities
218
+ live in the implementor partition, `zone: 'general'` entities render in the
219
+ qa-gate column's bottom unknown sub-partition. The agent canvas is laid out
220
+ in **TWO side-by-side Phase groups** (plan `20260812-panel-f5-design-system`
221
+ Task 8, user 2026-08-12 round-4 decision; side-by-side layout per plan
222
+ `20260813-panel-agent-canvas-legend-layout` Task 2): the **Phase 1 group on
223
+ the LEFT** (review-edit-chain — the sequential Review & Edit chain:
224
+ product-manager → architect → writing-specialist) and the **Phase 2 group on
225
+ the RIGHT** (sdd-implement → qc-tri → qa-gate — the iterative plan loop),
226
+ top-aligned (all group label rows share the same `y = PAD_Y`), each with its
227
+ group label row; the **Phase-2 label annotates the CURRENT PLAN** — the
228
+ first InProgress `state.plans[]` row (`data-canvas-group-plan`, projected
229
+ `activePlanId`; `+N more` when several plans run in parallel, muted
230
+ 「无进行中 plan」 when none). The subagent **entity cards** aggregate **by role** from actual
231
+ dispatch evidence — the same role across sessions folds into one card ×N,
232
+ and every off-roster dispatch (the former `generalPurpose` SDD reviewer,
233
+ `scout`, anonymous `role === ''`) folds into the single `general` bucket
234
+ entity (the card is role-titled — the role id; the agent session id / task
235
+ tag ride the record line, never the title) — role chip / status point / ×N
236
+ count; running entities carry the
237
+ business glow-pulse highlight (on the ROUNDED `.card-body` — the card is a
238
+ single rounded element, no square outline overlay, plan
239
+ `20260812-panel-f5-design-system` Task 5), un-evidenced stages render the dashed
240
+ "待执行" pending placeholder with their expected role chips, un-evidenced
241
+ KNOWN_AGENTS members render dashed idle cards (the full 14-role roster is
242
+ never hidden), and the header
243
+ shows the `N executing · M pending` summary; cards carry the projected
244
+ **emphasis tier** (plan `20260812-panel-f5-design-system` Task 4, design
245
+ doc §3): `emphasis: 'current' | 'next' | 'off' | null` — the iteration's
246
+ current-phase roles render at **100%** chrome intensity, later-phase
247
+ expected roles at **75%**, already-passed / stage-less (on-demand, general)
248
+ roles at **45%**, and `null` (no iteration / unresolved transition) applies
249
+ NO override — always a chrome **alpha mix** (`--mstar-canvas-emphasis-*`
250
+ tokens; never a whole-card `opacity`, so the status point + running glow
251
+ stay opaque). Settled entities get a **standalone GREEN DONE FRAME + green ✓**
252
+ (plan `20260812-panel-f5-design-system` Task 8 — user round-4 feedback #1/#3:
253
+ `data-agent-done="true"`, a full-strength success border + 1px ring on the
254
+ rounded card body + the ✓ in the status point) **ONLY when `emphasis ≠ 'off'`**
255
+ — an off-tier role (already-passed / stage-less on-demand + general) renders
256
+ the muted dot instead and NEVER shows the completion marker. The agent
257
+ canvas filters dispatch evidence to the **current iteration's plans only**
258
+ (plan `20260813-panel-quick-fixes` Task 2): the steering compass
259
+ `iterationId` when active, else the nearest iteration from the catalog
260
+ `plans[].iterationRefs` (most-recent plan by 8-digit id date prefix +
261
+ doneAt); provably cross-iteration events produce no entity/edge — the
262
+ roster keeps its idle cards, and plan-less / unknown-plan / standalone
263
+ dispatches are never hidden. Status honesty (Task 2): `advisory` is no
264
+ longer terminal — a soft-enforcement dispatch falls through to its paired
265
+ settle (green ✓ when a settle exists, `running` when none), `denied` stays
266
+ terminal, and the advisory verdict still renders in the event log. The
267
+ canvas legend sits BELOW the viewport (Task 3, moved from above). Edges — plan `20260812-panel-f5-design-system` Task 5 (design
268
+ doc §2): the `expected` stage skeleton arrows AND the ANIMATED **next** edge
269
+ (the former `@keyframes agent-dash-flow` dash-flow arrow of plan
270
+ `20260810-panel-agent-flow-zone`) are **REMOVED** — flow order is implied
271
+ by the fixed column order + column labels, the current position by the
272
+ running card glow + status point — leaving TWO semantic kinds: the
273
+ evidence-driven **`actual` handoff** edges (same-plan ts-adjacent dispatch
274
+ entity-key pairs, `general` endpoints filtered, ≤1 per entity pair) drawn as
275
+ **bezier `C` curves** anchored to card **ports** — 4 fixed edge-midpoint
276
+ ports (north / south / east / west; static-invisible, hover-revealed as
277
+ small dots) with the arrow tip pulled back to a **10px standoff** off the
278
+ port — the arrow follows the line's local tangent at the anchor (**H1**),
279
+ and no line's stroke or arrow crosses any text (**H2**: standoff + side-gap
280
+ routing, design doc §2.0/§2.5/§2.6; tightened in plan
281
+ `20260813-panel-quick-fixes` Task 3 — same-column vertical flows whose
282
+ center-x line would cross an in-between card body reroute into the column's
283
+ LEFT side gap (forward AND reverse), and reverse horizontal beziers keep
284
+ direction-aware control points BETWEEN the endpoints, never bulging into
285
+ the adjacent column) — plus the **bidirectional supervise
286
+ line** (plan `20260812-panel-f5-agent-layout` Task 1/2) — one static
287
+ design-knowledge sub-bucket edge inside the `sdd-implement` column
288
+ (implementor ↔ sdd-reviewer — the mstar-sdd mutual-supervision contract),
289
+ now anchored at the **side-gap vertical anchor** (`x = card right edge +
290
+ 18px`, vertical bezier flow, arrows along the vertical tangent — design doc
291
+ §2.5/§2.7); dim dashed by default, lit business SOLID when the projected
292
+ `evidenced` flag is true — evidence-driven lighting, never a fabricated
293
+ activation) — with the
294
+ agent-flow event strip migrated into the **事件记录 (Event Log) tab** — a
295
+ non-canvas log page (spec F1.5, plan `20260811-panel-event-log`): two
296
+ partitions (**Agent 流转事件** / **违规记录**), every row an expandable
297
+ native `<details>` carrying the full catalog fields (a missing field renders
298
+ 「—」, never a guessed value), muted empty states — the two partitions
299
+ render SIDE BY SIDE in a locked-height two-column grid
300
+ (`repeat(2, minmax(0, 1fr))` — the page never scrolls as a whole; each
301
+ partition pins its title and owns an internal `overflow-y` scroll on its
302
+ row list; plan `20260813-panel-quick-fixes` Task 4 root-caused the
303
+ whole-page scroll — the panel root opts into the host
304
+ `data-conversation-composer-overlay` (the host's full-height opt-in), so
305
+ `height:100%` resolves and `.rowList`'s `overflow-y: auto` scrolls INSIDE
306
+ the partition (the host page no longer scrolls), with bottom clearance
307
+ reserving the floating composer via the host-published
308
+ `--dsh-composer-height`), falling back to two stacked 50/50 locked rows below 1200px (the
309
+ `data-event-log-*` anchors unchanged, plan `20260811-panel-f3-agent-general`)
310
+ — the canvas-corner
311
+ **`AgentEventDock`** is REMOVED with the page (无双份日志, spec §5; the
312
+ fixed footer bar — zone legend + gate summary + violations — died with the
313
+ WorkflowCanvas zone dashboard in the tabs-shell plan; the footer that
314
+ remains is the freshness marker). Empty branches (spec §2, plan
315
+ `20260812-panel-f5-agent-layout` Task 3): waiting keeps the muted hint, and
316
+ NO harness renders a **centered inactive-state card** — folder icon + 「No
317
+ Morning Star harness detected」 title + hint copy (the detail panel stays
318
+ inactive — no tabs, no sidebar — and activates automatically once a harness
319
+ is detected; the `data-mstar-empty="no-harness"` anchor stays on the title,
320
+ `data-mstar-graph` on the main container). Below 1200px the zones stack vertically. Projection is the pure
321
+ `projectGraph(source)` function (schema constants strictly separated from
322
+ catalog evidence; never throws; missing fields degrade to explicit
323
+ empty/last-known states — muted empty states, never orange warn boxes)
324
+ producing a data-only `ZoneView`; `WorkflowCanvas` renders it as plain
325
+ HTML/CSS.
326
+
327
+ **Dependency**: the zone dashboard carries **no graph library** — the
328
+ `@xyflow/react` devDependency (previously inlined into `dist/client.js` at
329
+ build time) was removed with the react-flow rendering layer (plan
330
+ `20260810-panel-canvas-zones`), and the plain-`.css` text loader whose only
331
+ consumer was `@xyflow/react/dist/style.css` is gone too (`CLIENT_EXTERNALS`
332
+ is unchanged — react / react-dom and the `@deepseek-ai/dsh-client-*` platform
333
+ modules stay external). The build script asserts the removal end to end: the
334
+ emitted bundle must contain **no `xyflow`/`reactflow` markers**, zero
335
+ `@deepseek-ai/*` value imports, and **no `import.meta` / ESM statements** —
336
+ the web loader executes plugin bundles as classic `<script>`s, where a
337
+ literal `import.meta` is a parse-time SyntaxError (a zustand v4
338
+ `import.meta.env` read is defined away at build; see the iteration
339
+ install-verification guide §6). Bundle size at this plan's wrap-up: **145,159 B
340
+ raw / 29,460 B gzip** (re-measure per the iteration install-verification
341
+ guide — the bundle shrank to ~85 KB when react-flow was removed and grew
342
+ back with the agent-execution zone's entity rendering, then again with the
343
+ F5 emphasis tiers + edge rework).
344
+
345
+ Install / verify (the client half rides the same bundle-row install as the
346
+ server half):
347
+
348
+ ```sh
349
+ cd <repo>/packages/dsh
350
+ bun run build # dist/client.js (closure-factory CJS) + dist/client.d.ts
351
+ # corepack machines (repo root declares packageManager: bun): prefix with COREPACK_ENABLE_PROJECT_SPEC=0
352
+ dsh plugin --profile web add <abs packages/dsh path> # same profile bundle install
353
+ dsh web # boot → /plugins/@mstar-harness/dsh/client.js served
354
+ ```
355
+
356
+ Verified locally (install-verification guide): the boot graph contains the
357
+ client entry (`@mstar-harness/dsh` with the declared inject faces), the
358
+ `/plugins/<id>/client.js` route serves the exact built bundle (rev = content
359
+ sha1), and the browser handoff materializes the plugin entry (`inject` +
360
+ `apply` + CSS injection under classic-script semantics) — see
361
+ `.mstar/iterations/iter-20260809-mstar-panel-beautify/guides/install-verification.md`.
362
+
363
+ **Known Limitations** (this iteration): the iteration stepper's Step 1
364
+ (iteration-start) IS the current step while the steering compass is
365
+ `status: active` (Phase 1 in flight — catalog `compassStatus` field), carrying
366
+ NO PASS/FAIL badge (Phase 1 has no gate verdict); Step 5 (merge-ready) can
367
+ never be the **current** step —
368
+ the engine phase gate only evaluates Phase 2→3→4 (merge-ready is never a gate
369
+ transition); it renders `next` only while Step 4 (pr-delivery) is current, idle
370
+ otherwise;
371
+ the current step follows the TTL-refreshed `compassStatus` — up to one catalog
372
+ interval (60 s) behind a mid-session `active`→`locked` flip (bounded,
373
+ documented staleness, never a wrong verdict);
374
+ the agent-entity status derivation pairs a PAIRED settle exactly by its
375
+ dispatch identity (agent, role, planId, taskId — QC-tri N=3 settles land on
376
+ their own cards), and an unpaired dispatch stays running (no paired settle,
377
+ never faked); the current-iteration filter with NO steering compass infers
378
+ the iteration from plan ids (8-digit date prefix) + doneAt — a
379
+ deterministic, documented heuristic, and only provably cross-iteration
380
+ events are dropped; no historical
381
+ back-scan of a resumed long log (the server re-emits the row at every turn's
382
+ first step, digest-gated); no custom top-level slot (the `conversation.view`
383
+ tab is the only session-level panel seat available without dsh-private layout
384
+ changes — spec §1). Panel acceptance is dual-track: in-loop browser harness
385
+ verification against the rebuilt bundle (see iteration guides
386
+ `iter-20260810-panel-zones/guides/`) plus user-restart final GUI acceptance —
387
+ rerun steps in the install-verification guide §8. R1 (browser observation)
388
+ closed and archived 2026-08-10.
389
+
390
+ ## Development
391
+
392
+ Commands (from `packages/dsh`): the coverage gate is per-file 100% on `src/` (dsh testing policy); the build bun-bundles the src entries into `dist/` (engine + schemastery inlined; `@deepseek-ai/cordis` and the runtime seam imports — `@deepseek-ai/dsh-skill-filesystem`, `@deepseek-ai/dsh-tools` (`defineTool`), `@deepseek-ai/dsh-llm` — external), runs `build-client` (`scripts/build-client-bundle.ts` — the closure-factory CJS browser bundle per spec §6.2, `dist/client.js`) and emits tsc declarations.
393
+
394
+ ```sh
395
+ bun test --coverage
396
+ bunx tsc --noEmit
397
+ bun run build
398
+ ```
399
+
400
+ `bun run test` builds the client bundle first (the `pretest` hook runs
401
+ `build-client` — the manifest-contract suite asserts `dist/client.js` exists);
402
+ a direct `bun test` on a fresh checkout fails with a `bun run build` hint
403
+ instead of a bare assertion.
404
+
405
+ The dev-time seam surfaces (types, event shapes, runtimes) are the REAL `@deepseek-ai/dsh-*` packages, installed from the public npm registry (`registry.npmjs.org`, no root `.npmrc` needed — bun auto-installs peers by default).
406
+
407
+ ## Model Experience
408
+
409
+ ### Request surface and condition
410
+
411
+ #### What the model sees
412
+
413
+ Every composed step carries one `mstar-engine-status` catalog user message (the `<mstar_engine_status>` watermark block — see the Engine-status catalog section). Gate decisions add: the dispatch veto as the registry-materialized `PreToolDecision { kind: 'deny', reason }` error; the status gate as the `mstar/status-gate` advisory (warn pass, hard-mode repair escape, or degraded allow); the dispatch gate as the `mstar/dispatch-gate` advisory (warn pass or degraded); the skill lint gate as the `mstar/skill-lint` advisory (warn pass, hard-mode repair escape, or degraded allow). Every model-visible row is reconstructable from the session log (catalog-form sources + advisory events).
414
+
415
+ **Leaf delivery discipline (PM 2026-08-12):** leaf subagents hand back their Completion Report in the **final (closing) message**, not via the `report` tool — the dsh tool-subagent-report default `reportDelivery: quiet` routes a report into the parent's next-step queue, where it strands when the parent's turn has ended (no step boundary follows). The closing message is the guaranteed delivery channel; reserve `report` for mid-turn findings that change what the parent should do next (SSOT: `skills/mstar-host/references/dsh.md` → PM dispatch).
416
+
417
+ #### Token effect
418
+
419
+ The catalog appends one fixed, stable user message per composed step (small constant block — no growth with session length beyond one row per step; per-session digest dedup is a P3 item). Veto and advisory text exists only when a gate fires.
420
+
421
+ #### KV Cache effect
422
+
423
+ The catalog row is appended at the END of the composed step messages, after delegation — the request prefix (system prompt + prior messages) is untouched, so prefix cache state is neither created nor invalidated by the plugin; the trailing row is byte-identical across steps. Tool-error text varies per violation but never participates in the request prefix.
424
+
425
+ ## Known Limitations and Deferred Work
426
+
427
+ - **Dev-time seams resolve from the npm registry** — the `@deepseek-ai/dsh-*` seams are peerDependencies only (the host provides them at runtime); dev-time typecheck/tests/build resolve them from the public npm registry (`registry.npmjs.org`, no root `.npmrc` needed — bun auto-installs peers by default). **All runtime seam imports are externalized at build time** (`--external @deepseek-ai/cordis / @deepseek-ai/dsh-skill-filesystem / @deepseek-ai/dsh-tools / @deepseek-ai/dsh-llm` — the published `dist/` imports them instead of inlining); the gates are exercised through the exact `ctx.waterfall` dispatch the real registry/fs tools perform. The suite runs against the REAL seam packages from the npm registry — no committed `peer-stubs/` stand-ins, no local link farm.
428
+ - **Anti-recursion binding is Config-declared** — dsh exposes no per-agent role on the tool-execution context, so `dispatchBinding` declares one deployment-wide role; an Assignment with a different `Execute as` cannot be caught as self-recursion, and multi-role dispatchers need per-instance plugins.
429
+ - **Lease gate diverges from opencode by design** — opencode's `beforeDispatch` runs no lease checks; the dsh lease gate is additive (`lease.dispatch.*` codes) and fires only for writable SDD/InProgress dispatches, so parity covers the field set, not the lease surface.
430
+ - **Shared engine composition adopted** — the dispatch gate core is the engine's single `composeDispatchGate` (opencode/omp/CLI parity, so field/branch/anti-recursion violation codes are identical by construction), and the compass frontmatter parser is the engine's shared `parseCompassFrontmatter` (no local fork — nothing left to drift). Both run over the dsh header-region slice; the lease + worktree L1/L2 checks stay dsh-side additions on top.
431
+ - **Engine single-version pin** — `@mstar-harness/engine` is an exact `2.1.1` devDependency bundled into `dist/` (never a runtime dependency); `readHarnessVersion()` reads the dsh package manifest next to the bundle — `2.1.1`, equal to the pinned engine by the single-version invariant.
432
+ - **Schemastery empty-array materialization** — an omitted optional ARRAY Config key materializes as `[]`; the dispatch keys preserve omission via `.default(undefined)`, and any future optional array key must do the same.
433
+ - **Payload boundary** — the dispatch gate validates the delegation payload (Assignment text), not the child's runtime behavior; post-publish observation via `subagent/start` remains an option if model-visible child activity needs surfacing.
434
+ - **Status gate is content-blind by seam design** — the `fs/write-intent`/`fs/edit-intent` waterfall carries only `(target, actor)`, never the incoming content, so the write that FIRST corrupts a valid `status.json` passes in BOTH modes (the gate validates the pre-write document only). Hard mode therefore never vetoes status writes: an already-invalid document is allowed as a **repair escape** (error-level advisory with `hard: true, repair: true`) so the repairing write can land. Recovery path: repair the document in place (the gate allows it) or delete `status.json` and let the harness re-create it; monitor hard-mode deployments for `repair: true` advisories.
435
+ - **Missing `status.json` lease behavior** — on sdd writable dispatches a missing status file surfaces `lease.dispatch.unverifiable` (advisory in warn, deny under hard); non-SDD dispatches carry no lease obligation and keep the silent degrade-allow.
436
+ - **Gate matching follows `displayPath`** — the status gate matches on the resolved `displayPath` of the fs target. A backend reporting workspace-relative paths, a symlinked harness dir, or remote/URI targets never match and the gate is inert for them (no false positives); use absolute local paths for gated harness writes.
437
+ - **design-md seam scope is global basename matching** — `isSeamTarget('design-md')` matches any `DESIGN.md` / `DESIGN.dark.md` on the filesystem, regardless of the resolved `{HARNESS_DIR}` / repo root. A write to an unrelated project's DESIGN.md that does not follow the mstar token format therefore logs an error-level repair-escape advisory under hard mode (`hard: true, repair: true`) outside the harness — a noisy false-positive surface (the write is never blocked). Deliberate ("the artifact is the file itself, wherever the design lives"); containing the scope to the repo root when a harness dir resolves is a possible follow-up.
438
+ - **audit seam scope matches any `plans/audit-*` segment at any depth** — `isAuditPlanTarget` scans all path segments, so a tree unrelated to mstar (e.g. a dependency or sibling project with a `plans/audit-*` layout) gets mstar audit Status-block + secret lints on write. Same class as the design-md scope (advisory-only, never blocking); the layout is mstar-audit's documented Phase 4 shape, so the match is intentional.
439
+ - **skill-lint × roles-seam double-fire on `<root>/mstar-roles/SKILL.md`** — when a configured skill root contains the `mstar-roles` dir (the repo-root mirror case in dev, and the bundled mirror in the published form), one write to `mstar-roles/SKILL.md` fires BOTH the skill-authoring lint gate and the roles seam gate (two advisories / two repair-escape logs in hard). Both validators legitimately apply — the double-lint is advisory-only, not a correctness break; the "scopes are disjoint" property holds among the four seams only, not across the skill gate.
440
+ - **Content-blind skill-lint blind spots** — the `fs/write-intent` slot carries only `(target, actor)`: first-create incoming content is not linted, and valid→invalid overwrites are not detected on the listener path (it lints the pre-write on-disk document only). Warn/hard advisories surface pre-existing on-disk violations only — the same class of limitation as the status gate.
441
+ - **Explicit relative `bundledSkillDir` overrides are cwd-anchored** — skill-filesystem resolves a relative bundled root with plain `join()` semantics against the dsh **process cwd** at boot. The plugin's DEFAULT bundled root is the package's OWN `harness-skills/` mirror resolved package-relative (NOT cwd-anchored — works from any launch cwd); only an explicit RELATIVE override inherits the cwd anchoring, so deployments overriding the default should pass an **absolute path in the profile layer** (see `bundle/README.md`).
442
+ - **Bundled mirror is a build-time sync** — `harness-skills/` + `harness-commands/` are produced by `bundle-assets` at build/postinstall (repo-root `skills/` + `commands/` mirrors; gitignored). A checkout where `bundle-assets` has not run mounts no bundled skills and registers no commands (the default mount is inert, not an error).
443
+ - **Profile-bundle install into the `web` profile: registry and local checkout** — `dsh plugin --profile web add @mstar-harness/dsh` (registry) and `add <local checkout>` are the supported paths; both run through the same pnpm + reconcile mechanism (the reconcile step joins `@mstar-harness/dsh` to `dsh.profile.bundles`). A local checkout needs a prior `bun run build` — the package has no `prepare` script (the monorepo builds packages explicitly), so an unbuilt checkout installs an empty `dist/`.
444
+ - **`lintSkillWrite` typed veto not production-wired** — the incoming-document hard veto (`SkillLintVetoError`, code `skill-lint.veto`) is exported and test-covered, but has no production caller yet: the engine `HostAdapter` has no content-carrying skill-write hook (only `beforeStatusWrite`/`beforeDispatch`/`beforeMerge`), and the fs intent slot is content-blind. Wiring lands with a future content-carrying hook; until then the listener path enforces only via the repair-escape advisory (never a veto).
445
+ - **CLI `HOST_SIGNALS` lacks the `subagent` token** — the engine `ToolSignal` union includes it and `detectHost` handles it, but `packages/cli` `HOST_SIGNALS` is not updated yet, so `mstar host detect --signals subagent` would reject until the CLI list is updated on upstreaming.
446
+ - **Entry is a module index over `src/gates/*`** — the split shipped: `src/index.ts` (371 lines) re-exports the frozen 27-name export surface from the gate modules (`_shared` / `status` / `skill-lint` / `seams` / `dispatch` / `catalog` / `tools` / `adapter`) and keeps the plugin manifest, the single cordis augmentation point, the command registration, and the `apply()` startup wiring. The surface (17 value + 10 type-only names; `Config` counts once) is frozen by `tests/export-surface.spec.ts` — the runtime value-export set plus, under `typecheck:tests` (`bunx tsc --noEmit -p tests/tsconfig.json`), the value-namespace identity and the per-name type-only probes.
447
+ - **Engine dsh rows are upstreaming-destined** — the dsh changes to engine `host.ts` (`DetectResult`, `ToolSignal`, `resolveSkillRoot`) live in the mstar-workflow engine mirror and are intended for a user-authorized upstream PR into mstar-harness; the `mstar-host` skill mirror (§ Detect / § Resolve loaded skill root / `references/dsh.md`) updates with it.
448
+ - **Iteration stepper: Step 1 is compass-driven, Step 5 is schema-driven** — the zone dashboard's Step 1 (iteration-start) is the current step while the steering compass is `status: active` (Phase 1 in flight — no gate verdict, so no PASS/FAIL badge); Step 5 (merge-ready) is a schema constant the engine gate never lights as current (transition covers Phase 2→3→4 only), so it always renders idle — recorded in the iteration guide, not a defect. The full panel-limitation list lives in the Web client plugin section.