btspoony/mstar-harness--packages-dsh58

@mstar-harness/dsh

Morning Star harness dsh (DeepSeek Harness) cordis function plugin — in-process engine gates (status/dispatch/lease) with hard refusal channels.

AI Analysis

适合需要对DSH引擎进行状态分发和租约管理的系统级任务。

Package
@mstar-harness/dsh
Version
3.8.3
License
MIT
Last updated
Sep 12, 2026

Install

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:btspoony/mstar-harness#cd811d651df342990fb6d6f06ced424be3ee4b47&path:packages/dsh

Usage

How a dsh app consumes the plugin — install paths, configuration, what mounts at boot, and the enforcement semantics.

Install paths

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:

One-command CLI entry (recommended)npx @mstar-harness/cli init --target dsh installs the full capability in one go: it runs the two dsh plugin --profile web add installs below in order (the mstar bundle first, then dsh-llm-fallbacks), and npx @mstar-harness/cli doctor --target dsh reports each plugin row as uninstalled / disabled / mounted / drifted (drifted = the fallbacks row is installed at a version other than the pinned one; init --target dsh re-adds the pin, doctor exits non-zero until then). It is the same two-command install, orchestrated; --no-fallbacks skips the second row (and with it the seeded roles — see What you get below).

(a) Registry install (published form) — the npm package carries the built dist/ (no build step on install):

dsh plugin --profile web add @mstar-harness/dsh

(b) Local checkout install (dev) — the package checkout itself, for iterating on the plugin:

cd /packages/dsh
dsh plugin --profile web add .

dsh plugin --profile add initializes the profile on first use (web starts from the shipped template: @deepseek-ai/dsh-base + @deepseek-ai/dsh-web-app), forwards `` 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).

(c) Optional capability: dsh-llm-fallbacks (second command) — the role-based subagent configuration capability (see LLM fallbacks integration) is a SEPARATE plugin row and must be installed with its own command:

dsh plugin --profile web add dsh-llm-fallbacks

The two-command install is the contract — folding a dsh-llm-fallbacks row into this bundle's patch is explicitly rejected (roadmap §8.3 F4): the loader has no insert-if-absent semantics, so a same-id insert is a duplicate loader entry id boot failure (the whole dsh session fails to start), and a different-id insert mounts the plugin twice — two apply() runs with split fallback state (per-context state stores, double listeners, config-override lottery) for anyone who also installs the package directly. Layer order is the reconcile append order: dsh-llm-fallbacks lands after dsh-base/llm-retry (its hard ordering requirement) and after the mstar row. Single-command multi-activation is an upstream feature gap (reconcile dedup or insert-if-absent patch semantics), not actionable from this repo.

What you get with zero configuration — with BOTH rows installed (via the CLI entry or the two commands above), the mstar plugin declares the 13 mode: subagent mstar role seeds (derived from the bundled harness-agents/ mirror, project-manager excluded) into the fallbacks taxonomy at boot: each seeded role's persona defaults to its mirror description plus the mandatory role-loading guidance line, the seeded state stays revertible (the fallbacks/revert-seed gateway / the settings rollback button), and the runtime advisory reports missing ids and persona overrides. The seeds mechanism is B4 — the installed-deployment e2e (tests/install-e2e.spec.ts) closes the verification loop: a real init --target dsh install into a temp DSH_HOME, booted from the installed artifacts, asserts all 13 ids present in the effective taxonomy with non-empty personas. Not included: model routing, automatch dispatch, or the dsh TUI.

Fresh-publish age window: pnpm's minimumReleaseAge gate can make a dsh plugin add range resolution pick an older published version (without the seeds surface) for up to ~24h after a fresh publish — re-run npx @mstar-harness/cli init --target dsh after the window (or pin the version) to converge on the latest surface.

Headless profile (one-shot runs)

The plugin is not web-bound: it also mounts in the dsh headless profile (dsh --profile headless "" — the one-shot, no-GUI/no-port mode). The install path is identical, one command:

dsh plugin --profile headless add @mstar-harness/dsh

The shipped headless template auto-initializes on first use (@deepseek-ai/dsh-base + @deepseek-ai/dsh-headless), and the reconcile step appends the mstar row to the bundle stack (dsh-base → dsh-headless → @mstar-harness/dsh). Every plugin capability rides a dsh-base seam that headless inherits — status/dispatch/lease/worktree gates, the skill mount, the engine-status catalog, the harness-rules system-prompt injection, the 7 model-facing tools — so the harness is fully live in a one-shot run. Launch from the repo working directory (the runner writes meta.cwd = process.cwd() and the per-workspace harness-dir probe starts there). The browser client half is web-profile-only and simply does not load.

Headless usage caveats (dsh 0.1.0-rc.6 verified):

  • One-shot turn model — the runner submits the task as one user message and exits when the agent goes idle (whenIdle()); it does NOT await run_in_background children. Foreground subagent dispatch works (a child session is created and its result reaches the parent); background QC-tri-style parallelism does NOT complete in-process — either dispatch QC seats foreground (serial wall time) or have the agent collect background results with tool-subagent-control BEFORE ending the turn.
  • No interaction channelask_user_question and approval prompts fail closed (there is no answerer). Use DSH_PERMISSION_MODE=danger-full-access for unattended runs (sandbox danger-full-access + approval never); interactive Prepare flows (grill-me) belong on the web profile.
  • Default model resolution — headless composes no fallbacks row, so an agent-default-model settings pin of FallbacksChain fails with NO_ADAPTER (the web-profile artifact). Point the default model at a real provider, or install dsh-llm-fallbacks into the headless profile too (note: on the published dsh 0.1.0-rc.6 the fallbacks settings integration predates the SettingsProvider.installSection API, so the virtual adapter does not register — this resolves with dsh ≥ 0.1.2-alpha).
  • Config via the profile user layer — profile-level cordis.patch.yml overrides work as documented (e.g. enforcement: hard + dispatchBinding on the mstar row); the mstar row's own config: {} stays neutral.

