@mstar-harness/dsh 3.6.0-alpha.3 → 3.6.0

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 CHANGED
@@ -1,6 +1,6 @@
1
- # Translation pairing record for the @mstar-harness/dsh package README pair.
1
+ # packages/dsh README language-pair confirmation.
2
2
  # Blob hashes (git hash-object) of each side as of the last confirmation that
3
3
  # both languages say the same thing (dsh i18n contract: a pair is three
4
4
  # sibling files; editing either side obligates re-confirming and re-recording).
5
- README.md: 0ac2dde792b70de22ca30d83141dd3144a975c72
6
- README.zh.md: 29ec00188f7e58176dadb85d3688a4f7551dad74
5
+ README.md: a791ed87500a5164387bbb72277bb1d09406937b
6
+ README.zh.md: 9c9cc7399c34045c52ab72167e4a40779c9f917e
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [中文](README.zh.md)
4
4
 
5
- ![dsh](https://img.shields.io/badge/dsh-0.1.2--alpha.2-4B32C3.svg)
5
+ ![dsh](https://img.shields.io/badge/dsh-0.1.2--rc.1-4B32C3.svg)
6
6
 
7
7
  [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.
8
8
 
@@ -43,6 +43,23 @@ The **two-command install is the contract** — folding a `dsh-llm-fallbacks` ro
43
43
 
44
44
  > **Fresh-publish age window**: pnpm's `minimumReleaseAge` gate can make a `dsh plugin add <spec>` 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.
45
45
 
46
+ ### Headless profile (one-shot runs)
47
+
48
+ The plugin is not web-bound: it also mounts in the dsh **headless** profile (`dsh --profile headless "<task>"` — the one-shot, no-GUI/no-port mode). The install path is identical, one command:
49
+
50
+ ```sh
51
+ dsh plugin --profile headless add @mstar-harness/dsh
52
+ ```
53
+
54
+ 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.
55
+
56
+ **Headless usage caveats** (dsh 0.1.0-rc.6 verified):
57
+
58
+ - **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.
59
+ - **No interaction channel** — `ask_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.
60
+ - **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).
61
+ - **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.
62
+
46
63
  ### Configuration
47
64
 
48
65
  | Key | Type | Default | Meaning |
@@ -146,7 +163,7 @@ Distinct states: **mounted** (service applied — full capability), **unmounted*
146
163
 
147
164
  ### Role persona delivery (native subagent persona channel)
148
165
 
149
- Persona delivery rides dsh's NATIVE `SubagentStartRequest.persona` slot (`@deepseek-ai/dsh-subagent`): the plugin intercepts the `ctx.subagents` service READ through the cordis `internal/get` waterfall — the framework's documented service-read interception hook — and wraps the runtime value so a role-matched start merges the persona into the request BEFORE the child is composed — on BOTH start surfaces: the one-shot `start` AND the opt-in continuable `startContinuable` (tool-subagent `backgroundMode: 'continuable'`; its `ContinuableStartSpec.request` carries the same `persona` slot). The underlying `SubagentRuntime` object is never mutated (no monkey-patching), and the wrapping listener is fiber-scoped (an HMR re-apply unwinds and restores it, re-binding the fresh Config). Native semantics (dsh `0.1.2-alpha.2`): the request persona registers the scoped `deployment:persona` section (order 0) on the child, SHADOWING the deployment persona for that child alone — the child EMBODIES the role persona instead of coexisting with it — is persisted in the child descriptor, and is reapplied on resume. Role identity uses the SAME engine Assignment header grammar as the dispatch gate. Persona lookup is the single `personaFor` chain — `rolePersonas[executeAs]` → bundled mirror default → skip — **never gated on `roleMap` or on the fallbacks mounted state** (persona delivery is fallbacks-independent). An explicit request persona (tool-subagent's own `Config.persona`) wins over the role persona — caller intent is never overridden.
166
+ Persona delivery rides dsh's NATIVE `SubagentStartRequest.persona` slot (`@deepseek-ai/dsh-subagent`): the plugin intercepts the `ctx.subagents` service READ through the cordis `internal/get` waterfall — the framework's documented service-read interception hook — and wraps the runtime value so a role-matched start merges the persona into the request BEFORE the child is composed — on BOTH start surfaces: the one-shot `start` AND the opt-in continuable `startContinuable` (tool-subagent `backgroundMode: 'continuable'`; its `ContinuableStartSpec.request` carries the same `persona` slot). The underlying `SubagentRuntime` object is never mutated (no monkey-patching), and the wrapping listener is fiber-scoped (an HMR re-apply unwinds and restores it, re-binding the fresh Config). Native semantics: the request persona registers the scoped `deployment:persona` section (order 0) on the child, SHADOWING the deployment persona for that child alone — the child EMBODIES the role persona instead of coexisting with it — is persisted in the child descriptor, and is reapplied on resume. Role identity uses the SAME engine Assignment header grammar as the dispatch gate. Persona lookup is the single `personaFor` chain — `rolePersonas[executeAs]` → bundled mirror default → skip — **never gated on `roleMap` or on the fallbacks mounted state** (persona delivery is fallbacks-independent). An explicit request persona (tool-subagent's own `Config.persona`) wins over the role persona — caller intent is never overridden.
150
167
 
151
168
  **Capability gate (per surface)**: one-shot `SubagentRuntime.start` REJECTS a persona request for a provider without the native `persona` capability (fail loud, no silent degradation — out-of-process providers ship without it), so the channel checks `getProvider(name).capabilities.persona` FIRST on that surface. The continuable surface is gated by the NATIVE continuable contract instead — `SubagentCapabilities` is documented as ONE-SHOT-scoped and continuable children are composed by the continuation manager itself, gated by `provider.prepareContinuable`; the channel checks that, skipping the merge for providers without continuable support (the native start fails loud on its own — the persona is never logged as delivered for a start that would reject). Either way the merge is skipped with one contained debug log and the start proceeds unchanged — never a failed dispatch.
152
169
 
@@ -559,7 +576,7 @@ The catalog row is appended at the END of the composed step messages, after dele
559
576
  - **Entry is a module index over `src/gates/*`** — the split shipped: `src/index.ts` re-exports the frozen 56-name export surface (31 value + 25 type-only names; `Config` counts once) 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 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.
560
577
  - **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.
561
578
  - **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.
562
- - **`dsh-llm-fallbacks` is an optional dev-time-only dependency** — dsh `0.1.2-alpha.2` natively covers subagent customization, so fallbacks is strictly optional: `src/` carries zero imports of it (runtime and type — the consumed surface is the local structural mirror `fallbacks-structural.ts`, kept in sync by the probe's exact-keys drift gate plus the `typecheck:tests` real → view assignability check), `package.json` carries it only under `devDependencies` (type mirroring + the real-package test harness), and `dist/` carries no import and no type reference (only ONE string literal naming the package — the probe's loader-entry match; the advisory logs say `fallbacks`). Activation is a SEPARATE explicit install (two-command contract), never transitive; there is no `--external` guard anymore — a future value import must re-add a runtime dependency by design.
579
+ - **`dsh-llm-fallbacks` is an optional dev-time-only dependency** — dsh natively covers subagent customization, so fallbacks is strictly optional: `src/` carries zero imports of it (runtime and type — the consumed surface is the local structural mirror `fallbacks-structural.ts`, kept in sync by the probe's exact-keys drift gate plus the `typecheck:tests` real → view assignability check), `package.json` carries it only under `devDependencies` (type mirroring + the real-package test harness), and `dist/` carries no import and no type reference (only ONE string literal naming the package — the probe's loader-entry match; the advisory logs say `fallbacks`). Activation is a SEPARATE explicit install (two-command contract), never transitive; there is no `--external` guard anymore — a future value import must re-add a runtime dependency by design.
563
580
  - **Role→model override NOT delivered this batch** — routing a role to a fallbacks `model` (or persona via fallbacks rules) would require rewriting the child's `agentOptions` on the start request, but start-request options are caller-controlled (tool-subagent's own Config; call args are `description`/`prompt`/`run_in_background` only, deep-frozen). Awaits upstream `fallbacks-explicit-role-tool` or the N-B1 systemPrompt adoption (roadmap §10.4).
564
581
  - **Persona delivery is dsh-native — no additive section** — the role persona merges into `SubagentStartRequest.persona` (one-shot `start` AND the opt-in continuable `startContinuable`) and SHADOWS the deployment persona for role-matched children (child embodies the role; persisted + reapplied on resume). There is NO `mstar:role-persona` system-prompt section anymore (plan 20260831-dsh-alpha2-optional-fallbacks).
565
582
  - **Persona injection is fallbacks-independent** — `dsh-llm-fallbacks` only routes LLM failures; it is never required for persona delivery. Unmounted → the same persona lands via the native channel with the single delivery debug log (AC-4). One-shot starts for providers without the native `persona` capability (out-of-process) skip the persona with one contained debug log; continuable starts for providers without `prepareContinuable` skip it the same way (the native start fails loud on its own) — the start is never failed by the channel for either.
package/README.zh.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
- ![dsh](https://img.shields.io/badge/dsh-0.1.2--alpha.2-4B32C3.svg)
5
+ ![dsh](https://img.shields.io/badge/dsh-0.1.2--rc.1-4B32C3.svg)
6
6
 
7
7
  让 [Morning Star](https://github.com/btspoony/mstar-harness) 成为一等公民的 dsh(DeepSeek Harness)宿主——一个 cordis 函数插件,将 mstar engine 进程内挂载,实现 engine `HostAdapter`(`host: 'dsh'`),守护 `{HARNESS_DIR}/status.json` 写入(校验 + 咨询;hard 下按修复逃生放行),在 `Enforcement: hard` 开启时阻止被禁止的 subagent 派发,对挂载技能根下的 `SKILL.md` 写入执行技能撰写 lint,通过 dsh skill-filesystem 提供者挂载 mstar `skills/` 镜像(单一规范挂载),并向每个组合后的 agent 步骤追加一条持久化的 `mstar-engine-status` catalog 行。随 dsh Loader 应用启动;一切均通过 seam 的拒绝/咨询通道行使职责,从不改动工具本身。
8
8
 
@@ -43,6 +43,22 @@ dsh plugin --profile web add dsh-llm-fallbacks
43
43
 
44
44
  > **fresh publish 年龄窗口提示**:pnpm 的 `minimumReleaseAge` 门禁可能让 `dsh plugin add <spec>` 的 range 解析在全新发布后约 24h 内选中旧版本(不含 seeds surface)——窗口过后重跑 `npx @mstar-harness/cli init --target dsh`(或显式 pin 版本)即可收敛到最新 surface。
45
45
 
46
+ ### Headless profile(一次性运行)
47
+
48
+ 本插件并非 web 专属:它同样可以挂载进 dsh **headless** profile(`dsh --profile headless "<task>"`——一次性、无 GUI/无端口模式)。安装路径完全一致,一条命令:
49
+
50
+ ```sh
51
+ dsh plugin --profile headless add @mstar-harness/dsh
52
+ ```
53
+
54
+ 出厂 headless 模板在首次使用时自动初始化(`@deepseek-ai/dsh-base` + `@deepseek-ai/dsh-headless`),reconcile 步骤把 mstar 行追加进 bundle 层栈(`dsh-base → dsh-headless → @mstar-harness/dsh`)。插件的所有能力都落在 headless 继承的 `dsh-base` seam 上——status/dispatch/lease/worktree 闸门、技能挂载、engine-status catalog、harness-rules system-prompt 注入、7 个模型面工具——因此在一次性运行中 harness 完整生效。**必须从仓库工作目录启动**(runner 写入 `meta.cwd = process.cwd()`,按工作区的 harness 目录探测从这里开始)。浏览器客户端半体仅属于 web profile,headless 下自然不加载。
55
+
56
+ **Headless 使用注意事项**(已在 dsh 0.1.0-rc.6 上验证):
57
+
58
+ - **一次性 turn 模型**——runner 把任务作为一条 user message 提交,agent 转入 idle(`whenIdle()`)后即退出;它**不会**等待 `run_in_background` 子任务。前台 subagent 派发可用(创建子会话、结果回到父会话);后台 QC-tri 式并行在进程内不会完成——要么前台派发 QC 席(串行墙钟时间),要么让 agent 在结束 turn **之前**用 `tool-subagent-control` 收集完后台结果。
59
+ - **无交互通道**——`ask_user_question` 与审批提示 fail-closed(没有应答者)。无人值守运行用 `DSH_PERMISSION_MODE=danger-full-access`(sandbox `danger-full-access` + approval `never`);交互式 Prepare 流程(grill-me)属于 web profile。
60
+ - **默认模型解析**——headless 不组合 fallbacks 行,因此 settings 里 `agent-default-model` 钉在 `FallbacksChain` 会以 `NO_ADAPTER` 失败(web profile 的产物)。把默认模型指向真实 provider,或同样把 `dsh-llm-fallbacks` 装进 headless profile(注意:已发布的 dsh 0.1.0-rc.6 上,fallbacks 的 settings 集成早于 `SettingsProvider.installSection` API,虚拟适配器不会注册——随 dsh ≥ 0.1.2-alpha 解决)。
61
+
46
62
  ### Configuration
47
63
 
48
64
  | Key | Type | Default | Meaning |
@@ -146,7 +162,7 @@ profile bundle 组合出以下行——注册表行来自 `@deepseek-ai/dsh-base
146
162
 
147
163
  ### 角色 persona 交付(原生 subagent persona 通道)
148
164
 
149
- persona 交付走 dsh 原生的 `SubagentStartRequest.persona` 槽(`@deepseek-ai/dsh-subagent`):插件经 cordis `internal/get` waterfall——框架文档化的服务读取拦截钩子——拦截 `ctx.subagents` 的服务读取并包装运行时值,使角色匹配的 start 在子会话组装之前把 persona 合入请求——**同时覆盖两个启动面**:一次性 `start` 与可选的 continuable `startContinuable`(tool-subagent `backgroundMode: 'continuable'`;其 `ContinuableStartSpec.request` 携带同一个 `persona` 槽)。底层 `SubagentRuntime` 对象绝不被改动(无 monkey-patching),包装监听器归 apply fiber 所有(HMR 重挂载会先卸载再恢复,并重新绑定新 Config)。原生语义(dsh `0.1.2-alpha.2`):请求 persona 会以作用域化的 `deployment:persona` 段(order 0)注册到子会话上,对该子会话**遮蔽**部署 persona——子会话**体现**角色 persona 而非与其共存——并持久化进子会话描述符、在 resume 时重放。角色身份使用与派发闸门相同的 engine Assignment 头语法。persona 查找是单一 `personaFor` 链——`rolePersonas[executeAs]` → 打包镜像默认 → 跳过——**从不以 `roleMap` 或 fallbacks 挂载状态为前提**(persona 交付与 fallbacks 无关)。显式的请求 persona(tool-subagent 自身的 `Config.persona`)优先于角色 persona——绝不覆盖调用方意图。
165
+ persona 交付走 dsh 原生的 `SubagentStartRequest.persona` 槽(`@deepseek-ai/dsh-subagent`):插件经 cordis `internal/get` waterfall——框架文档化的服务读取拦截钩子——拦截 `ctx.subagents` 的服务读取并包装运行时值,使角色匹配的 start 在子会话组装之前把 persona 合入请求——**同时覆盖两个启动面**:一次性 `start` 与可选的 continuable `startContinuable`(tool-subagent `backgroundMode: 'continuable'`;其 `ContinuableStartSpec.request` 携带同一个 `persona` 槽)。底层 `SubagentRuntime` 对象绝不被改动(无 monkey-patching),包装监听器归 apply fiber 所有(HMR 重挂载会先卸载再恢复,并重新绑定新 Config)。原生语义:请求 persona 会以作用域化的 `deployment:persona` 段(order 0)注册到子会话上,对该子会话**遮蔽**部署 persona——子会话**体现**角色 persona 而非与其共存——并持久化进子会话描述符、在 resume 时重放。角色身份使用与派发闸门相同的 engine Assignment 头语法。persona 查找是单一 `personaFor` 链——`rolePersonas[executeAs]` → 打包镜像默认 → 跳过——**从不以 `roleMap` 或 fallbacks 挂载状态为前提**(persona 交付与 fallbacks 无关)。显式的请求 persona(tool-subagent 自身的 `Config.persona`)优先于角色 persona——绝不覆盖调用方意图。
150
166
 
151
167
  **能力闸门(按启动面)**:一次性 `SubagentRuntime.start` 会对不具备原生 `persona` 能力的提供者直接拒绝 persona 请求(fail loud、绝不静默降级——进程外提供者即无此能力),因此该启动面通道先检查 `getProvider(name).capabilities.persona`。continuable 启动面改按**原生 continuable 契约**闸门——`SubagentCapabilities` 文档仅限一次性路径,continuable 子会话由延续管理器自行组装、以 `provider.prepareContinuable` 为闸门;通道检查该字段,对不支持 continuable 的提供者跳过合并(原生 start 会自行 fail loud——绝不会在会被拒绝的 start 上把 persona 记为已交付)。两种情况都以一条受控 debug 日志跳过合并、启动原样继续——通道绝不因此使派发失败。
152
168
 
@@ -332,7 +348,7 @@ catalog 行在委托之后追加到组合步骤消息的**末尾**——请求
332
348
  - **入口是 `src/gates/*` 之上的模块索引**——拆分已交付:`src/index.ts` 从各 gate 模块(`_shared` / `status` / `skill-lint` / `seams` / `dispatch` / `catalog` / `tools` / `adapter`)原样 re-export 冻结的 56 名导出面(31 值导出 + 25 type-only 名;`Config` 计一次),并保留插件 manifest、单一 cordis augmentation 点、命令注册与 `apply()` 启动接线。导出面由 `tests/export-surface.spec.ts` 冻结——运行时值导出集 + `typecheck:tests`(`bunx tsc --noEmit -p tests/tsconfig.json`)下的值命名空间恒等与逐名类型探测。
333
349
  - **engine dsh 行待上游化**——engine `host.ts` 的 dsh 改动(`DetectResult`、`ToolSignal`、`resolveSkillRoot`)位于 mstar-workflow engine 镜像,计划经用户授权的上游 PR 合入 mstar-harness;`mstar-host` 技能镜像(§ Detect / § Resolve loaded skill root / `references/dsh.md`)随之一并更新。
334
350
  - **迭代 stepper:Step 1 为 compass 驱动,Step 5 为 schema 驱动**——zone dashboard 的 Step 1(iteration-start)在 steering compass `status: active`(Phase 1 进行中)时为当前步(无 gate 判定 → 无 PASS/FAIL 徽标);Step 5(merge-ready)是 engine 闸门永不点亮为当前的 schema 常量(transition 只覆盖 Phase 2→3→4,merge-ready 从不是 gate transition);仅当 Step 4 为当前步时作为 `next` 渲染,其余为 idle——已记录于迭代 guide,非缺陷。完整面板限制清单见 Web 客户端插件一节。
335
- - **`dsh-llm-fallbacks` 为可选的开发期依赖**——dsh `0.1.2-alpha.2` 原生覆盖 subagent 定制,fallbacks 因此严格可选:`src/` 对其零导入(运行时与类型——被消费面是本地结构镜像 `fallbacks-structural.ts`,由探测的 exact-keys 漂移闸门 + `typecheck:tests` 的 real → view 可赋值检查保持同步),`package.json` 仅在 `devDependencies` 携带它(类型镜像 + 真实包测试 harness),`dist/` 无导入也无类型引用(仅 1 处命名该包的字符串字面量——探测的 loader 条目匹配;建议日志写作 `fallbacks`)。激活是**单独显式安装**(双命令契约),绝不传递;不再有 `--external` 护栏——未来的值导入必须按设计重新加入运行时依赖。
351
+ - **`dsh-llm-fallbacks` 为可选的开发期依赖**——dsh 原生覆盖 subagent 定制,fallbacks 因此严格可选:`src/` 对其零导入(运行时与类型——被消费面是本地结构镜像 `fallbacks-structural.ts`,由探测的 exact-keys 漂移闸门 + `typecheck:tests` 的 real → view 可赋值检查保持同步),`package.json` 仅在 `devDependencies` 携带它(类型镜像 + 真实包测试 harness),`dist/` 无导入也无类型引用(仅 1 处命名该包的字符串字面量——探测的 loader 条目匹配;建议日志写作 `fallbacks`)。激活是**单独显式安装**(双命令契约),绝不传递;不再有 `--external` 护栏——未来的值导入必须按设计重新加入运行时依赖。
336
352
  - **本批次未交付角色→模型覆盖**——把角色路由到 fallbacks `model`(或经 fallbacks 规则路由 persona)需要改写启动请求上的子会话 `agentOptions`,但启动请求选项由调用方控制(tool-subagent 自己的 Config;调用参数仅为 `description`/`prompt`/`run_in_background`,且深度冻结)。等待上游 `fallbacks-explicit-role-tool` 或 N-B1 systemPrompt 采纳(roadmap §10.4)。
337
353
  - **persona 交付为 dsh 原生——不再有附加段**——角色 persona 合入 `SubagentStartRequest.persona`(一次性 `start` 与可选的 continuable `startContinuable` 两个启动面),对角色匹配的子会话**遮蔽**部署 persona(子会话体现角色;持久化并在 resume 时重放)。`mstar:role-persona` system-prompt 段已不复存在(plan 20260831-dsh-alpha2-optional-fallbacks)。
338
354
  - **persona 注入与 fallbacks 无关**——`dsh-llm-fallbacks` 只路由 LLM 失败;persona 交付从不依赖它。未挂载 → 同一 persona 经原生通道交付,仅一条交付 debug 日志(AC-4)。一次性 start 中不具备原生 `persona` 能力的提供者(进程外)以一条受控 debug 日志跳过 persona;continuable start 中不具备 `prepareContinuable` 的提供者同样跳过(原生 start 会自行 fail loud)——通道绝不因两者使 start 失败。
package/dist/client.js CHANGED
@@ -6,46 +6,69 @@ var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ function __accessProp(key) {
10
+ return this[key];
11
+ }
12
+ var __toESMCache_node;
13
+ var __toESMCache_esm;
9
14
  var __toESM = (mod, isNodeMode, target) => {
15
+ var canCache = mod != null && typeof mod === "object";
16
+ if (canCache) {
17
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
+ var cached = cache.get(mod);
19
+ if (cached)
20
+ return cached;
21
+ }
10
22
  target = mod != null ? __create(__getProtoOf(mod)) : {};
11
23
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
12
- for (let key of __getOwnPropNames(mod))
13
- if (!__hasOwnProp.call(to, key))
14
- __defProp(to, key, {
15
- get: () => mod[key],
16
- enumerable: true
17
- });
24
+ if (mod && typeof mod === "object" || typeof mod === "function") {
25
+ for (let key of __getOwnPropNames(mod))
26
+ if (!__hasOwnProp.call(to, key))
27
+ __defProp(to, key, {
28
+ get: __accessProp.bind(mod, key),
29
+ enumerable: true
30
+ });
31
+ }
32
+ if (canCache)
33
+ cache.set(mod, to);
18
34
  return to;
19
35
  };
20
- var __moduleCache = /* @__PURE__ */ new WeakMap;
21
36
  var __toCommonJS = (from) => {
22
- var entry = __moduleCache.get(from), desc;
37
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
23
38
  if (entry)
24
39
  return entry;
25
40
  entry = __defProp({}, "__esModule", { value: true });
26
- if (from && typeof from === "object" || typeof from === "function")
27
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
28
- get: () => from[key],
29
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
- }));
41
+ if (from && typeof from === "object" || typeof from === "function") {
42
+ for (var key of __getOwnPropNames(from))
43
+ if (!__hasOwnProp.call(entry, key))
44
+ __defProp(entry, key, {
45
+ get: __accessProp.bind(from, key),
46
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
47
+ });
48
+ }
31
49
  __moduleCache.set(from, entry);
32
50
  return entry;
33
51
  };
