@mstar-harness/dsh 3.9.1 → 3.9.3

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/dist/index.js CHANGED
@@ -1401,12 +1401,18 @@ var REQUIRED_FIELDS = [
1401
1401
  { key: "delegation", label: "Delegation", code: "delegation" },
1402
1402
  { key: "taskCategory", label: "Task category", code: "task-category" }
1403
1403
  ];
1404
+ var REVIEW_SEAT_ROLES = ["qc-specialist", "qc-specialist-2", "qc-specialist-3", "code-reviewer", "qa-engineer"];
1405
+ var BUDGET_LABELS = ["Budget (review / QC seats)", "Budget"];
1406
+ var RETURN_SHAPE_LABELS = ["Return shape (review / QC seats)", "Return shape"];
1404
1407
  function violation2(severity, code, message, fix) {
1405
1408
  return { ok: false, severity, code, message, fix };
1406
1409
  }
1410
+ function describeAbsence(value) {
1411
+ return value === undefined ? "the field is absent" : value === "" ? "the field is empty" : value.trim().toLowerCase() === "n/a" ? 'the value is "N/A"' : undefined;
1412
+ }
1407
1413
  function parseAssignmentFields(assignmentText) {
1408
1414
  const fields = {};
1409
- for (const line of assignmentText.split(/\r?\n/)) {
1415
+ for (const line of assignmentHeaderRegion(assignmentText).split(/\r?\n/)) {
1410
1416
  const match = line.match(/^[ \t]*(?:[-*][ \t]+)?\*\*\s*([^*:]+?)\s*\*\*\s*:\s*(.*)$/) ?? line.match(/^[ \t]*(?:[-*][ \t]+)?([A-Za-z][A-Za-z -]*?)\s*:\s*(.*)$/);
1411
1417
  if (!match)
1412
1418
  continue;
@@ -1421,6 +1427,10 @@ function parseAssignmentFields(assignmentText) {
1421
1427
  fields.workingBranch = value;
1422
1428
  else if (label === "Branch policy")
1423
1429
  fields.branchPolicy = value;
1430
+ else if (BUDGET_LABELS.includes(label))
1431
+ fields.budget = value;
1432
+ else if (RETURN_SHAPE_LABELS.includes(label))
1433
+ fields.returnShape = value;
1424
1434
  }
1425
1435
  return fields;
1426
1436
  }
@@ -1508,6 +1518,33 @@ function validateAssignmentFields(assignmentText, opts = {}) {
1508
1518
  for (const { key, label, code } of REQUIRED_FIELDS) {
1509
1519
  requireField(violations, fields[key], label, code);
1510
1520
  }
1521
+ const role = (fields.executeAs ?? "").trim().replace(/^@/, "").toLowerCase().split(/\s+/)[0] ?? "";
1522
+ const reviewSeat = REVIEW_SEAT_ROLES.includes(role);
1523
+ const category = (fields.taskCategory ?? "").replace(/^[*_`"'\s]+/, "").toLowerCase();
1524
+ const auditRound = /^audit(?![A-Za-z0-9])/.test(category);
1525
+ if (reviewSeat || auditRound) {
1526
+ const subject = reviewSeat ? `review seat "${role}"` : `audit round (Task category: ${category})`;
1527
+ const boundingFields = [
1528
+ {
1529
+ code: "assignment.field.budget-missing",
1530
+ label: "Budget",
1531
+ fix: `add "**Budget (review / QC seats)**: <cap> — may only tighten the default in mstar-harness-core § 定向执行与验证边界, never loosen it"`,
1532
+ value: fields.budget
1533
+ },
1534
+ {
1535
+ code: "assignment.field.return-shape-missing",
1536
+ label: "Return shape",
1537
+ fix: `add "**Return shape (review / QC seats)**: <what the seat returns and how it stops — verdict + findings shape; a clean round returns findings: [] explicitly>"`,
1538
+ value: fields.returnShape
1539
+ }
1540
+ ];
1541
+ for (const field of boundingFields) {
1542
+ const missing = describeAbsence(field.value);
1543
+ if (missing === undefined)
1544
+ continue;
1545
+ violations.push(violation2("high", field.code, `${subject} must declare a round ${field.label} — ${missing}`, field.fix));
1546
+ }
1547
+ }
1511
1548
  if (writable) {
1512
1549
  const workingPresent = fields.workingBranch !== undefined && fields.workingBranch !== "";
1513
1550
  const policyPresent = fields.branchPolicy !== undefined && fields.branchPolicy !== "";
@@ -2454,7 +2491,9 @@ function findingsCleanupGate(register, planId, opts) {
2454
2491
  const id = typeof entry.id === "string" ? entry.id : "<unnamed>";
2455
2492
  const label = `R#${id}`;
2456
2493
  if (mode === "zero-residual") {
2457
- if (entry.severity === "nit") {
2494
+ if (normalizeSeverity(entry.severity) === "critical") {
2495
+ violations.push(violation6("high", "findings.zero-residual-critical", `${label}: unresolved critical blocks approval under zero-residual — fix now or close via explicit risk acceptance`));
2496
+ } else if (entry.severity === "nit") {
2458
2497
  violations.push(violation6("medium", "findings.zero-residual-nit", `${label}: style-only nits must be fixed in-session or dropped — never left open under zero-residual`));
2459
2498
  } else if (entry.decision === "risk-accepted" || entry.lifecycle === "waived") {
2460
2499
  violations.push(violation6("medium", "findings.zero-residual-risk-accepted", `${label}: waived/risk-accepted findings must be closed/archived, not left open under zero-residual`));
@@ -4163,6 +4202,8 @@ function findEphemeralCitations(skillText) {
4163
4202
  }
4164
4203
  return citations;
4165
4204
  }
4205
+ var DATED_SLUG_TOKEN_SOURCE = "\\b20\\d{6}-[a-z0-9][a-z0-9-]*\\b(?!\\.\\d)";
4206
+ var DATED_SLUG_TOKEN_RE = new RegExp(DATED_SLUG_TOKEN_SOURCE, "g");
4166
4207
  var WORKFLOW_VERB_START_RE = /^(?:explains?|describes?|covers?|provides?|walks?|guides?|shows?|lists?|details?|demonstrates?|outlines?|teaches?|summarizes?)\b/i;
4167
4208
  var PRONOUN_RE = /\bI\b(?!\/)|\b(?:we|you|my|our|your|us)\b/gi;
4168
4209
  var DESCRIPTION_MAX_WORDS = 120;
@@ -21,7 +21,7 @@ Before a plan is locked, verify every item:
21
21
 
22
22
  ### 2. Verification gates
23
23
 
24
- Each verification step names the changed behavior, exact scoped command and expected result, or reusable evidence with its applicability. Use only checks needed for this change; discovering a repository command does not make it a gate. Scope authority → `mstar-harness-core` § 定向执行与验证边界.
24
+ Each verification step names the changed behavior, exact scoped command and expected result, or reusable evidence with its applicability. Use only checks needed for this change; discovering a repository command does not make it a gate. Scope authority → `mstar-harness-core` § 定向执行与验证边界. Verification gates stay inside the change's own layer: a development plan's task never gates on real-browser, device, or installed-deployment E2E — that verification lives only in a separately requested `mstar-e2e` workflow, whose own scenario rows are its legitimate tasks.
25
25
 
26
26
  | Pattern | Weak (do not use) | Strong (scope first) |
27
27
  |---------|-------------------|----------------------|
@@ -186,8 +186,8 @@ Only these five, **lowercase English**:
186
186
 
187
187
  | `severity` | Meaning |
188
188
  | ---------- | ------- |
189
- | `critical` | Merge-blocking; maps to QC **Critical** findings. |
190
- | `high` | Not blocking but high impact (security, correctness, data, significant tech debt); fix, escalate, or open residual with PM follow-up. |
189
+ | `critical` | **Unsafe to ship, reachable on this merge** — correctness bug, security hole, data loss, or broken public contract whose unsafe outcome can be triggered here; merge-blocking. Maps to QC **Critical** findings. |
190
+ | `high` | Not blocking — the same unsafe-to-ship classes whose unsafe outcome is **not reachable on this merge** (narrow reach, unreachable path, or already mitigated), **or significant tech debt**; fix, escalate, or open a residual with PM follow-up. |
191
191
  | `medium` | Should address this or next milestone; may be open residual. |
192
192
  | `low` | Small impact, cheap fix; may be open residual. |
193
193
  | `nit` | Style, naming, wording, non-behavior doc nits; **lighter than `low`**. PM may omit from the register if no tracking needed. |
@@ -196,17 +196,33 @@ Summary vs `mstar-review-qc`: unresolved **`critical`** → usually `Request Cha
196
196
 
197
197
  ### 4. QC report section → JSON `severity`
198
198
 
199
+ Grade by **what would happen if the finding is true**, never by how uncertain you are. Whether a finding blocks turns on whether its unsafe outcome is **reachable on this merge** — the axis defined in §3 — and not on the report section (Critical / Warning / Suggestion) it was filed under; the filing is a routing hint, not a severity decision. Two classes reach `high` or above: (a) **unsafe to ship** — correctness, security, data loss, broken public contract → `critical` / `high` even at low confidence; (b) **significant tech debt** → `high`. Everything else stays below: documentation accuracy, citations/line numbers, naming, wording, and test polish are `low` / `nit` — including inside a normative document — **unless the defect would itself drive an unsafe outcome** (a normative instruction that leads an executor into a correctness, security, or data failure), in which case it grades by that consequence. Evidence confidence belongs in the report (`Confidence`), not encoded by inflating `severity`. When the uncertainty is about **scope** (reachability) rather than severity class, record the worst-case class among the plausible ones and state the open question in the entry's `scope`.
200
+
199
201
  When registering into the project register (template in `mstar-review-qc`):
200
202
 
201
203
  | Report Findings section | JSON `severity` |
202
204
  | ----------------------- | --------------- |
203
- | **Critical** | Default `critical`. PM may record `high` if “not blocking this merge but follow up soon” — state reason in `title`/`scope`. |
204
- | **Warning** | `high` or `medium`: security/correctness/data → `high`; other substantive non-blocking → `medium`; **when unsure, use `high`**. |
205
+ | **Critical** | Default `critical`. PM may record `high` only when the §3 axis puts the unsafe outcome outside reachability on this merge, with the reasoning stated in `title`/`scope`. |
206
+ | **Warning** | `medium` for ordinary substantive non-blocking items. A security/correctness/data finding follows the same §3 reachability axis as the **Critical** row: `high` when the unsafe outcome is not reachable on this merge, `critical` when it is — note the Warning filing in `title`/`scope`. |
205
207
  | **Suggestion** | `low` or `nit`: substantive improvement → `low`; pure style/optional → `nit`. |
206
208
 
207
209
  **Common mistake:** report **Warning** is not a valid `severity` string; there is no `warning` in the enum (see legacy below).
208
210
 
209
- ### 5. Legacy `"severity": "warning"`
211
+ ### 5. Cross-chain vocabulary (one axis, four labels)
212
+
213
+ The blocking judgement is decided **once**, on the §3 axis. Each chain's label set is a different projection of that one decision — map by **axis band**, never by label shape:
214
+
215
+ | Blocking judgement (§3 axis) | register `severity` | audit Merge class | plan-QC report section | L2 task review |
216
+ | ---------------------------- | ------------------- | ----------------- | ---------------------- | -------------- |
217
+ | **Blocking** — unsafe outcome reachable on this change/merge | `critical` | `must-fix` | **Critical** | `Critical` |
218
+ | High impact, non-blocking — unsafe but not reachable here, or significant tech debt | `high` | `should-fix` | **Warning** | `Important` |
219
+ | Substantive, non-blocking — below the above | `medium` | `should-fix` | **Warning** | `Important` |
220
+ | Small and cheap | `low` | `nit` | **Suggestion** | `Minor` |
221
+ | Style / naming / wording | `nit` | `nit` | **Suggestion** | `Minor` |
222
+
223
+ **A cross-chain translation never changes the judgement** — a label is a projection of the axis, so moving a finding between chains must not promote or demote it.
224
+
225
+ ### 6. Legacy `"severity": "warning"`
210
226
 
211
227
  In old JSON, **`"severity": "warning"`** is read and rolled up as **`low`**. **Forbidden** on new entries.
212
228
 
@@ -238,14 +254,14 @@ Intent: clear findings in the current plan session whenever possible. Open resid
238
254
  1. After QC: default path is **fix-now + targeted re-review**, not `Approve with residuals`.
239
255
  2. Do **not** register open R# for items that can be fixed in this session.
240
256
  3. **`nit`**: fix in-session **or** drop with no R# (existing “no tracking needed”); **never** open residual for style-only nits.
241
- 4. **`Approve with residuals`** only when every remaining open item is a true blocker-defer (`decision: defer`, `target` = next iteration/milestone, Durable Roadmap Gate written).
257
+ 4. **`Approve with residuals`** only when every remaining open item is a true blocker-defer (`decision: defer`, `target` = next iteration/milestone, Durable Roadmap Gate written) — **except `critical`** (unsafe outcome reachable on this merge, §3): a `critical` is fixed now, or the risk is explicitly accepted and the entry is **closed** per item 6, never left open as the approval's remaining item.
242
258
  5. **True defer** only: external dependency; product/scope decision for a later iteration; or explicit **current-turn** user defer — plus Durable Roadmap Gate.
243
259
  6. **`waived` / `risk-accepted`**: still require PM + user/architect alignment; **close in the register** (do not leave open). Prefer a cheap fix over waive-as-shortcut.
244
- 7. Plan **Done**: prefer an empty `entries[<plan_id>]` in the register. If any open entries remain, **every** one must be blocker-defer + roadmap; otherwise keep `InReview` / `Blocked`.
260
+ 7. Plan **Done**: prefer an empty `entries[<plan_id>]` in the register. If any open entries remain, **every** one must be blocker-defer + roadmap and none may be `critical` (item 4); otherwise keep `InReview` / `Blocked`.
245
261
 
246
262
  ### `allow-residual` (legacy default)
247
263
 
248
- Non-blocking Warning/Suggestion may ship with open register entries and `Approve with residuals` when no unresolved Critical remains (existing residual lifecycle unchanged).
264
+ Non-blocking register entries — `severity` below `critical` on the §3 axis — may ship with open entries and `Approve with residuals` when no unresolved `critical` remains (existing residual lifecycle unchanged).
249
265
 
250
266
  > **Engine check (when available):** run `mstar status findings-cleanup <plan-id> [--project <id>] [--mode zero-residual|allow-residual]` (or import `findingsCleanupGate` from `@mstar-harness/engine` in a host hook) to enforce the mode above against the plan's register entries. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
251
267
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  ## Global Constraints
16
16
 
17
- [Project requirements — version floors, naming, exact values — copied verbatim from spec. Every task includes them. Verification scope follows `mstar-harness-core` § 定向执行与验证边界: only changed behavior and direct contracts; no local full suites without explicit user permission.]
17
+ [Project requirements — version floors, naming, exact values — copied verbatim from spec. Every task includes them. Verification scope follows `mstar-harness-core` § 定向执行与验证边界: only changed behavior and direct contracts; no local full suites without explicit user permission. Never assign real-browser/device/installed-deployment E2E evidence as a task or a gate of a development plan; each layer proves itself with its own unit/integration tests. Real-environment verification lives only in a separately requested `mstar-e2e` workflow, whose named scenarios are that workflow's own plan rows.]
18
18
 
19
19
  ---
20
20
 
@@ -187,11 +187,13 @@ Classify each **accepted** finding (after vet) as exactly one class. Do not inve
187
187
 
188
188
  | Class | Use when | Verdict effect |
189
189
  | --- | --- | --- |
190
- | `must-fix` | Shipping this issue is unsafe: correctness bug, security hole, data loss, auth/authz bypass, or a broken public contract. Same meaning as today's `blocked` gloss ("a must-fix issue stands in the way of shipping"). | Any count ≥ 1 → `blocked` |
191
- | `should-fix` | A real issue that should be addressed before merge but is not itself a ship-stopper. Same meaning as today's middle gloss ("issues found; address before merge"). | Else if count ≥ 1 → `needs fixes` |
190
+ | `must-fix` | Shipping this issue is unsafe **and** the unsafe outcome is reachable in the reviewed change: correctness bug, security hole, data loss, auth/authz bypass, or a broken public contract. This is the same class the register records as `critical` (class pointer below). Same meaning as today's `blocked` gloss ("a must-fix issue stands in the way of shipping"). | Any count ≥ 1 → `blocked` |
191
+ | `should-fix` | A real issue that should be addressed before merge but is not itself a ship-stopper: unsafe but **not** reachable in this change, significant tech debt, or otherwise substantive non-blocking — the register's `high` / `medium` bands. Same meaning as today's middle gloss ("issues found; address before merge"). | Else if count ≥ 1 → `needs fixes` |
192
192
  | `nit` | Optional cleanup, naming, comment, or small suggestion that does **not** change merge-readiness. Lint-covered cosmetics stay ignored (existing lens rule) — they are not findings. | Does not change verdict |
193
193
 
194
- Tie-break: unsafe to ship → `must-fix`; should be addressed before merge but ship-safe → `should-fix`; otherwise `nit`. A LOW-confidence smell that fails evidence rules is **not** a finding (existing disqualify rules) — put it on `- unverified:` if it must be mentioned.
194
+ **Class ↔ register:** these three classes are this chain's projection of the one blocking judgement — the register `severity` value, plan-QC report section, and L2 task-review label sitting at each band are tabulated in `mstar-artifacts` `references/status-and-residuals.md` § Residual findings: `severity` → §5 Cross-chain vocabulary. Translate by band; never re-grade on translation.
195
+
196
+ Tie-break: unsafe to ship **and reachable in this change** → `must-fix`; should be addressed before merge but ship-safe → `should-fix`; otherwise `nit`. A LOW-confidence smell that fails evidence rules is **not** a finding (existing disqualify rules) — put it on `- unverified:` if it must be mentioned.
195
197
 
196
198
  Presumptive-structural classes: a refactor that relocates complexity instead of reducing it · a change pushing a file past the size boundary with no decomposition · feature logic added to a shared module · a near-duplicate of an existing canonical helper · a silent fallback hiding an unclear invariant → default `should-fix`; downgrade to `nit` only with a stated reason; never `must-fix` on shape alone without correctness/security evidence.
197
199
 
@@ -16,7 +16,7 @@ This is an explicitly requested verification workflow, separate from development
16
16
  ## Workflow
17
17
 
18
18
  1. **PM scopes the request.** Record the existing user authorization, build/ref, environment/device, named scenarios and expected results, permitted side effects, capability, and report path. Ask only for missing required inputs; never infer production, accounts, or devices. Reuse relevant knowledge without a new global scan.
19
- 2. **PM registers independent work.** Use existing workflow `type: plan`, its own workflow/plan IDs and working context. Snapshot states are `running | paused | completed | failed | stopped`; plan rows use `Todo → InProgress → InReview → Done/Blocked`. Do not insert an iteration phase, ordinary QA gate, or automatic QC tri-review into a verification-only run.
19
+ 2. **PM registers independent work.** Use existing workflow `type: plan`, its own workflow/plan IDs and working context. Snapshot states are `running | paused | completed | failed | stopped`; plan rows use `Todo → InProgress → InReview → Done/Blocked`. Do not insert an iteration phase, ordinary QA gate, or automatic QC tri-review into a verification-only run. The scenario rows registered here are the legitimate exception to the "never a development plan's task" boundary in `mstar-harness-core` § 定向执行与验证边界 — that boundary governs development plans, not this verification-only workflow.
20
20
  3. **PM dispatches ops.** Use `Execute as: ops-engineer`, `Task category: ops`, `Delegation: forbidden`, and the existing Scope / Inputs / Constraints / Evidence Required / Acceptance Criteria fields. Pass the concrete report path under `{WORKFLOW_DIR}/<workflow-id>/reports/e2e.md`. Ops executes only the named scenarios and records actual results using `references/report-template.md`.
21
21
  4. **Run independent scenarios concurrently** when sessions, devices, data, and writable state are isolated. Serialize shared state. Stop when the assigned scenarios finish; new environments or broader suites need matching user authorization.
22
22
  5. **PM reviews the scoped report and closes.** `InReview` means report acceptance against the scenario list, not another broad code review. Ops returns evidence and cannot mark Done. PM owns the final plan/workflow state and any bounded repair handoff; preserve the originating iteration's state and unit-test evidence.
@@ -137,9 +137,10 @@ Read **`mstar-host`** after this skill; detect host per its table, then Read the
137
137
 
138
138
  - **本地全量测试默认禁止,完整套件交 CI。** 只有用户明确许可才能例外;Assignment 的 `Constraints` 引用许可,`Evidence Required` 写明命令、范围、环境与次数。PM 字段、风险等级、缺证据、fix wave 和早期探索都不产生许可;不得拆成多个无关“小测试”绕过全量边界。
139
139
  - **全域只读调查限早期探索。** 实现、fix、QC、QA 只查本次变更、直接影响接口及相关 knowledge;不重新全仓扫描、测试或审查。通过知识索引只选相关 Active 条目;缺口超出范围时报告具体所缺信息,不自行扩展任务。
140
+ - **只读审查席位有界。** review / QC / L2 task review 的范围是 Assignment 的 diff pack 加直接影响接口;只在 must-fix 线索上跟进出界。默认 **≤ 12 次文件打开或 ≤ 10 分钟**(PM 按 Assignment `Budget` 收紧,不得放宽);席位还必须写明 `Return shape`(返回什么、如何在预算内停下),干净轮次显式返回 `findings: []` 而非散文。`Task category: audit` 的轮次同受这两项约束,即使 `Execute as` 不在 QC 席位集内(`audit` 类请求可落在 `@code-reviewer` 之外的执行者上)。触达即停止扩展:返回当前 verdict 与已得 findings,并在报告 `## Scope` 声明 `Truncated coverage:`。**截断 ≠ `Unconfirmed`**——后者仍是证据通道失败态并阻断 `Approve`;未覆盖范围按既有「未提及 = 未审查」由 PM 汇总,且部分覆盖的运行不可作为批准——门禁语义 → `mstar-review-qc`。
140
141
  - **验证按变更映射。** 可执行逻辑使用对应单测;非可执行文档与 prompt/skill 策略使用真实定向静态或 before/after 证据,不制造测试文件。SDD 的 `Verification mode: scoped-check` 格式与适用性 → `mstar-sdd/references/file-handoffs.md`。报告结构校验不证明命令执行或 diff 适用性,也不是任意 shell 拦截器。
141
142
  - **只使受影响证据失效。** HEAD 或 Review range 改变不等于全部重跑;复用仍有效的 L1/CI/先前 QA 证据,记明原范围及仍适用的理由。fix 只验证相关回归;QC 复审只看归属 finding、fix delta 与直接接口。`full tri-review` 表示席位数量,不授权全仓 review;QC 不运行 test/build/install。
142
- - **QA 仅定向单元测试与验收证据映射。** 模式仅 `acceptance-only` / `targeted` / `report-only`。用户许可的本地全量由实现 owner 或 ops 另接明确行动,QA 只消费证据。真实浏览器、真机、安装/部署 E2E 仅由用户显式启动独立 `mstar-e2e` workflow,PM 编排、ops 执行;不作为迭代 QA gate。未验证的真实环境行为如实记录,不伪称通过。
143
+ - **QA 仅定向单元测试与验收证据映射。** 模式仅 `acceptance-only` / `targeted` / `report-only`。用户许可的本地全量由实现 owner 或 ops 另接明确行动,QA 只消费证据。真实浏览器、真机、安装/部署 E2E 仅由用户显式启动独立 `mstar-e2e` workflow,PM 编排、ops 执行;**不作为迭代 QA gate,也不作为开发 plan 的 task 或任何 gate 的证据义务**——各层以自身单测/集成测试自证;真实环境验证只在该独立 workflow 内发生,其命名场景即该 workflow 的 plan rows。未验证的真实环境行为如实记录,不伪称通过。
143
144
  - **依赖允许即并行。** PM 对无依赖、写所有权及 worktree 隔离的 ready tasks 并行派发;共享写目标、同一 session/ledger、前置接口与 integration merge 才按具体约束串行。leaf 不因并行策略获得派发权限。
144
145
  - **完成即交付。** Assignment 给出任务、输入、所有权、允许检查与可观察结果;执行者只解答这些问题,不重复分析已解决内容、不顺手修复或增加“保险”检查。真实范围缺口返回 PM,已有证据充分即停止。
145
146
 
@@ -26,7 +26,7 @@ starts at **Phase 2 entry**.
26
26
 
27
27
  **本 Phase 定义 per-plan 派发循环的完整流程**:前置条件检查、session todos、backlog 读取、integration 分支管理、per-plan dispatch 循环(分支→实现→QC→**QA gate**→Done→合并)、dispatch-first 约束。PM 读取本 Phase(含 §2.0–§2.5 与下方 lease 细则)即可执行迭代。
28
28
 
29
- **Findings cleanup(默认)**:Phase 2 每个 plan Assignment 默认 **`Findings cleanup: zero-residual`**(可修 findings 当轮 fix→re-review 清干净;仅真 blocker-defer + Durable Roadmap 可留 open R#)。compass 或 Assignment 可显式覆写为 `allow-residual`。SSOT → **`mstar-artifacts`**「Findings cleanup modes」。
29
+ **Findings cleanup(默认)**:Phase 2 每个 plan Assignment 默认 **`Findings cleanup: zero-residual`**(可修 findings 当轮 fix→re-review 清干净;仅真 blocker-defer + Durable Roadmap 可留 open R#,`critical` 不属 defer)。compass 或 Assignment 可显式覆写为 `allow-residual`。SSOT → **`mstar-artifacts`**「Findings cleanup modes」。
30
30
 
31
31
  ## 2.0 前置条件(五道闸)
32
32
 
@@ -212,7 +212,7 @@ Iteration Phase 2 附加:
212
212
  - PM **NEVER** 在 PM 线程实现产品代码(delegate dev;hotfix 例外见 **`mstar-phase-gates`**)
213
213
  - `Subagent invokes issued: 0` 而 Assignment 已写出 → **`dispatch incomplete`**;下一条补发 invoke,禁止 PM 顶替
214
214
  - QC 初轮:**SDD → N=3**;**inline → N=1**;plan QC tri 三席 **同条消息 N=3**(非 implement 轨数)
215
- - **`Findings cleanup: zero-residual`(默认)**:QC 后可修 Warning/Suggestion → 继续 fix→targeted re-review,直至 clean `Approve` 或仅剩真 blocker-defer;**禁止**把可修项登记为 open residual 草草 `Approve with residuals`
215
+ - **`Findings cleanup: zero-residual`(默认)**:QC 后可修 Warning/Suggestion → 继续 fix→targeted re-review,直至 clean `Approve` 或仅剩真 blocker-defer(`critical` 不属 defer —— 定义 → **`mstar-artifacts`**「Findings cleanup modes」);**禁止**把可修项登记为 open residual 草草 `Approve with residuals`
216
216
 
217
217
  ## Feature worktree (per plan)
218
218
 
@@ -110,6 +110,7 @@ per-plan Done 是 per-plan 的闭环终点;compound 是迭代级收口活动
110
110
  - Prepare 阶段证据:问题定义、歧义结论、plan 链接。
111
111
  - Execute 阶段证据:tasks 清单、实现自检、审查/验证证据。
112
112
  - 结论证据:不得仅写"done",必须可复核(命令、输出、截图或复现步骤)。
113
+ - **证据与变更同层。** 单测/集成测试是 plan task 的默认证据;**开发 plan** 中,真实浏览器、真机、安装/部署 E2E **不写成 task,也不构成任何 gate 的证据义务**——各层自行测试,缺环境如实记为未验证。这类验证的**唯一**落点是用户显式请求的独立 `mstar-e2e` workflow:该 workflow 自身以 plan 注册并承载命名场景,是此边界的合法例外(授权来源见 `mstar-harness-core` § 定向执行与验证边界)。issue/需求/验收文本中出现的端到端场景**不构成**在开发 plan 中加 task 的授权。
113
114
 
114
115
  ## References
115
116
 
@@ -89,7 +89,7 @@ Register 文档形状(`entries[<plan-id>]` 数组 JSON)、**9 个必填字
89
89
  ### Findings cleanup(与 Assignment 联动)
90
90
 
91
91
  - Assignment **`Findings cleanup: zero-residual | allow-residual`** 是唯一 mode 来源(`metadata.findings_cleanup` mirror 已删);迭代 Phase 2 默认 `zero-residual`。
92
- - `zero-residual`:可修 findings 当轮 fix → re-review 清干净;仅真 blocker 可 defer 且须 Durable Roadmap + `target`;`nit` 必须当场修或删;waived/risk-accepted 必须关闭,不得留 open。
92
+ - `zero-residual`:可修 findings 当轮 fix → re-review 清干净;仅真 blocker 可 defer 且须 Durable Roadmap + `target`(`critical` 不属 defer —— 定义 → **`mstar-artifacts`**「Findings cleanup modes」);`nit` 必须当场修或删;waived/risk-accepted 必须关闭,不得留 open。
93
93
  - `allow-residual`:仅 unresolved **critical** 阻止 Approve。
94
94
  - mode 全文与 enforcement → **`mstar-artifacts`** `references/status-and-residuals.md`(「Findings cleanup modes」+ 其 engine check)。
95
95
 
@@ -38,7 +38,7 @@ description: "Morning Star QC orchestration — **SDD mandatory plan QC tri-revi
38
38
  ## Residual Findings 留档门禁(PM)
39
39
 
40
40
  - 先读 Assignment **`Findings cleanup`**(`plans[].metadata.findings_cleanup` mirror 已删——Assignment 是唯一 mode 来源)→ **`mstar-artifacts/references/status-and-residuals.md`**「Findings cleanup modes」。
41
- - **`Findings cleanup: zero-residual`**(iteration Phase 2 默认):可修 **Warning / Suggestion / Critical** → **fix-now + targeted re-review**,**禁止**把可修项登记为 open R# 或用 `Approve with residuals` 收口;**`nit`** 当场修或丢弃(无 R#)。仅 **真 blocker-defer**(外部依赖 / 须下轮产品决策 / 用户本轮显式 defer + Durable Roadmap)可登记 open R#(`decision: defer`)。此时 `Approve with residuals` **仅**允许剩余项全是该类 defer。
41
+ - **`Findings cleanup: zero-residual`**(iteration Phase 2 默认):可修 **Warning / Suggestion / Critical** → **fix-now + targeted re-review**,**禁止**把可修项登记为 open R# 或用 `Approve with residuals` 收口;**`nit`** 当场修或丢弃(无 R#)。仅 **真 blocker-defer**(外部依赖 / 须下轮产品决策 / 用户本轮显式 defer + Durable Roadmap)可登记 open R#(`decision: defer`)。此时 `Approve with residuals` **仅**允许剩余项全是该类 defer,且**不含 `critical`**(不安全后果本次 merge 可达,见上文「Findings cleanup modes」);`critical` 当场修复,或走显式 risk acceptance 并在 register 内关闭,**不得**作为批准遗留项。
42
42
  - **`Findings cleanup: allow-residual`**(standalone / hotfix / inline 默认):阻断项修复后仍有 **Warning / Suggestion** 或技术债 → 必须留档;**`Approve with residuals`** 仅当无 open **Critical**;PM 汇总结论须含 residual 清单与跟踪位置。
43
43
  - **`severity`** 仅允许 `mstar-artifacts/references/status-and-residuals.md` 枚举。
44
44
  - **Open SSOT**:`{PROJECT_DIR}/<id>/residuals.json`(默认 `{HARNESS_DIR}/projects/<id>/`;无项目流程 `_default`)→ `entries[<plan-id>]`;PM 在 consolidated 决策分配 **R1…** 并写入。关闭 → 在 register 内 **in place** 置 `lifecycle` / `closed_at` / `closure_note`(v1 `archived/residuals/` 与 `archive-residuals` 已移除)。
@@ -60,6 +60,14 @@ Leaf reviewers apply verdict per **`mstar-roles/references/qc-specialist/report-
60
60
  - **汇总层零注入**:consolidated 中每条发现可溯源到某 `qcN.md`;PM 不得在汇总层引入席位报告之外的新声明(PM 自身观察走独立 Status Update,不混入 gate 决策输入)。
61
61
  - **Unconfirmed 传导**:任一席位 verdict = `Unconfirmed`(`report-template.md` 定义的证据通道失败态)→ gate 决策不得为 `Approve`——先补证据(重发 review-package / 修 diff 基线)再收敛;受影响席位走既有 targeted re-review 机制(同 `qcN.md` `## Revalidation` 原位更新 verdict),不新增 re-review 形态、不改 N 规则。
62
62
 
63
+ ### 席位预算与截断(PM)
64
+
65
+ - **座次不放宽范围。** N=3 只增加视角:每个席位仍只审其 diff pack 与直接影响接口,预算也不因席位增加而变宽。PM 用 Assignment `Budget` 收紧;默认与数字 SSOT → **`mstar-harness-core`** § 定向执行与验证边界。
66
+ - **截断报告保留 verdict。** 席位因触达预算而声明 `Truncated coverage:` 时,其 verdict 有效,PM **不得**因此升级为 `Unconfirmed`——`Unconfirmed` 仍是证据通道失败态(见上条传导规则)。
67
+ - **未覆盖范围不改写门禁。** 席位 verdict 只涵盖其已审范围:当 Assignment 范围未被完整覆盖时,**gate decision 不得为 `Approve`**。PM 二选一——把未覆盖范围按 targeted re-review 重新派发(席位在预算内补完),或显式收窄 `Review range` 并把收窄依据记入 `qc-consolidated.md` 后再收敛。截断范围仍按「未提及 = 未审查」在 `qc-consolidated.md` 中如实标注 `unreviewed`,PM 不重审无关内容来补全它。
68
+
69
+ > **Engine check (when available):** run `mstar qc validate-report <report.md>` on each seat report (and `mstar dispatch validate <assignment-file>` for the Assignment-side round-bounding gate — `Budget` + `Return shape` on review / audit rounds; or `import { validateQcReport } from "@mstar-harness/engine"` in a host hook). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
70
+
63
71
  ## 证据规则(PM · consolidated 输入)
64
72
 
65
73
  - Critical 发现须含触发条件、影响范围、修复建议。
@@ -45,6 +45,18 @@ Layering anchor: `mstar-review-qc/references/review-responsibility-boundaries.md
45
45
 
46
46
  `⚠️ Cannot verify from diff` items do not block other findings — PM resolves them before marking the task complete.
47
47
 
48
+ ### Issue severity (Mode A)
49
+
50
+ `Critical` / `Important` / `Minor` are this mode's projection of the one blocking judgement — the axis itself is defined once in `mstar-artifacts` `references/status-and-residuals.md` (§ Residual findings: `severity` → §5 Cross-chain vocabulary). Do not re-derive its ladder here.
51
+
52
+ | Label | Threshold on the axis | Effect |
53
+ | --- | --- | --- |
54
+ | `Critical` | Unsafe **and** reachable in this task's diff: correctness bug, security hole, data loss, auth/authz bypass, broken public contract. | Blocks the task — drives the per-task fix loop (`mstar-sdd` `references/file-handoffs.md` § Fix loop). |
55
+ | `Important` | High-impact but non-blocking: unsafe but **not** reachable in this diff, significant tech debt, or otherwise substantive. | Drives the per-task fix loop (same). |
56
+ | `Minor` | Small and cheap, or style / naming / wording only. | Not a fix-loop driver — handed to `## Minor (for plan QC)` in the same ledger file (`mstar-sdd` SKILL.md). |
57
+
58
+ Mode B (audit) does not use this vocabulary either — it reports with the audit finding format (`Impact` / `Effort` / `Risk` / `Confidence` per finding, no severity class; `mstar-audit` `references/finding-format.md`) and ranks plans by `Priority` in the audit index (`mstar-audit` `references/codebase-audit.md` § Execution order & status). Mode C (PR review) is the only mode that classifies with the **Merge class** (`must-fix` / `should-fix` / `nit`; `mstar-audit` `references/pr-review.md` § Merge class — PR findings only). Never mix label sets in one report.
59
+
48
60
  ## Mode B — Audit Executor (`Task category: audit`)
49
61
 
50
62
  - Execute the `mstar-audit` codebase-audit variant: SKILL.md common core (Recon → Vet & prioritize) + `references/codebase-audit.md` (Audit — parallel category scout fan-out; ≤4 concurrent `standard`, ≤8 `deep` → Write plans at `{PLAN_DIR}/audit-<date>/`).
@@ -11,6 +11,7 @@ The concise gate summary remains in `references/project-manager.md`.
11
11
  - For parallel batch with `N >= 2`, dispatch turn must emit all `N` invokes in one message when host supports it.
12
12
  - **Same-repo writable parallel tracks**: tool concurrency and worktree isolation are **separate gates**. Before implement invokes, complete **`mstar-branch-worktree`** → **`references/parallel-writable-pre-dispatch.md`**.
13
13
  - **Scope and stopping are explicit**: apply `mstar-harness-core` § 定向执行与验证边界. Give each leaf one result, owned paths/symbols, relevant inputs, named checks/selectors, and an evidence-based stopping condition. Reuse unaffected evidence; do not inject a suite merely because the repo exposes it. Independent ready assignments run concurrently after their dependency/isolation checks.
14
+ - **Review/QC rounds are quantitative, not adjectival**: a read-only review / QC dispatch states a `Budget` (expansion cap) and a `Return shape`, so the seat stops when its assigned questions are answered or the cap is reached, returns the verdict it has plus a truncated-coverage declaration, and never expands until a human steers. Budget defaults, the truncation marker, and its relation to `Unconfirmed` → `mstar-harness-core` § 定向执行与验证边界. The severity bar for the round's findings → `mstar-artifacts` `references/status-and-residuals.md`.
14
15
  - **Skill preset activation is PM-owned**: topic skills are presets in each role's `Skill Preset (PM-Activated)` section (`mstar-roles/references/<role>.md`), not self-loaded defaults. Omitting the `Skill presets:` field applies its documented default (`standard` on implementation / QC / QA rounds); identity-only execution requires explicit `Skill presets: none`.
15
16
 
16
17
  ## Executor Anti-Recursion Rules
@@ -50,6 +51,7 @@ The **`**You are a leaf executor. You MUST NOT:**`** section (previously just pr
50
51
  - Anti-patterns must be action-oriented ("auto-dispatch to …", "treat … as invoke", "start … before …") — not abstract descriptions.
51
52
  - If the assignment involves multiple QCs or parallel tracks, add a specific bullet about NOT serializing or pre-empting the parallel dispatch.
52
53
  - If the assignment is part of a broader staged plan with follow-up tasks, add a bullet about NOT auto-extending scope into downstream tasks.
54
+ - **Anti-pattern — unbounded negative acceptance:** an Acceptance Criterion phrased as a repo-wide negative property ("prove no surviving claim of X anywhere", "make sure nothing else uses Y") with no termination rule. Scope it to the assigned diff pack plus directly affected interfaces, or state the budget that bounds the search — the seat stops there and declares what it did not cover. An open-ended "prove no X anywhere" acceptance is a dispatch defect, not a review task.
53
55
 
54
56
  ```markdown
55
57
  ## Assignment
@@ -116,6 +118,10 @@ The **`**You are a leaf executor. You MUST NOT:**`** section (previously just pr
116
118
  - In: <owned files/symbols, directly affected interfaces; finding + fix delta for re-review>
117
119
  - Out: <excluded work and specific boundary>
118
120
  **Inputs**: <brief, diff, relevant knowledge, reusable evidence with original range>
121
+ **Budget (review / QC seats)**: <expansion cap (file opens / wall clock) — may only tighten the default in `mstar-harness-core` § 定向执行与验证边界, never loosen it; `N/A` on implement / ops rounds>
122
+ **Return shape (review / QC seats)**: <what the seat returns and how it stops — verdict + findings shape; a clean round returns `findings: []` explicitly instead of prose; `N/A` when the round produces no findings>
123
+ **Severity bar**: <what this round must treat as blocking — the blocking classes are unsafe-to-ship or significant tech debt; class definitions and the full report-section mapping → `mstar-artifacts` `references/status-and-residuals.md`; `N/A` on rounds with no findings>
124
+ **Input provenance**: <how the seat grounds its claims — the command plus observed output for a `declared` / `recorded` / `written` artifact claim, and provenance for an asserted `path:line` citation; `N/A` when the round asserts neither>
119
125
  **Deliverables**: ...
120
126
  **Acceptance Criteria**:
121
127
  - [ ] ...
@@ -123,7 +129,7 @@ The **`**You are a leaf executor. You MUST NOT:**`** section (previously just pr
123
129
  - [ ] <AC → exact affected unit-test selector or scoped static check; expected result>
124
130
  - [ ] <reused evidence + why unchanged, or new observable proof>
125
131
  - [ ] commit proof
126
- **Constraints**: <no scope expansion; no local full suite without referenced explicit user permission; QA unit-only; no spontaneous browser/device/E2E; stop on concrete missing inputs and return once acceptance is evidenced>
132
+ **Constraints**: <no scope expansion; no local full suite without referenced explicit user permission; QA unit-only; no spontaneous browser/device/E2E; review / QC seats stop at the assigned budget and declare truncated coverage instead of expanding; stop on concrete missing inputs and return once acceptance is evidenced>
127
133
  **Effort (agent-oriented)**: <XS/S/M/L/XL + session band>
128
134
  **Orchestration Guard** (see `**You are a leaf executor. You MUST NOT:**` block at top for primary anti-patterns):
129
135
  - No recursive same-role dispatch
@@ -135,6 +141,13 @@ The **`**You are a leaf executor. You MUST NOT:**`** section (previously just pr
135
141
  **Execution evidence**: <RCA/test-first/review feedback/evidence expectations for the assignee, if applicable>
136
142
  ```
137
143
 
144
+ ## PM Self-Check (artifact claims and citations)
145
+
146
+ State a claim only as strongly as the evidence in hand:
147
+
148
+ - An artifact claim — `declared` / `recorded` / `written` — is stated only together with the command and the observed output that shows it; without both, describe the artifact as pending rather than done.
149
+ - An asserted `path:line` carries its provenance: a normative-document citation is traced (`git show <ref>:<path>`) or fetched raw with a content identity check, so the quoted text is shown to come from the revision being cited — not from memory of the file.
150
+
138
151
  ## L1 path fields (iteration Phase 2, lease gate not waived)
139
152
 
140
153
  When iteration **L1** is active (the integration worktree is recorded in the workflow snapshot `integration_worktree_path`; worktree mode is **not** waived):
@@ -69,9 +69,9 @@ Read Assignment **`Findings cleanup`** first (`mstar-artifacts` — Findings cle
69
69
 
70
70
  - Prefer **fix-now + targeted re-review** for Critical / Warning / Suggestion that can be fixed this session.
71
71
  - **NEVER** park fixable findings as open R# or use `Approve with residuals` for them.
72
- - Register open R# **only** for true blocker-defers (`decision: defer` + Durable Roadmap + `target` next iteration/milestone).
72
+ - Register open R# **only** for true blocker-defers (`decision: defer` + Durable Roadmap + `target` next iteration/milestone) — never a `critical` (`mstar-artifacts` Findings cleanup modes).
73
73
  - `nit`: fix or drop (no R#).
74
- - Plan Done: prefer empty open list; any remaining open R# must all be blocker-defer + roadmap.
74
+ - Plan Done: prefer empty open list; any remaining open R# must all be blocker-defer + roadmap — never a `critical` (`mstar-artifacts` Findings cleanup modes).
75
75
 
76
76
  ### When `Findings cleanup: allow-residual` (or unset outside iteration Phase 2)
77
77
 
@@ -6,6 +6,8 @@ Extension of `references/qc-specialist-shared.md`. Frontmatter and path rules re
6
6
 
7
7
  Write under the Assignment-provided **`{SDD_DIR}/review/qc#.md`** (`qc1`…`qc3` or `qc.md`). YAML frontmatter first (see `qc-specialist-shared.md`), then:
8
8
 
9
+ **Machine-checked lines** (`mstar qc validate-report <report.md>`): the frontmatter fields `report_kind` / `reviewer` / `reviewer_index` / `plan_id` / `verdict` / `generated_at`; the body `**Verdict**:` line must agree with the frontmatter `verdict` (trailing prose is fine); each `## Summary` count must equal the top-level entries under the matching `## Findings` severity section — `## Summary` and `## Findings` are the report's SINGLE current state, so an in-place revalidation refreshes both instead of appending a second tally (`qc-specialist-shared.md` § Targeted re-review); `Approve` is refused while Critical/Warning counts are non-zero; `Unconfirmed` is refused while the report declares `Truncated coverage:`. A cap stop is not a channel failure — keep the earned verdict and write the truncation line.
10
+
9
11
  ```markdown
10
12
  # Code Review Report
11
13
 
@@ -24,6 +26,7 @@ Write under the Assignment-provided **`{SDD_DIR}/review/qc#.md`** (`qc1`…`qc3`
24
26
  - Working branch (verified): {name}
25
27
  - Review cwd (verified): {path from git rev-parse --show-toplevel}
26
28
  - Files reviewed: {count}
29
+ - Truncated coverage: {present only when the seat budget stopped expansion — name what was not covered; omit this line otherwise. The verdict stands: truncation is not `Unconfirmed`}
27
30
  - Commit range (if not identical to Review range line, explain): {hash..hash}
28
31
  - Analysis methods: {e.g. git-diff, read, grep, deep-lens: <names> — not test/build runs}
29
32
 
@@ -29,7 +29,7 @@ Layer SSOT → `mstar-review-qc/references/review-responsibility-boundaries.md`.
29
29
  2. **Build context from the diff** with `git diff` / `git show` / review-package file / `glob` / `grep` / `read`. Use the supplied relevant knowledge/context; do not launch global exploration or delegate navigation.
30
30
  3. Re-verify branch vs **`Working branch` / `Branch policy`** before concluding.
31
31
  4. **Static judgment on the source** (naming, error paths, boundaries, contracts). Default tooling = read/grep only. **Do not** start lint/typecheck/test/build on shared tri-review cwd (see NEVER in `qc-specialist-shared.md`).
32
- 5. Apply only the **`reviewer-checklist.md`** items affected by the diff. Reuse unchanged L2 evidence; re-review only the assigned findings and fix delta. Stop when these questions have evidence.
32
+ 5. Apply only the **`reviewer-checklist.md`** items affected by the diff. Reuse unchanged L2 evidence; re-review only the assigned findings and fix delta. **Stop** when the assigned review questions are answered or the Assignment **`Budget`** is reached (default → `mstar-harness-core` § 定向执行与验证边界) — no repo-wide tracing to "be sure". A budget stop keeps the verdict and records `Truncated coverage:` in `## Scope`; it is never a reason to emit `Unconfirmed`.
33
33
  6. Produce structured findings with severity and evidence. PM maps report sections to register **`severity`** (`projects/<id>/residuals.json` → `entries[<plan-id>]`) per `mstar-artifacts/references/status-and-residuals.md` — do not invent non-canonical severity strings.
34
34
  7. **Write report:** Write `.md` to the Assignment-provided `{SDD_DIR}/review/` report path. Do not commit raw bundle reports unless Assignment explicitly says `Review archive mode: tracked reports`.
35
35
  8. **No stall:** When done, emit **Completion Report** in the same turn — no “notify PM?” choosers.
@@ -21,6 +21,8 @@ Your output is a structured QC report plus Completion Report.
21
21
 
22
22
  **Scope:** follow **`mstar-harness-core`** § 定向执行与验证边界. Initial review covers assigned changed hunks and directly affected interfaces; reuse L2 evidence. Re-review covers only assigned findings and fix delta. Seat count never authorizes full-repository review or fresh global exploration.
23
23
 
24
+ **Budget and stopping (hard):** honour the Assignment **`Budget`** and **`Return shape`** (return the declared verdict + findings; a clean round returns `findings: []` explicitly instead of prose); when `Budget` is omitted, the default in the core section applies — it may be tightened, never loosened. Follow past the assigned range only on a must-fix trail. On reaching the budget, stop expanding: keep the verdict for what was reviewed and declare `Truncated coverage:` in the report `## Scope`. A cap stop is **not** `Unconfirmed` — the evidence channel was intact, only scope was cut; `Unconfirmed` stays reserved for a failed channel. The Assignment-side presence of `Budget` and `Return shape` is machine-checked by `mstar dispatch validate`, and the report-side `Truncated coverage:` / verdict pairing by `mstar qc validate-report` (see the engine check in **`mstar-review-qc`** § 席位预算与截断).
25
+
24
26
  **Do (L3):** Read `git diff` / review-package; reason about correctness, security, contracts, maintainability, reliability; flag coverage **gaps in the diff** (missing tests for changed behavior); write findings with evidence from source.
25
27
 
26
28
  **Do not (leave to L1 / L4):** Run test suites, builds, package installs, or heavy project toolchains that mutate caches — see NEVER rules and `reviewer-workflow.md`.
@@ -73,6 +75,7 @@ Write the Assignment-provided path under **`{SDD_DIR}/review/{report_suffix}.md`
73
75
  When Assignment includes **`QC re-review: targeted`**:
74
76
 
75
77
  - Edit the **same** bundle `{report_suffix}.md` — add **`## Revalidation`**, update frontmatter verdict/`generated_at`.
78
+ - **Refresh the current state in place**: `## Summary` and the `## Findings` sections must describe the state AFTER the fix delta (a closed finding leaves its section, counts drop), so the report carries exactly ONE tally. `## Revalidation` records the process — what was re-checked, findings closed/kept per ID — and never holds a second count. Leaving the original `## Summary` counts in place while the verdict moves to `Approve` makes the report contradict itself.
76
79
  - Do **not** create `qcN-rev2.md` on this path.
77
80
  - Full tri re-review → new basenames per `mstar-artifacts/references/plan-files-and-reports.md`.
78
81
 
@@ -39,12 +39,17 @@ Dispatch:
39
39
  Diff file: [DIFF_FILE]
40
40
 
41
41
  Read the diff file once. Do not re-run git. Do not mutate checkout.
42
- Review only the assigned task diff and directly affected interfaces.
43
- No repository-wide exploration or full test suite. Reuse relevant
44
- implementer evidence; a specific doubt permits only the assigned focused
45
- unit check. Non-executable docs/policy may use scoped-check evidence;
46
- verify its applicability against the diff, never invent a test obligation.
47
- Stop once the assigned acceptance questions are answered.
42
+ Review only the assigned task diff and directly affected interfaces;
43
+ no repository-wide tracing unless a blocking finding requires it.
44
+ No full test suite. Reuse relevant implementer evidence; a specific
45
+ doubt permits only the assigned focused unit check. Non-executable
46
+ docs/policy may use scoped-check evidence; verify its applicability
47
+ against the diff, never invent a test obligation. Stop once the
48
+ assigned acceptance questions are answered.
49
+ The task diff plus directly affected interfaces are this review's budget
50
+ (default bounded-seat cap → `mstar-harness-core` § 定向执行与验证边界);
51
+ when it is reached, stop there and return the assessment for what was
52
+ reviewed plus a `Truncated coverage: <what was not covered>` line.
48
53
 
49
54
  ## Output
50
55
 
@@ -55,7 +60,7 @@ Dispatch:
55
60
  ### Strengths
56
61
 
57
62
  ### Issues
58
- #### Critical | Important | Minor
63
+ #### Critical | Important | Minor # thresholds + fix-loop routing → mstar-roles/references/code-reviewer.md § Issue severity (Mode A)
59
64
 
60
65
  ### Assessment
61
66
  **Task quality:** Approved | Needs fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstar-harness/dsh",
3
- "version": "3.9.1",
3
+ "version": "3.9.3",
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",