Configuration

KeyTypeDefaultMeaning
harnessDirstringrepo .mstarc [config] harness_dir, else 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; 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.
enforcement'hard' | 'soft'compass, else warn-onlyPer-deployment override. Precedence: Config wins; else the Assignment's own **Enforcement**: hard header flag (dispatch gate only); else the repo .mstarc [config] enforcement; else the iteration compass frontmatter; else warn-only. Config / .mstarc soft are the ONLY local rollbacks — an Assignment-level soft does NOT override a hard compass.
dispatchToolsstring[]['subagent', 'subagent_fork']Delegation tool names the dispatch gate matches — the dsh preset's TWO delegation tools, subagent and its fork sibling subagent_fork (both carry Assignment-shaped { description, prompt } args; a toolName config may rename instances).
dispatchBindingstringunset → fail-closed empty-binding under hardThe dispatching agent's own harness role (the anti-recursion CALLER); an Assignment whose Execute as equals it is self-recursion.
roleMapRecordunsetmstar role id (Execute as) → dsh-llm-fallbacks role id. A taxonomy bridge for logging + future rule-driven interop ONLY — never consulted by the persona channel (see LLM fallbacks integration).
rolePersonasRecordunset (bundled mirror default)mstar role id (Execute as) → persona text; the native subagent persona channel's override source — a role-matched start (one-shot start or the opt-in continuable startContinuable) merges the persona into the native request persona slot (the child embodies the role persona INSTEAD OF the deployment persona; persisted + reapplied on resume). Merge order: the request's own persona wins AS-IS (a caller-set persona is never overridden — no role merge); otherwise a non-empty entry beats the bundled harness-agents/ mirror default, an empty-string entry is treated as unset and falls through to the mirror default, and an absent entry uses the mirror default (see LLM fallbacks integration).
skillRootsstring[]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 /skills absolute path.
bundledSkillDirstringpackaged 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.
catalogTtlMsnumber60000Pre-step catalog cache refresh interval (ms): how often the per-workspace unified mstar-engine 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.
workflowGate'off' | 'warn' | 'ask' | 'hard''warn'Workflow/ralph gate mode (see Gates → Workflow / ralph gate). off = pass-through with no verdict row; warn = advisory-only; ask = first-seen names route through the approval waterfall (P-c); hard = policy violations veto before any child starts. Default warn changes NO hard behavior — the gate is advisory-only unless the deployment opts into ask/hard.
workflowNamesstring[]unsetWorkflow name allowlist (P-a): meta.name values treated as KNOWN by the gate. Empty or absent ⇒ every name is unknown (documented — the gate is NOT "allow all" by omission). Ralph calls carry no meta.name — P-a never applies to them. Recommended for the mstar read-only fan-out path: ['mstar-qc-tri', 'mstar-audit-fanout', 'mstar-pr-seats'].

Recommended operator overlay. The three recommended workflowNames above cover the mstar read-only fan-out path (plan QC tri, large-repo /codebase-audit, /amazing-pr-review deep); listing them is an operator overlay in the profile layer, never an mstar default. With the shipped empty list every name is unknown, which under the default workflowGate: 'warn' is one workflow.name.unknown advisory the run survives. A production deployment that also wants unknown names vetoed sets workflowGate: 'hard'; the shipped default stays 'warn'.

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).

Composed row set

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):

- name: '@deepseek-ai/dsh-skill'   # skill registry (ctx.skills) — dsh-base row
- name: '@deepseek-ai/dsh-tools'   # tool registry (ctx.tools) — dsh-base row
- name: '@deepseek-ai/dsh-commands' # command registry (ctx.commands) — dsh-base row
- name: '@mstar-harness/dsh'       # this bundle's patch insert (config: {} — plugin defaults apply)

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.

What the plugin does when mounted

  • Status gatefs/write-intent + fs/edit-intent listeners validate the v3 coordination-document target set — the v2 root {HARNESS_DIR}/status.json, workflows//snapshot.json and projects//residuals.json — each with its matching engine validator (validateStatus = v2 root / validateWorkflowSnapshot / validateProjectRegister, the P2-fixed harnessDocKindOfTarget shape), plus the snapshot-target findingsCleanupGate extension per plan row that configures a mode (residuals read from the project registers).
  • 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.
  • Skill-authoring lintSKILL.md writes under the configured skill roots run the engine skill-authoring lints (lintFrontmatter + lintFiveQuestion).
  • Seam lintsDESIGN.md / audit-plan / knowledge-doc / roles-dir writes under the harness get their artifact-specific engine lints.
  • Model-facing toolsmstar_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. The mstar_iteration_gate mirror takes the v3 input snapshot_path ({HARNESS_DIR}/workflows//snapshot.json — mirror of mstar iteration gate --workflow ; the old status_path root input is gone with the v1 read path).
  • Bundled commandsctx.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).
  • Pre-step catalog row — every composed agent step appends ONE unified mstar-engine 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-works