52
+ var __moduleCache;
53
+ var __returnValue = (v) => v;
54
+ function __exportSetter(name, newValue) {
55
+ this[name] = __returnValue.bind(null, newValue);
56
+ }
34
57
  var __export = (target, all) => {
35
58
  for (var name in all)
36
59
  __defProp(target, name, {
37
60
  get: all[name],
38
61
  enumerable: true,
39
62
  configurable: true,
40
- set: (newValue) => all[name] = () => newValue
63
+ set: __exportSetter.bind(all, name)
41
64
  });
42
65
  };
43
66
 
44
67
  // src/client/index.ts
45
68
  var exports_client = {};
46
69
  __export(exports_client, {
47
- inject: () => inject,
48
- apply: () => apply
70
+ apply: () => apply,
71
+ inject: () => inject
49
72
  });
50
73
  module.exports = __toCommonJS(exports_client);
51
74
 
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Local structural mirrors of the consumed `dsh-llm-fallbacks` surface
3
- * (plan `20260831-dsh-alpha2-optional-fallbacks` Task 2). dsh
4
- * `0.1.2-alpha.2` natively covers subagent customization, so the fallbacks
3
+ * (plan `20260831-dsh-alpha2-optional-fallbacks` Task 2). dsh natively
4
+ * covers subagent customization, so the fallbacks
5
5
  * plugin is an OPTIONAL capability activated by the unchanged two-command
