@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.
- package/README.i18n.yaml +7 -0
- package/README.md +448 -0
- package/README.zh.md +221 -0
- package/bundle/README.md +312 -0
- package/bundle/cordis.patch.yml +17 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/panel/PanelView.d.ts +67 -0
- package/dist/client/panel/TabNav.d.ts +28 -0
- package/dist/client/panel/graph/event-log.d.ts +76 -0
- package/dist/client/panel/graph/project-graph.d.ts +499 -0
- package/dist/client/panel/graph/schema.d.ts +224 -0
- package/dist/client/panel/guards.d.ts +12 -0
- package/dist/client/panel/locale.d.ts +134 -0
- package/dist/client/panel/pages/AgentCanvasPage.d.ts +363 -0
- package/dist/client/panel/pages/EventLogPage.d.ts +48 -0
- package/dist/client/panel/pages/IterationInfoSection.d.ts +80 -0
- package/dist/client/panel/pages/IterationTaskPage.d.ts +37 -0
- package/dist/client/panel/panel-meta.d.ts +18 -0
- package/dist/client/panel/plan-sort.d.ts +54 -0
- package/dist/client/panel/sidebar.d.ts +17 -0
- package/dist/client/panel/state-section.d.ts +23 -0
- package/dist/client/panel/use-mstar-engine-status.d.ts +42 -0
- package/dist/client/panel/zones/Legend.d.ts +18 -0
- package/dist/client/panel/zones/TaskBoard.d.ts +40 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +4486 -0
- package/dist/gates/_shared.d.ts +198 -0
- package/dist/gates/adapter.d.ts +131 -0
- package/dist/gates/agent-flow.d.ts +320 -0
- package/dist/gates/catalog.d.ts +118 -0
- package/dist/gates/dispatch.d.ts +152 -0
- package/dist/gates/seams.d.ts +152 -0
- package/dist/gates/skill-lint.d.ts +87 -0
- package/dist/gates/status.d.ts +81 -0
- package/dist/gates/tools.d.ts +37 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +5748 -0
- package/dist/invariant.d.ts +15 -0
- package/dist/invariant.js +29 -0
- package/dist/service.d.ts +96 -0
- package/dist/types.d.ts +241 -0
- package/harness-commands/codebase-audit.md +40 -0
- package/harness-commands/iteration-drive.md +129 -0
- package/harness-commands/iteration-loop.md +139 -0
- package/harness-commands/iteration-start.md +179 -0
- package/harness-skills/grill-me/SKILL.md +10 -0
- package/harness-skills/mstar-audit/SKILL.md +183 -0
- package/harness-skills/mstar-audit/references/audit-playbook.md +130 -0
- package/harness-skills/mstar-audit/references/finding-format.md +65 -0
- package/harness-skills/mstar-branch-worktree/SKILL.md +219 -0
- package/harness-skills/mstar-branch-worktree/references/parallel-writable-pre-dispatch.md +68 -0
- package/harness-skills/mstar-coding-behavior/SKILL.md +147 -0
- package/harness-skills/mstar-compound/SKILL.md +105 -0
- package/harness-skills/mstar-compound/assets/resolution-template.md +94 -0
- package/harness-skills/mstar-compound/references/category-mapping.md +37 -0
- package/harness-skills/mstar-compound/references/compound-workflow.md +155 -0
- package/harness-skills/mstar-compound/references/concepts-vocabulary.md +44 -0
- package/harness-skills/mstar-compound/references/schema.yaml +122 -0
- package/harness-skills/mstar-compound-refresh/SKILL.md +140 -0
- package/harness-skills/mstar-compound-refresh/references/project-knowledge-bootstrap.md +164 -0
- package/harness-skills/mstar-design-md/SKILL.md +142 -0
- package/harness-skills/mstar-design-md/references/completeness-checklist.md +181 -0
- package/harness-skills/mstar-design-md/references/design-md-spec.md +508 -0
- package/harness-skills/mstar-design-md/references/vercel-example.md +200 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.dark.md.template +354 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.md.template +474 -0
- package/harness-skills/mstar-dispatch-gates/SKILL.md +128 -0
- package/harness-skills/mstar-dispatch-gates/references/leaf-executor-checklist.md +23 -0
- package/harness-skills/mstar-harness-core/SKILL.md +180 -0
- package/harness-skills/mstar-host/SKILL.md +78 -0
- package/harness-skills/mstar-host/references/_shared/host-role-binding-core.md +51 -0
- package/harness-skills/mstar-host/references/_shared/plan-mode-bridge-core.md +91 -0
- package/harness-skills/mstar-host/references/codex.md +61 -0
- package/harness-skills/mstar-host/references/cursor-plan-mode-bridge.md +159 -0
- package/harness-skills/mstar-host/references/cursor.md +183 -0
- package/harness-skills/mstar-host/references/dsh.md +502 -0
- package/harness-skills/mstar-host/references/kimi-plan-mode-bridge.md +36 -0
- package/harness-skills/mstar-host/references/kimi.md +136 -0
- package/harness-skills/mstar-host/references/omp-plan-mode-bridge.md +32 -0
- package/harness-skills/mstar-host/references/omp.md +244 -0
- package/harness-skills/mstar-host/references/opencode.md +76 -0
- package/harness-skills/mstar-host/references/parallel-dispatch.md +68 -0
- package/harness-skills/mstar-host/references/zcode-plan-mode-bridge.md +36 -0
- package/harness-skills/mstar-host/references/zcode.md +129 -0
- package/harness-skills/mstar-iteration/SKILL.md +393 -0
- package/harness-skills/mstar-iteration/references/autonomous-direction-lock.md +90 -0
- package/harness-skills/mstar-iteration/references/iteration-artifact-boundaries.md +103 -0
- package/harness-skills/mstar-iteration/references/iteration-compass-template.md +142 -0
- package/harness-skills/mstar-iteration/references/iteration-corpus-hygiene.md +45 -0
- package/harness-skills/mstar-iteration/references/iteration-workspace-readme-template.md +27 -0
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +193 -0
- package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +95 -0
- package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +84 -0
- package/harness-skills/mstar-iteration/references/phase5-helper-discovery.md +24 -0
- package/harness-skills/mstar-phase-gates/SKILL.md +112 -0
- package/harness-skills/mstar-plan-artifacts/SKILL.md +46 -0
- package/harness-skills/mstar-plan-artifacts/references/done-compaction.md +88 -0
- package/harness-skills/mstar-plan-artifacts/references/knowledge-and-designs.md +100 -0
- package/harness-skills/mstar-plan-artifacts/references/plan-files-and-reports.md +99 -0
- package/harness-skills/mstar-plan-artifacts/references/plan-quality-bar.md +99 -0
- package/harness-skills/mstar-plan-artifacts/references/status-and-residuals.md +570 -0
- package/harness-skills/mstar-plan-artifacts/templates/README.md +9 -0
- package/harness-skills/mstar-plan-artifacts/templates/notes.empty.json +5 -0
- package/harness-skills/mstar-plan-artifacts/templates/plan.main.md +54 -0
- package/harness-skills/mstar-plan-artifacts/templates/plans-done.empty.json +3 -0
- package/harness-skills/mstar-plan-artifacts/templates/status.empty.json +7 -0
- package/harness-skills/mstar-plan-conventions/SKILL.md +165 -0
- package/harness-skills/mstar-plan-conventions/references/artifact-storage-paths.md +50 -0
- package/harness-skills/mstar-plan-conventions/references/effort-estimation.md +38 -0
- package/harness-skills/mstar-plan-conventions/references/harness-bootstrap-and-agents-layering.md +93 -0
- package/harness-skills/mstar-review-qc/SKILL.md +60 -0
- package/harness-skills/mstar-review-qc/references/review-responsibility-boundaries.md +54 -0
- package/harness-skills/mstar-roles/SKILL.md +86 -0
- package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +46 -0
- package/harness-skills/mstar-roles/references/architect.md +114 -0
- package/harness-skills/mstar-roles/references/code-reviewer.md +109 -0
- package/harness-skills/mstar-roles/references/frontend-dev.md +70 -0
- package/harness-skills/mstar-roles/references/fullstack-dev-shared.md +89 -0
- package/harness-skills/mstar-roles/references/ops-engineer.md +78 -0
- package/harness-skills/mstar-roles/references/product-manager.md +107 -0
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +198 -0
- package/harness-skills/mstar-roles/references/project-manager/plan-management.md +61 -0
- package/harness-skills/mstar-roles/references/project-manager/qa-trigger-matrix.md +56 -0
- package/harness-skills/mstar-roles/references/project-manager/qc-and-residuals.md +98 -0
- package/harness-skills/mstar-roles/references/project-manager/routing-and-dev-allocation.md +99 -0
- package/harness-skills/mstar-roles/references/project-manager.md +310 -0
- package/harness-skills/mstar-roles/references/prompt-engineer.md +71 -0
- package/harness-skills/mstar-roles/references/qa-engineer/acceptance-gate.md +62 -0
- package/harness-skills/mstar-roles/references/qa-engineer.md +79 -0
- package/harness-skills/mstar-roles/references/qc-specialist/deep-review-lenses.md +95 -0
- package/harness-skills/mstar-roles/references/qc-specialist/report-template.md +72 -0
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-checklist.md +44 -0
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-workflow.md +57 -0
- package/harness-skills/mstar-roles/references/qc-specialist-shared.md +128 -0
- package/harness-skills/mstar-roles/references/writing-specialist.md +59 -0
- package/harness-skills/mstar-sdd/SKILL.md +133 -0
- package/harness-skills/mstar-sdd/references/file-handoffs.md +83 -0
- package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +44 -0
- package/harness-skills/mstar-sdd/references/implementer-prompt.md +56 -0
- package/harness-skills/mstar-sdd/references/sticky-implementer-session.md +103 -0
- package/harness-skills/mstar-sdd/references/task-reviewer-prompt.md +53 -0
- package/harness-skills/mstar-skill-authoring/SKILL.md +162 -0
- package/harness-skills/mstar-skill-authoring/references/skillsbench-authoring.md +117 -0
- package/harness-skills/mstar-strategy/SKILL.md +130 -0
- package/harness-skills/pm/SKILL.md +40 -0
- package/package.json +92 -0
package/README.i18n.yaml
ADDED
|
@@ -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.
|