Skip to content

Commit 2eefc8a

Browse files
fix(pm): the contract review's item ④ rides the narrowing face too (#26695)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9RP3jSzSG3UJMVL5NFpFfad)_ Fixes #26527 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:契约复核的 ④ 设计判断现在也挂在收窄面(`Clause-②: no (narrowing)`),模板、简报与规则文本同步改成三面;申报面照旧无 ④。 - 为什么改:你裁了 A(评论 6442046166):只在运行时代码里收窄已发布接受集的 PR,复核也要对照 `main` 上的 spec 问「这次收窄是在消费端砍掉了一个已声明的能力,还是把 spec 自己的拒绝落实了」。 - 风险与回滚:只动复核流程的文本与模板,不动任何运行时;回滚即 revert 这一个 commit。 - 先看:`scripts/pm/record-recognisers.mjs` 的 `REVIEW_FACES` narrowing 行(`fullReview: true`)与简报的 narrowing 专用 ④ 段;`contract-review.md` L22/L30。 - 两分钟验证:`node scripts/pm/record-recognisers.mjs --brief-template --face narrowing` 应打出 ④ 段(「the narrowing itself, read against the published spec on `main`」);`--face declaration` 的围栏内无 ④。 - 需要你做的:批准本 PR(GOVERNED_APPROVERS);席位已请总监契约复审,批准后席位落地;在此之前保持 draft。 ## What changes The maintainer's ruling on #26527 item 3 (letter A, ruling record 6442046166) hangs item ④, the design judgment, on the narrowing face of the contract review as well. A PR that narrows a published accept set in runtime code alone, touching neither `packages/spec/src/**` nor a governed path, now gets the same ④ the schema and rules faces get, in the narrowing's own shape: no `hits` files, so the judgment is of the narrowing itself, read against the published spec on `main` — does it take a declared capability away at the consumer, or make the spec's own refusal real? - `scripts/pm/record-recognisers.mjs` - `REVIEW_FACES.narrowing` gains `fullReview: true`; `recordCarriesDesignJudgment` is unchanged and now answers true for that face, so the record prints `### ④ Design judgment` on `--face narrowing` (the declaration face, below tier, still prints three headings). - The `--template` notes name three faces and the narrowing scenario (the narrowing itself against the published spec on `main`); the declaration face alone is said to carry no ④. - The `--brief-template` on the narrowing face carries a narrowing-specific ④ instruction (read against the published spec on `main`; a capability declared and not delivered is an implementation gap, implemented or retired, never narrowed at the consumer) and a scope line saying ④ judges the narrowing over the whole-diff floor, lockfiles, generated output, changesets and prose not reviewed. The schema and rules faces keep the per-`hits`-file shape unchanged. - Docblocks on the face table, the record builder and the brief builder say the same. - `.claude/skills/pm-dispatch/references/contract-review.md` - L30: 「④ 设计判断只欠 schema 与 governed 规则文本两面」 → 「④ 设计判断欠 schema、governed 规则文本、收窄三面」 (114 B → 118 B, same line). - L22: the record-shape parenthetical 「(schema/governed 两面加 ④)」 → 「(申报面外三面加 ④)」 (115 B → 111 B, same line). The card named L30 only; L22 states the same face set a second time and would have contradicted L30, so it moves with it — declared in the report as a within-file widening. - 55 lines before and after; no new line; every edited line under the 120-byte budget. ## Why Faces resolve schema → rules → narrowing → declaration, so a narrowing PR that also touches a spec or governed path already carried ④; only the runtime-only narrowing fell to a face without it. That is exactly the face where the pm-dispatch principle 「声明而未兑现是实现缺口,补实现或退役,⛔ 不在消费端收窄」 is most easily broken (spec untouched, runtime narrowed first), and the review asked only whether the declaration line was spelled right. The ruling closes that gap without a new face or a new gate. ## Tests Forced test edits, all in the self-test of `scripts/pm/record-recognisers.mjs` (`pnpm check:pm-record-recognisers`): - Flipped: 「the narrowing face carries NO ④」 → carries ④ (fourth heading, fenced on `--face narrowing`); 「exactly the two path-read faces are full-review faces」 → the three at-tier faces (`schema,rules,narrowing`); 「the narrowing brief carries no ④」 → carries ④ in the narrowing's own shape (spec scenario, no `hits`-ONLY rule, no angle brackets, no model identifier). - Reworded fragments: the notes pin now reads 「on the schema, rules and narrowing faces」 and 「the declaration face alone carries no ④」; the brief face pin covers `narrowing` too. - Added: the notes name the narrowing scenario (template battery floor 28 → 29); the `hits` faces keep the per-file ④ shape and never the narrowing's (brief battery floor 17 → 18). - Unchanged and still green: the declaration face carries no ④ in record or brief. Self-test at `78af1243`: 219 cases pass, exit 0 (217 before the change). Mutation leg (one shot, `scripts/ablation-replace.mjs`, anchor hit exactly once, trap-restored, restored blob byte-identical to HEAD `462459281f4b`): `fullReview: true` → `false` on the narrowing row ⇒ exit 1, 5 of 219 cases fail (the three flipped pins and the two added ones). No build or dist is involved; the script runs from source. ## Acceptance notes - The card's acceptance line 「`--template --paths packages/objectql/src/x.ts` with a narrowing face prints ④」 is not reachable through `--paths` alone: `reviewFace` reads the narrowing face off the `Clause-②:` line, which a path list cannot hand it. Measured at `78af1243`: `--template --paths packages/objectql/src/x.ts` (no changeset in the list) prints the declaration face, exit 0; `--template --paths .changeset/x.md packages/objectql/src/x.ts` is refused, exit 1, telling the caller to pass `--face narrowing` (pinned before this PR). The face that prints ④ is `--template --face narrowing`, and it does. - No other reader of `fullReview` exists outside this file (`git grep fullReview` at `78af1243`: record-recognisers.mjs only); the queue guard and `dispatch-gates` do not read it. - The pm-dispatch SKILL.md rule the brief now echoes (「⛔ 不在消费端收窄」) is untouched. ## Verification - `node scripts/pm/record-recognisers.mjs --self-test` — 219 cases pass, exit 0. - `pnpm check:pm-skill-ratchet` — exit 0 (self-test and scan); `pnpm check:pm-skill-id-lint` — exit 0, 104 files clean. - Derived gate list (`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `78af1243`): 38 commands; results in the `os-dev-report` comment on #26527 and the details block below. <details><summary>Derived gate sweep at `78af1243` — 38 commands, every exit 0, captured before any pipe; `--ran` reconciliation: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN</summary> ```text node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/check-declaration-mirrors.mjs :: exit 0 node scripts/check-declaration-mirrors.mjs --self-test :: exit 0 node scripts/check-self-test-wired.mjs :: exit 0 node scripts/check-self-test-wired.mjs --self-test :: exit 0 node scripts/check-self-test-workflow-commands.mjs :: exit 0 node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0 node scripts/check-whole-set-label-write.mjs :: exit 0 node scripts/check-whole-set-label-write.mjs --self-test :: exit 0 node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0 node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0 node scripts/pm/check-harness-current.mjs --self-test :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:bash32-floor :: exit 0 pnpm check:ci-filter-parity :: exit 0 pnpm check:cli-command-ids :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:entry-guard :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:parse-guard :: exit 0 pnpm check:pm-dispatch-gates :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-record-recognisers :: exit 0 pnpm check:pm-skill-id-lint :: exit 0 pnpm check:pm-skill-ratchet :: exit 0 pnpm check:pnpm-filter-targets :: exit 0 pnpm check:pnpm-flag-spellings :: exit 0 pnpm check:ratchet-remedy-authority :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:scripts-symbol-anchors :: exit 0 pnpm check:skill-frame-sync :: exit 0 pnpm check:watch-hint-literal :: exit 0 ``` Notes: `pnpm check:pm-dispatch-gates` ran its fast tier (1935 cases pass; 7 slow sections deferred, as the script does on every local run) in 5m30s; `@objectstack/lint check:doc-formula-expressions` needed `@objectstack/formula` and `@objectstack/lint` built first (through `scripts/pm/os-verify-lock.sh`, VERDICT command-exit 0, 99 s). Not in the derived list and not run locally: repo-wide `pnpm lint` (CI owns it) and the CI families outside the derivation; the PR check-runs are the record for those. </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (not touched) - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` is CI's run (repo-wide scan). - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset — nothing here publishes (`.claude/**` + `scripts/pm/**`), so `skip-changeset`; both declaration lines are filled in above. - [x] 6. `packages/spec` not touched. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English (the 维护者速读 block is the maintainer's Chinese read, as the dev contract asks). - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_01ADHkmRLPe6T3Z5Fy17DijY)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 94bab5a commit 2eefc8a