6
6
  * install contract — and a dev-time-only dependency of this package (type
7
7
  * mirroring here + the real-package test harness). The published package
8
8
  * carries ZERO runtime AND ZERO type references to `dsh-llm-fallbacks`.
9
9
  *
10
- * Shapes mirror `dsh-llm-fallbacks@0.4.0-alpha.1` `dist/index.d.ts`
10
+ * Shapes mirror `dsh-llm-fallbacks` `dist/index.d.ts`
11
11
  * (`FallbacksService`) and `dist/seeds.d.ts` (`SeedDeclaration`,
12
12
  * `SeedSkipReason`, `SeedConflict`, `SeedDeclareOutcome`, `EffectiveRole`,
13
13
  * `EffectiveRolesReadback`). Drift gates keeping the mirrors in sync:
package/dist/index.js CHANGED
@@ -3,21 +3,37 @@ var __getProtoOf = Object.getPrototypeOf;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toESMCache_node;
10
+ var __toESMCache_esm;
6
11
  var __toESM = (mod, isNodeMode, target) => {
12
+ var canCache = mod != null && typeof mod === "object";
13
+ if (canCache) {
14
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
15
+ var cached = cache.get(mod);
16
+ if (cached)
17
+ return cached;
18
+ }
7
19
  target = mod != null ? __create(__getProtoOf(mod)) : {};
8
20
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
9
- for (let key of __getOwnPropNames(mod))
10
- if (!__hasOwnProp.call(to, key))
11
- __defProp(to, key, {
12
- get: () => mod[key],
13
- enumerable: true
14
- });
21
+ if (mod && typeof mod === "object" || typeof mod === "function") {
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ }
29
+ if (canCache)
30
+ cache.set(mod, to);
15
31
  return to;
16
32
  };
17
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
18
34
 