2 files changed

Lines changed: 45 additions & 26 deletions

File tree

‎.claude/skills/pm-dispatch/references/contract-review.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
出货字节,⛔ 不是已发布接受集,改它不触发 `Clause-②: yes`;legacy node10 深引用在契约之外。
2020
- 四面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。
2121
- 复核记录 = 一条评论落 PR 或卡,席内与子代理同形;散文、dev 自评、`os-dev-report` 恒不算。
22-
- 同形 = `## Contract review` 题头、head sha 独占码段、①②③ 逐项(schema/governed 两面加 ④)、
22+
- 同形 = `## Contract review` 题头、head sha 独占码段、①②③ 逐项(申报面外三面加 ④)、
2323
独立性对、PASS/FAIL。
2424
- 同形含首行 `Served-tier:`:值写该面所定档的常量名 `CONTRACT_REVIEW_TIER` 或 `TIER_DEFAULT`;
2525
无此行不成裁决;模板 `node scripts/pm/record-recognisers.mjs --template`,申报面加 `--face declaration`。
2626
- 同形另带 `Local-runs:` 行:`none`,或 `probe — REASON` 具名唯一本地探针;
2727
有行必校,缺行旧记录不改判。
2828
- ① derived judgments 逐项:diff 引出的接受集与公开面变化逐条点名判对错。
2929
- ② semver 定级与 changeset 声明一致;③ 边界旗:dev 挂旗与 `open_questions` 逐旗答复或升级。
30-
- ④ 设计判断只欠 schema 与 governed 规则文本两面,spec、skills、ADR 皆已在内 ⛔ 不另立面:
30+
- ④ 设计判断欠 schema、governed 规则文本、收窄三面,spec、skills、ADR 皆已在内 ⛔ 不另立面:
3131
逐 `hits` 文件判改动对所引代码与验收场景是否成立,ADR 另判首个消费者与执行计划;
3232
被引代码读而不审;①–④ 合称完整复核,余面同形无 ④,⛔ 无第二条记录。
3333
- 实质 head 各欠一轮完整复核;只落发现的 commit 由同一复核者 delta 复核;无 must-fix 即止。

0 commit comments

Comments
 (0)