19
- // ../../node_modules/cosmokit/lib/index.cjs
20
- var require_lib = __commonJS((exports, module) => {
35
+ // ../../node_modules/.bun/cosmokit@1.8.1/node_modules/cosmokit/lib/index.cjs
36
+ var require_lib = __commonJS(function(exports, module) {
21
37
  var __defProp2 = Object.defineProperty;
22
38
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
23
39
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
@@ -411,8 +427,8 @@ var require_lib = __commonJS((exports, module) => {
411
427
  })(Time || (Time = {}));
412
428
  });
413
429
 
414
- // ../../node_modules/schemastery/lib/index.cjs
415
- var require_lib2 = __commonJS((exports, module) => {
430
+ // ../../node_modules/.bun/schemastery@3.18.0/node_modules/schemastery/lib/index.cjs
431
+ var require_lib2 = __commonJS(function(exports, module) {
416
432
  var __defProp2 = Object.defineProperty;
417
433
  var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
418
434
  var import_cosmokit = require_lib();
@@ -663,7 +679,7 @@ var require_lib2 = __commonJS((exports, module) => {
663
679
  Schema.extend = /* @__PURE__ */ __name(function extend(type, resolve22) {
664
680
  resolvers[type] = resolve22;
665
681
  }, "extend");
666
- Schema.resolve = /* @__PURE__ */ __name(function resolve(data, schema, options = {}, strict = false) {
682
+ Schema.resolve = /* @__PURE__ */ __name(function resolve4(data, schema, options = {}, strict = false) {
667
683
  if (!schema)
668
684
  return [data];
669
685
  if (options.ignore?.(data, schema))
@@ -8573,35 +8589,35 @@ function apply(ctx, config) {
8573
8589
  registerSeamTools(ctx, resolver);
8574
8590
  }
8575
8591
  export {
8576
- skillLocalConfig,
8577
- setRolePersonaLogger,
8578
- setRolePersonaAgentsDir,
8579
- setAdvisoryLogger,
8580
- runFallbacksAdvisory,
8581
- registerRolePersonaChannel,
8582
- recordWorkflowVerdict,
8583
- recordSettle,
8584
- recordDispatch,
8585
- readAgentFlow,
8586
- name,
8587
- lintSkillWrite,
8588
- lintSkillDoc,
8589
- lintSeamWrite,
8590
- lintRolesWrite,
8591
- lintDesignMdWrite,
8592
- lintCompoundWrite,
8593
- lintAuditWrite,
8594
- inject,
8595
- apply,
8596
- SkillLintVetoError,
8597
- SeamVetoError,
8598
- SETTLE_SEAM,
8599
- ROLE_PERSONA_LOGGER,
8600
- HarnessResolver,
8601
- DshMstar,
8602
- DshHostAdapter,
8603
- Config,
8604
- AGENT_FLOW_MAX_EVENTS,
8592
+ ADVISORY_LOGGER,
8605
8593
  AGENT_FLOW_FILE,
8606
- ADVISORY_LOGGER
8594
+ AGENT_FLOW_MAX_EVENTS,
8595
+ Config,
8596
+ DshHostAdapter,
8597
+ DshMstar,
8598
+ HarnessResolver,
8599
+ ROLE_PERSONA_LOGGER,
8600
+ SETTLE_SEAM,
8601
+ SeamVetoError,
8602
+ SkillLintVetoError,
8603
+ apply,
8604
+ inject,
8605
+ lintAuditWrite,
8606
+ lintCompoundWrite,
8607
+ lintDesignMdWrite,
8608
+ lintRolesWrite,
8609
+ lintSeamWrite,
8610
+ lintSkillDoc,
8611
+ lintSkillWrite,
8612
+ name,
8613
+ readAgentFlow,
8614
+ recordDispatch,
8615
+ recordSettle,
8616
+ recordWorkflowVerdict,
8617
+ registerRolePersonaChannel,
8618
+ runFallbacksAdvisory,
8619
+ setAdvisoryLogger,
8620
+ setRolePersonaAgentsDir,
8621
+ setRolePersonaLogger,
8622
+ skillLocalConfig
8607
8623
  };
package/dist/invariant.js CHANGED
@@ -3,15 +3,31 @@ var __getProtoOf = Object.getPrototypeOf;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toESMCache_node;
10
+ var __toESMCache_esm;
6
11
  var __toESM = (mod, isNodeMode, target) => {
12
+ var canCache = mod != null && typeof mod === "object";
13
+ if (canCache) {
14
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
15
+ var cached = cache.get(mod);
16
+ if (cached)
17
+ return cached;
18
+ }
7
19
  target = mod != null ? __create(__getProtoOf(mod)) : {};
8
20
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
9
- for (let key of __getOwnPropNames(mod))
10
- if (!__hasOwnProp.call(to, key))
11
- __defProp(to, key, {
12
- get: () => mod[key],
13
- enumerable: true
14
- });
21
+ if (mod && typeof mod === "object" || typeof mod === "function") {
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ }
29
+ if (canCache)
30
+ cache.set(mod, to);
15
31
  return to;
16
32
  };
17
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
@@ -23,7 +39,7 @@ var inject = ["invariants"];
23
39
  var install = () => {};
24
40
  var apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
25
41
  export {
26
- name,
42
+ apply,
27
43
  inject,
28
- apply
44
+ name
29
45
  };
@@ -7,50 +7,25 @@ input: "[pr|branch|scope] [quick|default|deep]"
7
7
 
8
8
  # Deep PR Review
9
9
 
10
- Run a read-only, evidence-first deep review of a pull request, branch, or diff and decide whether it is safe to ship. When a PR number exists, posting the GitHub Review is **mandatory** the review is not complete until comments land on the PR. Output: verdict + findings presented to the user, plus the posted review URL. Never auto-approve, never REQUEST_CHANGES, never merge.
10
+ Run a read-only, evidence-first review of a PR / branch / diff and decide whether it is safe to ship. Output: one verdict **computed from the finding tally**, never chosen(`score_pct` display-only)— plus findings presented to the user, and the posted GitHub Review URL when a PR number exists(posting is **mandatory** then). Never auto-approve, never REQUEST_CHANGES, never merge. **Read-only advisory** — does not enter the plan state machine.
11
11
 
12
- The verdict is **computed from the finding tally** (`must-fix` / `should-fix` / `nit` + `unverified`); `score_pct` is display-only feedback and never overrides it. Procedure and formula **`references/pr-review.md`** § Verdict synthesis / Tally and derived score.
13
-
14
- **Read-only advisory.** The review does not enter the harness plan state machine (`Todo → InProgress → InReview → Done`). Reviewers never edit the worktree, never merge, and never approve-as-merge.
12
+ Procedure SSOT **`mstar-audit` SKILL.md**(common core)+ **`references/pr-review.md`**(`pr` variant 全量:tier 解析、三阶段流水线、worktree isolation、posting、report archive、batch). This command is a thin launcher every contract lives in the reference.
15
13
 
16
14
  ## Boot
17
15
 
18
16
  1. `mstar-harness-core`
19
- 2. `mstar-audit` → SKILL.md(common core)+ `references/pr-review.md`(`pr` variant 全量)
17
+ 2. `mstar-audit` → SKILL.md + `references/pr-review.md`
20
18
  3. `mstar-coding-behavior` (evidence discipline)
21
19
  4. `mstar-branch-worktree` (worktree isolation)
22
20
  5. `mstar-host` → active host reference (invoke capability for parallel subagents)
23
- 6. 多 PR 输入的 batch 语义 → `references/pr-review.md` § Batch(one session = one PR;first-only + audit todos)
24
- 7. 档位解析后 → 按 `references/pr-review.md` § Review depth (tiers) 确认 seat 计划(quick 1 席 / default 2 席 / deep 三阶段)
25
-
26
- ## Routing(谁执行 review)
27
-
28
- **档位解析** — 显式档位 token 优先;无 flag 时按推断阶梯(自上而下,首个命中即定档):
29
-
30
- 1. **显式档位 token**(仅认专用 token 形式:`--quick` / `--default` / `--deep` flag,或参数末尾独立档位词;绝不匹配 `[pr|branch|scope]` 参数中的子串)→ 直接定档(用户意图 > 一切启发式)。任意两个档位 token 同现(`quick` / `default` / `deep` 任取其二)→ **硬停止冲突**:报告冲突,请用户二选一,不静默取优先级。
31
- 2. **too-large**(> ~1000 变更行)→ advise split(既有规则不变);坚持审 → `deep`。
32
- 3. **敏感面**(`security-review.md` §9 扩展面出现在 diff:auth / LLM / 供应链 / 数据面)→ `deep`(任何尺寸;安全敏感不打薄)。
33
- 4. **large**(> ~300 变更行 / 跨多变更面)→ `deep`(大 PR 不静默降档)。
34
- 5. **small**(≤ ~300 单面):tiny-mechanical 形状(docs-only / 重命名 / 格式化 / 纯删除)→ `quick`;其余真实代码变更 → `default`。
35
-
36
- 复用既有 100 / 300 / 1000 sizing bands(`pr-review.md` § Sizing & change shape),不引入第二套数字:`~100`(tiny-mechanical 带)≈ `quick` 推荐域;`~300`(one logical change 上沿 = 扇出阈值)为 `default` 上界;`~1000`(too-large → advise split)语义不变。显式 `quick` + 敏感面 → 尊重用户,但该席仍须执行领域内 security lens,且报告 `- notes:` 声明「quick tier — reduced coverage on a security-sensitive surface」。
37
-
38
- | Context | Who runs the review |
39
- |---------|-------------------|
40
- | **Single PR — `quick`**(1 席,≈ ¼ deep 席位时间) | 收集 + review 合入**同一席**一趟(不切领域);席内带领域内 security lens;**无独立 security 席**;报告 `tier: quick` + `- notes:` 降档覆盖声明 |
41
- | **Single PR — `default`**(2 席 ≈ ½ deep 席位时间) | 2 个领域席:收集合入领域席 = **席位复用**(Stage 1 不单独成波);两席均带领域内 security lens;**无独立 cross-domain 席**(跨域边界问题记 `- notes:`,主代理可宣布升级 `deep`);报告 `tier: default` |
42
- | **Single PR — `deep`**(4–7 席) | 三阶段全走(= 现状逐字):**Stage 1** 按领域扇出 2–3 轻量只读收集 agents(host scout/explorer/general)→ **Stage 2** 按同一领域派 2–3 mstar 内置角色(`code-reviewer` / `fullstack-dev` / `frontend-dev`)+ 大 PR/安全敏感面 0–1 独立 cross-domain security 席 → **Stage 3** 主代理合成:dedupe + three-way vet → tally/verdict → 报告 + 发布 GitHub Review;报告 `tier: deep` |
43
- | **Multiple PRs** | 只对**第一个** PR 按档位路由走 review(同 Single PR);其余 PR 登记为 audit todos(`{PROJECT_DIR}/_default/residuals.json`,`decision: defer`、`target: next session`、`tracking: pr-deep-review backlog`),并建议每个 PR 开独立 session |
44
-
45
- All review seats are **read-only** in this flow: never edit the reviewed worktree, never merge, never approve-as-merge. **Stage 1** collect seats are the host's lightweight read-only agents (`scout` / `explorer` / `general`); **Stage 2** domain seats are mstar built-in roles (`code-reviewer` / `fullstack-dev` / `frontend-dev`). All seats run in **Audit Mode** (shared contract → `mstar-roles` `references/_shared/leaf-executor-core.md`). PM dispatches; every seat returns evidence / findings in its **result payload** (any seat may be **write-blocked**; writable seats may **best-effort** write their evidence file directly — the main agent writes / consolidates) — no verdict token, no posting; the main agent (PM / command thread) synthesizes and publishes.
46
21
 
47
22
  ## Execute
48
23
 
49
- Execute **`mstar-audit`** § `pr` variant end to end(SKILL.md common core:recon + three-way attack & vet;variant detail:**`references/pr-review.md`** —— resolve the review **tier** first → **§ Review depth (tiers)**(档位表 + 推断阶梯 + seat 计划 + 报告 `tier` 声明); the linear `scope → guidance load → concern lenses → evidence → verdict → output` path is **Stage 3's** read of the variant; seats run per the tier's seat plan and **§ Review pipeline**). Review is run in a dedicated worktree against a diff from the PR's **real base** — resolve the base per `references/pr-review.md` § Worktree isolation (never assume `main`).
50
- **Tiered execution** — the resolved tier(§ Review depth (tiers))shapes the run: `deep` = 三阶段全走(现状逐字);`default` = 2 领域席、收集合入领域席(Stage 1 不单独成波);`quick` = 1 席、收集 + review 同席。The deep tier runs the pipeline in **`references/pr-review.md`** § Review pipeline: **Stage 1** collect seats fan out by domain and return evidence in their result payload; **Stage 2** domain seats review code + security and return findings; **Stage 3** the main agent (PM / command thread) synthesizes. **Any seat may be write-blocked** (read-only sandbox / EPERM) — seats return evidence / findings in their **result payload** and are **never required to write files**; writable seats may **best-effort** write their evidence file directly; the main agent **writes / consolidates all evidence files** from seat payloads → dedupe + three-way vet → tally/verdict → report + GitHub Review POST. Posting has three branches (§ Comment posting): `posted: yes` / `n/a-no-pr` / `failed` — chat output and the local report are delivered in all three. Worktree cleanup is done by the main agent once the local report is saved — the save runs in all three posting branches (`posted: yes` / `n/a-no-pr` / `failed`), so cleanup does not wait on POST success (§ Worktree isolation / § Local report archive).
51
-
52
- Review findings that need fixing can be turned into self-contained plans for the normal Prepare → Execute flow (reusing `mstar-audit` SKILL.md **`## Plan output (all variants)`** — same contract as the `pr` variant).
24
+ Execute **`mstar-audit` § `pr` variant end to end**(`references/pr-review.md`):
53
25
 
54
- Output verdict + findings to the user, with the posted GitHub Review URL. Posting procedure (when a PR number exists) → **`references/pr-review.md`** § Comment posting; the main agent saves the Stage 3 report and writes/consolidates the evidence files every seat returns evidence / findings in its **result payload** (any seat may be write-blocked); writable seats may **best-effort** write files in addition → **`references/pr-review.md`** § Local report archive. Never auto-approve or merge.
26
+ 1. **Tier first** resolve `quick` / `default` / `deep` per **§ Review depth (tiers)**(显式 token > too-large > 敏感面 > large > small 推断阶梯;两 token 同现 hard-stop 请用户二选一)→ tier seat 计划执行(quick 1 / default 2 / deep 三阶段)。
27
+ 2. **Isolate** — create the review worktree per **§ Worktree isolation**(real base,never assume `main`;empty changeset → stop;diff snapshot pinned at setup)→ fan out seats per **§ Review pipeline**(seats read-only,evidence/findings in result payload,never post;seat prompts get `--diff-file` via `mstar pr-review seat-prompt`).
28
+ 3. **Synthesize (main agent)** — dedupe + three-way vet → tally/verdict(**§ Tally and derived score**)→ persist the **`mstar.review/v1` envelope**(mandatory)→ report + GitHub Review POST per **§ Comment posting**(`posted: yes` / `n/a-no-pr` / `failed`;event fixed `COMMENT`)→ save local report + evidence files per **§ Local report archive**(all three posting branches)→ **then** worktree cleanup(`mstar pr-review worktree-cleanup`).
29
+ 4. **Batch** — one session = one PR per **§ Batch sibling PRs**;其余 PR → `mstar status backlog-register` 登记为 audit todos,建议各自独立 session.
55
30
 
56
- **Stage 3 envelope (mandatory):** after the tally, the main agent **must** fold the accepted findings into a `mstar.review/v1` envelope (`synthesizeReview` — or the equivalent engine call) and persist it via `mstar-harness persist review --key <plan-or-pr-id> --stdin` (or `getArtifactStore().put`). The Markdown archive is an optional human copy **not** a substitute for the envelope. Procedure → **`references/pr-review.md`** § Review pipeline (Stage 3).
31
+ Findings that need fixing self-contained plans per **`mstar-audit` SKILL.md `## Plan output (all variants)`**(normal Prepare Execute flow). Report the verdict + findings + posted review URL; the `tier:` declaration and any downgrade/upgrade `- notes:` follow **§ Review depth (tiers)** report contract.
@@ -76,7 +76,7 @@ The durable summary is not a paste of raw reports. It is a small gate record suf
76
76
  - **并行 vs 串行**:不同 `plan_id` **相互独立**时,可 **并行**派发多组三审(每组各自的 Assignment 与 `{SDD_DIR}/review/`);若 PM 选择串行,须在 Status Update 写明顺序——**每组仍须完整三审 + QA**,不是「一个大 QC」混审。
77
77
  - **读 skill**:书写或派发 QC 相关 Assignment 前,PM **必须** Read **`mstar-review-qc`**(编排与 residual);leaf `qc-specialist*` → **`mstar-roles/references/qc-specialist/`**。见 `mstar-conventions` SKILL.md **QC pre-dispatch gate**。
78
78
 
79
- **QC 落盘与宿主权限**:`qc-specialist` / `qc-specialist-2` / `qc-specialist-3` 在支持路径白名单的宿主上(如 OpenCode 的 **`permission.edit`**),默认 **仅可** Write/Edit Assignment 指定的 **`{SDD_DIR}/review/`** 下 **`.md`**。全局 agent 提示词应允许 `.mstar/sdd/**`、`.agents/sdd/**` 及 worktree 下对应路径。报告文件**必须**以 YAML **frontmatter** 开头(键见各 QC agent 提示词)。
79
+ **QC 落盘与宿主权限**:`qc-specialist` / `qc-specialist-2` / `qc-specialist-3` 在支持路径白名单的宿主上(如 OpenCode 的 **`permission.edit`**),默认 **仅可** Write/Edit Assignment 指定的 **`{SDD_DIR}/review/`** 下 **`.md`**。全局 agent 提示词应允许 `.mstar/sdd/**`、`.agents/sdd/**` 及 `.worktrees/**`。报告文件**必须**以 YAML **frontmatter** 开头(键见各 QC agent 提示词)。
80
80
 
81
81
  **QC 报告与 Git**:默认 raw QC/QA bundle **不**执行 `git add` / `git commit`。PM 将 durable gate summary 写入主 plan(本地会话 SSOT;默认 gitignored)并在当轮更新 project register 的 open residuals(本地 SSOT,默认 gitignored)。**跨 clone 须持久的** residual 或决策须提升入 tracked `{KNOWLEDGE_DIR}/` / `{SPECS_DIR}/` 或 `{HARNESS_DIR}/AGENTS.md`(见 `mstar-conventions`「Git 跟踪策略」)— **勿**默认 `git add` `status.json` / `workflows/` / `projects/` / `plans/`。若项目显式 opt-in 跟踪审计报告,在 Assignment 写 `Review archive mode: tracked reports` 并使用项目 allow rules。
82
82
 
@@ -67,7 +67,7 @@ Canonical vs legacy residual definitions → **`mstar-artifacts` SKILL.md**("`
67
67
  "execution_lease": {
68
68
  "holder": "omp:demo-session",
69
69
  "claimed_at": "2026-08-30T02:30:00Z",
70
- "worktree_path": "/tmp/worktrees/demo-plan",
70
+ "worktree_path": ".worktrees/demo-plan",
71
71
  "working_branch": "feature/demo-plan"
72
72
  }
73
73
  }
@@ -24,9 +24,9 @@ Deep PR review is a **three-stage pipeline**: collect → domain review → synt
24
24
 
25
25
  **Fan-out discipline**: every collect / domain seat is a **read-only audit seat** (shared contract → `mstar-roles` `references/_shared/leaf-executor-core.md` Audit Mode). PM creates the worktree and resolves the diff basis **first** (§ Worktree isolation), then fans out. Domain-seat Assignments may carry `Delegation: allowed (scout/explore only, read-only)` (reusing the full-audit pattern). **For three-stage seats, never-post is the permanent contract** — posting is Stage 3 only, by the main agent: the main agent (the command's orchestrator) posts the review; review seats never post. Audit Mode, Hard Rule 2, and Mode C are aligned; no seat-level POST carve-out exists.
26
26
 
27
- **Seat prompts** — every seat loads the **seat evidence contract** at `references/pr-review-seat-evidence.md` (return evidence / findings in the result payload — any seat may be **write-blocked**; the main agent writes the evidence files — § Local report archive). Stage 1 collect seats get: the absolute path to `references/pr-review.md` and the sections to read, the review worktree absolute path, recon facts (language / framework / directories / what was skipped), decided tradeoffs, and **Hard Rules 4/5 verbatim** — no findings table, no verdict. Stage 2 domain / security seats additionally load the **findings contract**: `references/finding-format.md`, `references/security-review.md` (security seats), and the instruction to produce findings with **Merge class** (§ Merge class), return them in the result payload (writable seats may **best-effort** write the Stage 2 evidence file directly — the main agent merges — § Local report archive), and return only findings — no fixes; never post.
27
+ **Seat prompts** — every seat loads the **seat evidence contract** at `references/pr-review-seat-evidence.md` (return evidence / findings in the result payload — any seat may be **write-blocked**; the main agent writes the evidence files — § Local report archive). Stage 1 collect seats get: the absolute path to `references/pr-review.md` and the sections to read, the review worktree absolute path, the absolute path to the pinned diff snapshot (when `worktree-setup` produced it — passed as `--diff-file`), recon facts (language / framework / directories / what was skipped), decided tradeoffs, and **Hard Rules 4/5 verbatim** — no findings table, no verdict. Stage 2 domain / security seats additionally load the **findings contract**: `references/finding-format.md`, `references/security-review.md` (security seats), and the instruction to produce findings with **Merge class** (§ Merge class), return them in the result payload (writable seats may **best-effort** write the Stage 2 evidence file directly — the main agent merges — § Local report archive), and return only findings — no fixes; never post.
28
28
 
29
- > **Engine check (when available):** run `mstar pr-review seat-prompt --stage 1|2 --domain <d> --seat <id> --worktree <path> [--security] [--recon <fact> ...]` (or `import { prReviewSeatPrompt } from "@mstar-harness/engine"` in a host hook) to generate the prompt skeleton — Hard Rules 4/5 verbatim, payload-return contract, no-verdict/no-post clauses, slug `<domain>-<seat>`, Merge-class instruction on stage 2. Judgment stays with the PM/agent: domain selection, which tradeoffs are decided, and whether the surface warrants the security lens. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
29
+ > **Engine check (when available):** run `mstar pr-review seat-prompt --stage 1|2 --domain <d> --seat <id> --worktree <path> [--security] [--recon <fact> ...] [--diff-file <path>]` (or `import { prReviewSeatPrompt } from "@mstar-harness/engine"` in a host hook) to generate the prompt skeleton — Hard Rules 4/5 verbatim, payload-return contract, no-verdict/no-post clauses, slug `<domain>-<seat>`, Merge-class instruction on stage 2. Judgment stays with the PM/agent: domain selection, which tradeoffs are decided, and whether the surface warrants the security lens. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
30
30
 
31
31
  ## Review depth (tiers)
32
32
 
@@ -61,7 +61,9 @@ The ladder reuses the existing ~100 / ~300 / ~1000 sizing bands — no second se
61
61
  ## Worktree isolation
62
62
  - All git mechanics — real-base resolution (never assume `main`), collision-free branch naming (`pr-<n>` → `pr-<n>-<date>-<i>` loop before **any** fetch), explicit-refspec fetches (single-branch/narrowed fetch configs stay correct; do **not** substitute `gh pr checkout <n>` — it lands on the PR-head name instead of the recorded branch, bypassing the ownership protocol), worktree creation, changeset pre-flight (untracked-only working-tree changes count as non-empty), diff-basis computation, sidecar recording, removal + prune + exact-branch deletion — execute mechanically:
63
63
 
64
- > **Engine check (when available):** run `mstar pr-review worktree-setup --pr <n> | --branch <b> | --diff | --working-tree | --commit <sha> [--path <dir>]` (or `import { pickReviewBranchName, preflightChangeset } from "@mstar-harness/engine"` in a host hook) to create the isolated review worktree, compute the diff basis inside it, record a sidecar json, and print `{reviewBranch, worktreePath, base, mergeBase, diffCmd}`; clean up with `mstar pr-review worktree-cleanup --path <dir> --branch <name> --report-saved` — removes the tree, prunes, deletes **exactly** the recorded branch (a foreign/unrecorded branch is refused) and refuses removal while the local report is unsaved. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
64
+ > **Engine check (when available):** run `mstar pr-review worktree-setup --pr <n> | --branch <b> | --diff | --working-tree | --commit <sha> [--path <dir>]` (or `import { pickReviewBranchName, preflightChangeset } from "@mstar-harness/engine"` in a host hook) to create the isolated review worktree (default location `<repo>/.worktrees/review-…` per the mstar-branch-worktree convention, override with `--path <dir>`), compute the diff basis inside it, record a sidecar json, and print `{reviewBranch, worktreePath, base, mergeBase, diffCmd, diffFile}` — `diffFile` is the pinned diff snapshot written beside the sidecar at `<parent-of-worktree>/.<wt-dirname>.prreview.diff` (`null` for `--diff` / `--working-tree` modes, which write no snapshot); clean up with `mstar pr-review worktree-cleanup --path <dir> --branch <name> --report-saved` — removes the tree, prunes, deletes **exactly** the recorded branch (a foreign/unrecorded branch is refused), removes the snapshot file, and refuses removal while the local report is unsaved. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
65
+
66
+ The diff snapshot is a review artifact beside the sidecar (`.‹wt-dirname›.prreview.diff` in the worktree's parent dir): setup writes it, cleanup removes it together with the worktree + sidecar, and a failed setup's rollback removes it too — it is never an orphan. Ownership is fd-bound identity: setup records the snapshot's `dev`/`ino`/`mtime` in the sidecar, and cleanup opens the path, verifies the open fd against the recorded identity, and unlinks only after a rename proves the fd's inode is the one it verified — a replaced file (even with identical bytes, or with a reused inode number on ext4) or a sidecar without the recorded identity is left in place with a note; a replacement swapped in mid-cleanup is restored via hard link — never overwriting a concurrent occupant of the path (EEXIST leaves both files in place, nothing deleted). An interrupted setup (sidecar written, snapshot never recorded) is refused by the next `worktree-setup` with a cleanup hint — the operator runs `mstar pr-review worktree-cleanup --path <dir> --branch <name|""> --report-saved` to remove the stale sidecar, then retries. Its range semantics: `## Commits` is the two-dot `base..head` form (commits reachable from head but not base), while `## Files changed` / `## Diff` use the three-dot merge-base pair — the same split the seat reads.
65
67
 
66
68
  Discipline that stays with the agent (behavior, not git mechanics):
67
69
 
@@ -30,7 +30,7 @@ Before the **first** concurrent writable implement dispatch in a round:
30
30
 
31
31
  1. **Re-read repo parallel rules** — root `AGENTS.md` and `{HARNESS_DIR}/AGENTS.md` for branch / worktree / merge-order constraints not duplicated in harness skills.
32
32
  2. **Confirm PM checkout** — PM thread stays on **`spec_integration_branch`** (or the team integration line). **Do not** `checkout` topic / feature branches in the PM **primary cwd** to "help" implementers.
33
- 3. **Create isolation** — for each writable track: `git worktree add <worktree-path> <branch>` (or host-equivalent) **before** Task invoke. Each Assignment **must** include absolute **`Worktree path`**.
33
+ 3. **Create isolation** — for each writable track: `git worktree add .worktrees/<track-slug> <branch>` (or host-equivalent) **before** Task invoke. Each Assignment **must** include absolute **`Worktree path`**.
34
34
  4. **Verify paths exist** — for each track: directory exists; `git -C <path> branch --show-current` matches Assignment **`Working branch`**.
35
35
  5. **Assignment tags** — `Dispatch mode: parallel independent tracks` + `Worktree isolation: required` (`mstar-phase-gates`).
36
36
  6. **Merge order** — when tracks may touch overlapping paths (shared packages, migrations, lockfiles), PM assigns **explicit sequential merge order** before dispatch.
@@ -38,7 +38,7 @@ A Phase 2 session **MUST** claim before moving a plan from `Todo`/`Blocked` to `
38
38
  2. **Resume (not steal):** if `execution_lease` exists and `holder` **equals this session** → verify-held: confirm `worktree_path` and `working_branch` match the Assignment; continue (not Blocked, not a new claim).
39
39
  3. **Blocked:** if `execution_lease` exists and `holder` **differs** → stop. No timestamp, TTL, or inactivity makes it stealable.
40
40
  4. **Orphan:** if `status` is `InProgress` but `execution_lease` is absent → **STOP** (see Orphan recovery). Do not writable-dispatch or invent a lease.
41
- 5. Create or verify the dedicated feature worktree and branch (`worktree_path` ≠ `control_worktree_path`).
41
+ 5. Create or verify the dedicated feature worktree and branch (default `<repoRoot>/.worktrees/<plan-id>-<slug>`; `worktree_path` ≠ `control_worktree_path`).
42
42
  6. Acquire the same-host write lock (above); re-read the coordination file; if row/status/lease changed, restart from step 1.
43
43
  7. In **one complete-file update** (under lock), set `status: "InProgress"` and write the full `execution_lease` object. Use a temp file in the same directory + atomic replace; never expose partial JSON.
44
44
  8. Re-read the stored row; verify `holder`, `worktree_path`, `working_branch` exactly match the attempted claim. Writable dispatch is forbidden until verification succeeds.
@@ -8,17 +8,17 @@ Parallel PM dispatch: read **`parallel-dispatch.md`** when dispatching **N ≥ 2
8
8
 
9
9
  ## omp-only context
10
10
 
11
- - Plugin markers: **`.omp-plugin/plugin.json`** (Morning Star host marker) and **`.claude-plugin/plugin.json`** (Claude-compatible marketplace discovery). Plugin root is the **repo root**; paths stay `./skills/`, `./commands/`, `./agents/`.
12
- - Runtime skills: repo `skills/` discovered after `omp plugin install` / `omp plugin link` (OMP extension-package sub-discovery) or Claude marketplace install.
13
- - Plugin commands: repo `commands/<name>.md` → slash **`/<name>`** (e.g. `/iteration-start`). omp uses the **filename** as the command name (no `morning-star-harness:` prefix).
14
- - Plugin agents: repo **`agents/*.md`** are discovered into the live **`task.agent`** list after install/link + reload. Morning Star **subagent** role ids (`product-manager`, `architect`, `fullstack-dev`, `qc-specialist`, …) are valid `agent` values **when listed** — see C5. `project-manager` is **`mode: primary`** (orchestration seat), not a typical `task` dispatch target.
11
+ - Plugin markers: **`.omp-plugin/plugin.json`** (Morning Star host marker) and **`.claude-plugin/plugin.json`** (Claude-compatible marketplace discovery). The **npm package** (`@mstar-harness/omp`) ships its own package-root `plugin.json` + `skills/` + `commands/` + `agents/` + `hooks/` + `tools/` mirrors; the **maintainer link path** is now `<repo>/packages/omp` (built) — hooks/tools moved into the package (2026-09-03), so linking the repo root provides skills/commands/agents only, with NO runtime gates.
12
+ - Runtime skills: package `skills/` (or repo `skills/` on the link path) discovered after `omp plugin install` / `omp plugin link` (OMP extension-package sub-discovery) or Claude marketplace install.
13
+ - Plugin commands: `commands/<name>.md` → slash **`/<name>`** (e.g. `/iteration-start`). omp uses the **filename** as the command name (no `morning-star-harness:` prefix).
14
+ - Plugin agents: **`agents/*.md`** are discovered into the live **`task.agent`** list after install/link + reload. Morning Star **subagent** role ids (`product-manager`, `architect`, `fullstack-dev`, `qc-specialist`, …) are valid `agent` values **when listed** — see C5. `project-manager` is **`mode: primary`** (orchestration seat), not a typical `task` dispatch target.
15
15
  - **No Kimi-style `sessionStart.skill`** — enter PM manually via **`/skill:pm`** (or the `pm` skill), then **Read next** → `mstar-harness-core` → `project-manager.md`.
16
16
  - Install (user-scoped, recommended):
17
- - `omp plugin install github:btspoony/mstar-harness`
17
+ - `omp plugin install @mstar-harness/omp`
18
18
  - or CLI: `npx @mstar-harness/cli init --target omp --scope global` (links `~/.mstar/harness`)
19
- - Project scope: `omp plugin install github:btspoony/mstar-harness --scope project` or `npx @mstar-harness/cli init --target omp --scope project`.
20
- - Local maintainers: `omp plugin link /path/to/mstar-harness` (or the CLI-managed `~/.mstar/harness` checkout).
21
- - After install/link: `omp plugin list` should show package **`morning-star`** (root `package.json` name). Reload / new session to pick up skills, commands, and agents.
19
+ - Project scope: `omp plugin install @mstar-harness/omp --scope project` or `npx @mstar-harness/cli init --target omp --scope project`.
20
+ - Local maintainers: `omp plugin link /path/to/mstar-harness/packages/omp` (or the CLI-managed `~/.mstar/harness/packages/omp` checkout) — the linked package tree resolves the engine via the workspace member, so run `bun install && bun run engine:build && bun run --cwd packages/omp build` in the checkout first. Linking the repo root no longer provides the runtime gates (hooks/tools moved into the package); the npm install stays the primary path.
21
+ - After install/link: `omp plugin list` should show package **`@mstar-harness/omp`** (npm) or **`morning-star`** (root `package.json` name, link path). Reload / new session to pick up skills, commands, and agents.
22
22
 
23
23
  ## Skill loading
24
24
 
@@ -210,10 +210,10 @@ Cannot emit required **N** → **`Blocked`**.
210
210
 
211
211
  ## In-process engine binding (omp ≥ 17.2.11)
212
212
 
213
- - **Surfaces** (repo root = plugin root): `hooks/pre/mstar-gates.ts` — one `tool_call` pre-hook that returns `{ block: true, reason }` (structured refusal the model sees as the tool error) or `undefined` (pass); `tools/mstar_{status_validate,dispatch_validate,lease_verify,path_resolve,iteration_gate,worktree_check}/index.ts` — six model-callable validator tools (engine validators only, Zod params via `pi.zod`).
213
+ - **Surfaces** (npm package root = plugin root; sources live in `packages/omp/src/`): `hooks/pre/mstar-gates.js` — one `tool_call` pre-hook that returns `{ block: true, reason }` (structured refusal the model sees as the tool error) or `undefined` (pass); `tools/mstar_{status_validate,dispatch_validate,lease_verify,path_resolve,iteration_gate,worktree_check}.js` — six model-callable validator tools (engine validators only, Zod params via `pi.zod`). omp discovers these by convention from the installed package root (`<pkg>/hooks/pre/` any file, `<pkg>/tools/` direct `*.js` files — the sub-directory scan only accepts `tools/<name>/index.ts`), not from `dist/`.
214
214
  |- **Enforcement semantics**: block ONLY under `Enforcement: hard`. Both gates read the repo `.mstarc` `[config] enforcement`, else the harness compass frontmatter (`enforcement: hard`, active/locked iterations only); the dispatch gate ALSO honors each Assignment's own header flag (`assignmentHeaderRegion` — a body example never hardens). A hard repo setting therefore hardens flag-less dispatches (Gate 1 / dsh `resolveDispatchHard` parity). Soft-mode dispatch violations are warn-logged through the extension logger (never blocked); soft status-write violations stay a silent pass. Rollback = unset the flag (or `.mstarc` `soft`). Never global.
215
215
  - **Anti-recursion scope (issue #156)**: the engine's `antiRecursionPrecheck` is **caller-scoped** — it compares the DISPATCHING agent's own role against the new Assignment's `Execute as`. omp's `tool_call` event carries no caller identity and the task entry `agent` is the spawn TARGET, which equals `Execute as` on every compliant dispatch (C5 above) — so Gate 2 does NOT run the precheck on omp (the pre-#156 wiring hard-blocked every compliant hard-mode dispatch on `self-type`, or on `empty-binding` when `agent` was omitted). The NEVER red line stays prompt-level on this host (`mstar-dispatch-gates`); dsh enforces it in-engine via Config `dispatchBinding`.
216
- - **Engine dependency**: the adapters import the published engine package (root `package.json` `dependencies` entry). omp git/npm plugin installs run `bun install <spec>` in the plugins tree declared deps installed; a bare `-l` / `omp plugin link` symlink install without `node_modules` cannot resolve the modules.
216
+ - **Engine dependency**: the npm package **bundles the engine inline** into every hook/tool bundle at build time — zero runtime package resolution, so module link can never fail on a missing package (the 2026-09-03 hotfix for the bare-import load failure). The maintainer `omp plugin link` path (now `<repo>/packages/omp`) still resolves the engine via the workspace member — run `bun install && bun run engine:build && bun run --cwd packages/omp build` in the checkout first (the member's `dist/` and the package's generated mirrors are gitignored).
217
217
  - **Graceful degradation (explicit)**: module load failure → `mstar_*` tools skipped, hook absent (no blocking), `commands/*.md` shell-out fallback intact. Caveat: a partial failure is SILENT — no in-band signal that gates are off; verify with `omp -p '/extensions'`.
218
218
  |- **`MSTAR_HARNESS_DIR` override / `.mstarc`**: the hook and tools discover `{HARNESS_DIR}` via `resolveHarnessDir` — a repo `.mstarc` `[config] harness_dir` (gitignored local config) first, then the probe `.mstar/` → `.agents/` → `.plans/`/`plans/`. Repos using a non-standard harness root can declare it in `.mstarc` or MUST export `MSTAR_HARNESS_DIR` (absolute path) in the omp session env — without either the status gate does not cover those roots and tools like `mstar_path_resolve` / `mstar_lease_verify` error out (parity with the opencode binding).
219
219
  - **Edit-path limitation**: the status gate validates the on-disk file for `edit` events (pre-edit state) — a corrupting edit is caught by the next write or `mstar_status_validate` (known v1 limitation, parity with opencode).
@@ -229,12 +229,12 @@ Cannot emit required **N** → **`Blocked`**.
229
229
  ## Git and final evidence
230
230
 
231
231
  - Git work follows `mstar-branch-worktree` and Assignment **Working branch** / **Branch policy**.
232
- - omp may offer task isolation / worktrees (`task.isolation`, `~/.omp/wt`) — still record Morning Star **Worktree path** / leases when L1 gates apply.
232
+ - omp may offer task isolation / worktrees (`task.isolation`, `~/.omp/wt`) — that is **host-level** task isolation **outside** the Morning Star convention; Morning Star **`Worktree path`** stays `<repoRoot>/.worktrees/` (record it + leases when L1 gates apply).
233
233
  - Completion reports cite concrete commands, artifacts, and commit lines when required.
234
234
 
235
235
  ## Gotchas
236
236
 
237
- - Installed npm/git plugin package name is root **`morning-star`** (`package.json`); Morning Star display name remains **morning-star-harness**.
237
+ - Installed npm plugin package name is **`@mstar-harness/omp`** (git/link path: root **`morning-star`**); Morning Star display name remains **morning-star-harness**.
238
238
  - Marketplace (Claude) installs and `omp plugin install` are different discovery providers — prefer one install path per machine to avoid duplicate skill listings.
239
239
  - Session plan UI / todos are not durable SSOT unless mirrored to `{HARNESS_DIR}`.
240
240
  - After install/link, **reload / new session** so `agents/*.md` appear in the live `task.agent` list — stale sessions may only show host generics and wrongly push you to `agent: "task"`.
@@ -298,7 +298,7 @@ SSOT = `{WORKFLOW_DIR}/<id>/snapshot.json` + `{PLAN_DIR}/`。todos 只追踪本
298
298
  - 若 `execution_lease` 存在且 `holder` **不同** → **Blocked**
299
299
  - 若 `status: InProgress` 但 **无** `execution_lease` → **STOP** 升级(孤儿状态恢复 → **`mstar-artifacts`**;本 skill 不自行补 lease)
300
300
  - 否则按 **`references/phase-2-worktree-lease.md`** claim:`Todo`/`Blocked` → `InProgress` + 写入完整 `execution_lease`;verify 通过前 **禁止**可写派发
301
- 2. **Plan start — feature worktree + branch**:创建/校验 dedicated feature worktreeAssignment 须含绝对 `Worktree path` + `Working branch`(与 lease 一致)。plan 内多可写并行轨 → **`mstar-branch-worktree`** **`references/parallel-writable-pre-dispatch.md`**
301
+ 2. **Plan start — feature worktree + branch**:创建/校验 dedicated feature worktree(默认 `<repoRoot>/.worktrees/<plan-id>-<slug>`);Assignment 须含绝对 `Worktree path` + `Working branch`(与 lease 一致)。plan 内多可写并行轨 → **`mstar-branch-worktree`** **`references/parallel-writable-pre-dispatch.md`**
302
302
  3. **Implement → InReview**(`§ 2.5`;产品编辑在 feature worktree;plans / snapshot / iterations / SDD 经 control 绝对路径):
303
303
  - **默认 `Execution mode: sdd`**(多 task plan;hotfix 可 `inline`)。
304
304
  - PM 载入 **`mstar-sdd`** 后,按 plan task 顺序 **串行** per-task 循环(**不是**一次派发 dev 做全部 tasks):
@@ -111,7 +111,7 @@ Lives on the snapshot plan row — `{WORKFLOW_DIR}/<id>/snapshot.json` → `plan
111
111
  - **Same `holder` as this session** → **resume**: verify `worktree_path` and
112
112
  `working_branch` match the Assignment; continue (not steal/block).
113
113
  - **Different `holder`** → **Blocked** (no timestamp makes it stealable).
114
- 3. Create or verify dedicated feature worktree + branch.
114
+ 3. Create or verify dedicated feature worktree + branch (default `<repoRoot>/.worktrees/<plan-id>-<slug>`).
115
115
  4. Re-read the snapshot under write lock; if row/status/lease changed, restart claim.
116
116
  5. One complete-file update (still under lock): `status: "InProgress"` + full `execution_lease`.
117
117
  Use temp file + atomic replace; never expose partial JSON.
@@ -96,7 +96,7 @@ The **`**You are a leaf executor. You MUST NOT:**`** section (previously just pr
96
96
  **Review cwd / Worktree path**: <absolute path or N/A>
97
97
  **plan_id**: <plan-id or N/A + scope label>
98
98
  **Review range / Diff basis**: <reproducible basis; merge-base = `metadata.target_branch` or PM-specified ref — not assumed `origin/main`>
99
- **Worktree path**: <absolute feature implementer path when L1/L2 isolation used; must ≠ control_worktree_path>
99
+ **Worktree path**: <absolute feature implementer path when L1/L2 isolation used; default `<repoRoot>/.worktrees/<plan-id>-<slug>` (L2 tracks: `<track-slug>`); must ≠ control_worktree_path>
100
100
  **QA gate**: mandatory | pm-acceptance | report-only — see `references/project-manager/qa-trigger-matrix.md`
101
101
  **QA gate reason**: <tier label, e.g. hotfix-inline | small-feature-clean-qc | mandatory-medium-feature>
102
102
  **QA mode**: acceptance-only | full | report-only | N/A — required when `QA gate: mandatory` or `report-only`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstar-harness/dsh",
3
- "version": "3.6.0-alpha.3",
3
+ "version": "3.6.0",
4
4
  "description": "Morning Star harness dsh (DeepSeek Harness) cordis function plugin — in-process engine gates (status/dispatch/lease) with hard refusal channels.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -65,21 +65,32 @@
65
65
  },
66
66
  "peerDependencies": {
67
67
  "@deepseek-ai/cordis": "^4.0.2",
68
- "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
69
- "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
70
- "@deepseek-ai/dsh-client-store": "^0.1.2-alpha.2",
71
- "@deepseek-ai/dsh-client-ui-chat": "^0.1.2-alpha.2",
72
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
75
- "@deepseek-ai/dsh-commands": "^0.1.2-alpha.2",
76
- "@deepseek-ai/dsh-fs": "^0.1.2-alpha.2",
77
- "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
78
- "@deepseek-ai/dsh-jobs": "^0.1.2-alpha.2",
79
- "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
80
- "@deepseek-ai/dsh-skill": "^0.1.2-alpha.2",
81
- "@deepseek-ai/dsh-skill-filesystem": "^0.1.2-alpha.2",
82
- "@deepseek-ai/dsh-tools": "^0.1.2-alpha.2"
68
+ "@deepseek-ai/dsh-agent": "^0.1.2-rc.1",
69
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
70
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
71
+ "@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
72
+ "@deepseek-ai/dsh-client-ui-chat": "^0.1.2-rc.1",
73
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-rc.1",
74
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
75
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
76
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
77
+ "@deepseek-ai/dsh-commands": "^0.1.2-rc.1",
78
+ "@deepseek-ai/dsh-fs": "^0.1.2-rc.1",
79
+ "@deepseek-ai/dsh-invariants": "^0.1.2-rc.1",
80
+ "@deepseek-ai/dsh-jobs": "^0.1.2-rc.1",
81
+ "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
82
+ "@deepseek-ai/dsh-scope": "^0.1.2-rc.1",
83
+ "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
84
+ "@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
85
+ "@deepseek-ai/dsh-skill": "^0.1.2-rc.1",
86
+ "@deepseek-ai/dsh-skill-filesystem": "^0.1.2-rc.1",
87
+ "@deepseek-ai/dsh-subagent": "^0.1.2-rc.1",
88
+ "@deepseek-ai/dsh-system-prompt": "^0.1.2-rc.1",
89
+ "@deepseek-ai/dsh-tools": "^0.1.2-rc.1",
90
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.2-rc.1",
91
+ "@deepseek-ai/dsh-util-time": "^0.1.2-rc.1",
92
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.2-rc.1",
93
+ "@deepseek-ai/schemastery": "^3.18.1"
83
94
  },
84
95
  "publishConfig": {
85
96
  "access": "public"
@@ -90,7 +101,7 @@
90
101
  "@types/react": "~18.3.1",
91
102
  "js-yaml": "^4.1.0",
92
103
  "bun-types": "^1.2.17",
93
- "dsh-llm-fallbacks": "^0.4.0-alpha.1",
104
+ "dsh-llm-fallbacks": "0.4.1",
94
105
  "schemastery": "^3.18.0",
95
106
  "typescript": "^5.9.3",
96
107
  "vitest": "^4.1.8",