Skip to content

Commit 5e5ce48

Browse files
pm-dispatch: owe the isolated contract review on three contract faces; changeset and docs prose move to the seat's ACCEPT (#21192)
Fixes #21187 Clause-②: no ## What this changes `references/contract-review.md` named five faces that owe an at-tier contract review, and three of them were prose: `.changeset` / CHANGELOG, `content/docs/**` and `apps/docs/**`. The eligibility line in `references/execution-duties.md` then forbids an off-tier seat from reviewing in-seat. Together, every PR carrying a releasing changeset owed an isolated `CONTRACT_REVIEW_TIER` subagent whenever its seat was not spec or skills. This PR implements the ruling. The isolated at-tier review is now owed on exactly three contract faces: - a `Clause-②: yes` declaration; - published schema (`packages/spec/src/**`, non-test); - governed rule text (the SKILL.md definition, `.claude/**` included; Tier S as today). The prose faces (`.changeset` / CHANGELOG, `content/docs/**`, `apps/docs/**`) are checked sentence by sentence against the diff in the dispatching seat's ACCEPT, at the seat's own tier, and the ACCEPT names the sentences it checked. No second agent is spawned for them. The change is text-only. No script or workflow implements the face list (search below), and the queue's contract-review gate reads only the two Clause-② legs (`landing-operations.md` 「条款②入队闸门」), which this PR does not touch. ## Rulings implemented - Maintainer, ruling A, quoted in the card body: 「我已经同意了,不需要严格的规则」. It answers the seat's proposal (quoted verbatim in the card body) that changeset prose be self-checked by the seat at ACCEPT, with no at-tier subagent spawned for it. - Maintainer to the director seat, settling forks 1, 2 and 3 of ruling record 5934170950 on the card: 「同意,你负责派发。」 1. The docs faces move with the prose: `content/docs/**` and `apps/docs/**` no longer owe an isolated review. 2. Two at-tier uses stay exactly as they are (see the next section but one). 3. `priority:p1`, landed this round. ## Every sentence changed (before, then after) All five files keep their line counts. Anchors are content, not line numbers. Sentences 1 to 6 landed in `4bde1f71a`; sentences 7 and 8 landed in `27e976d73` (review round 1). **1. `references/contract-review.md`, the face list** (two lines become three): ```text - 复核面 = 出货给用户或 agent 的五处:`content/docs/**`、`apps/docs/**`、CHANGELOG/`.changeset` 散文。 - 加已发布 schema(`packages/spec/src/**` 非测试)与 governed 规则文本(统一定义见 SKILL.md)。 ``` ```text - 复核面 = 契约三面:`Clause-②: yes` 申报、已发布 schema(`packages/spec/src/**` 非测试)、governed 规则文本(统一定义见 SKILL.md);`.changeset`/CHANGELOG、`content/docs/**`、`apps/docs/**` 散文面 ⛔ 不在其列:派发席按本席档在 ACCEPT 逐句对照 diff 核,ACCEPT 点名所核句。 ``` The line breaks fall at a source space (`governed 规则文本`, `散文面 ⛔`), so the rendered text is unchanged by them. **2. `references/contract-review.md`, 「五面皆不碰」** (renamed; meaning kept for the three-face set): ```text - 五面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。 ``` ```text - 三面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。 ``` **3. `references/contract-review.md`, the independence-pair line** (this is the line payment, see "Line budget"): ```text - 独立性对:`Implemented-by:`/`Reviewed-by:` 取值见 `node scripts/pm/record-recognisers.mjs --template`;子代理记采纳它的席位。 ``` ```text - 独立性对:`Implemented-by:`/`Reviewed-by:` 取值同见 `--template`;子代理记采纳它的席位。 ``` **4. `references/landing-operations.md`, 「交付后复核按面欠」:** ```text - 交付后复核按面欠 ⛔ 不按车道(五面见 `references/contract-review.md`);双肢命中即 spec 车道。 ``` ```text - 交付后复核按面欠 ⛔ 不按车道(三面见 `references/contract-review.md`);双肢命中即 spec 车道。 ``` **5. `references/execution-duties.md`, 「条款②自审资格按车道」:** ```text - 条款②自审资格按车道:spec 与 skills 席达档席内审;未达档 ⛔ 不自审,起隔离达档子代理。 ``` ```text - 契约三面自审资格按车道:spec/skills 席达档席内审;未达档 ⛔ 不自审,起隔离达档子代理。 ``` `spec 与 skills` became `spec/skills` only to keep the line within the ratchet's 120-byte cap (118 bytes). **6. `references/lanes/ui.md`, 「条款②复核本席适用」:** ```text - 条款②复核本席适用:按面欠达档复核记录,落 PR 或卡,归属与资格见 `../contract-review.md`。 ``` ```text - 契约三面复核本席适用:按面欠达档记录落 PR 或卡,散文面归 ACCEPT,见 `../contract-review.md`。 ``` The ui seat is the lane whose changeset-only PRs started this card, so its line says where the prose check now sits. **7. `references/review-checklist.md` 〈范围与 changeset〉, the ACCEPT-side prose check** (new line, review round 1). The path a seat walks at ACCEPT is `execution-duties.md` 〈复核〉 into this checklist, so the duty is stated here as well as in `contract-review.md`: ```text (none) ``` ```text - changeset/CHANGELOG、`content/docs/**`、`apps/docs/**`:逐句核 diff,ACCEPT 点名所核句,⛔ 不起子代理。 ``` The line is paid in the same file by compressing the two-line dev-union head check into one. The dropped words restate the dev's own obligation, which `.claude/agents/os-dev.md` carries (run the union after the final commit, quote the short sha in the report and the body), and the both-directions rule that the same section states two lines above (「不一致的双向都不入账」). No ⛔ line is touched. ```text - dev 本地并集同样先钉 head:最后一次提交之后跑,`git rev-parse --short HEAD` 抄进报告与正文。 - 与 PR 当前 `head.sha` 比一次,对不上即死树读数、双向都不入账;没抄 ⇒ 按没有读数处理。 ``` ```text - dev 本地并集钉 head:所抄 `git rev-parse --short HEAD` 不符 PR `head.sha` 或没抄 ⇒ 双向都不入账。 ``` **8. `references/contract-review.md`, the trigger** (review round 1). The first contract face is a `Clause-②: yes` declaration, which lives in the claim comment, not in the diff: ```text - 欠不欠按面判 ⛔ 不按车道:diff 碰下列任一面即欠达档复核,交付后当轮完成。 ``` ```text - 欠不欠按面判 ⛔ 不按车道:diff 或认领申报碰下列任一面即欠达档复核,交付后当轮完成。 ``` ## Deliberately unchanged (ruling point 2) These two lines are not prose review. Each is the record that lets a red or exceptional gate pass, so they stay exactly as they are: - `references/execution-duties.md`: 「改到已有 `.changeset/*.md` 的 PR ⛔ 不打 `skip-changeset`;确认取同 head 达档 PASS 或维护者原话」 - `references/landing-operations.md`: 「DELIBERATE CORRECTION 红(`check-empty-changeset`):同 head 达档复核 PASS 记录即确认」 Both lines grep exactly once at head, and neither is an added or removed line in the diff (the second shows up only as hunk context). ## Where the rule lives: the search Base `2c1cef334`. Searched `.claude/`, `AGENTS.md` and `CLAUDE.md`: - Face-list wording, `五面|五处|复核面|按面|四面|三面`: the rule hits only the anchors changed above. The other hits are unrelated: `execution-duties.md` 「三面都查」 (premise check), `lanes/devx.md` and `lanes/spec.md` (spec lane slicing), and `platform-readings.md` 「按面不按路由」 (footer readings). - At-tier wording, `达档|CONTRACT_REVIEW_TIER|at-tier|契约复[审核]`: none of these ties prose to an at-tier record. `dispatch-runbook.md` 「无主阻塞项的契约面(含 `packages/spec`)」 names contract faces only, and `SKILL.md` (the skills-hunk, Tier S and governed-definition lines) and `.claude/agents/os-dev.md` (Tier S landing) are about governed text. - Prose wording, `散文`, `content/docs|apps/docs`, `contract[- ]review|prose`, and `changeset` on the same line as `复核|review|达档|复审`: no further site. `review-checklist.md`, `SKILL.md` and `.claude/agents/os-dev.md` carry no restatement of the face list, so nothing outside `references/**` needed an edit. - Mechanism: 7 files under `scripts/` and `.github/` mention both a contract-review term and one of `.changeset` / `content/docs` / `apps/docs`. In each of them, 0 lines put the two within 4 lines of each other. No script reads the changed sentences. The one script that reads `contract-review.md` as text (the `dispatch-gates.mjs` self-test: the `CONTRACT_REVIEW_TIER` constant is present and the retired fuse text is absent) is unaffected, and its gate is green. - Sister checkouts (objectui `0a3e540`, cloud `90b1af0`, hotcrm `fb408a7`): 0 hits for `五面|复核面|五处|按面欠|CONTRACT_REVIEW_TIER` outside CHANGELOGs. ## Line budget | file | lines before → after | ceiling | bytes before → after | |:--|:--|:--|:--| | `references/contract-review.md` | 40 → 40 | 60 | 3349 → 3423 | | `references/landing-operations.md` | 101 → 101 | 101 | 8763 → 8763 | | `references/execution-duties.md` | 183 → 183 | 183 | 17365 → 17364 | | `references/lanes/ui.md` | 38 → 38 | 38 | 2601 → 2602 | | `references/review-checklist.md` | 77 → 77 | 77 | 6318 → 6321 | The new text in `contract-review.md` needs one line more than the old face list. That line is paid by deleting content in the same file: the second spelled-out copy of `node scripts/pm/record-recognisers.mjs --template` (sentence 3). The full command is still spelled once, eleven lines above. No line was re-wrapped to free space. `review-checklist.md` pays for its new line the same way (sentence 7). Every added line is at most 119 bytes. ## Local gates Run at head `27e976d73`, after the review-round-1 commit. The list was derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (18 commands, no paths passed; `check:required-contexts` joined the list with `review-checklist.md`). The `--ran` reconciliation over the exit-coded record printed: 「18 derived famil(ies) accounted for — 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none of them is 3)」. | command | exit | |:--|:--| | `node scripts/check-closing-keyword-parity.mjs` (and `--self-test`) | 0, 0 | | `node scripts/check-comment-mask-corpus.mjs` | 0 | | `node scripts/pm/check-harness-current.mjs --self-test` | 0 | | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 0 (see note) | | `pnpm check:agent-test-spelling` | 0 | | `pnpm check:cross-package-test-inputs` | 0 | | `pnpm check:doc-authoring` | 0 | | `pnpm check:driver-memory-census` | 0 | | `pnpm check:gitlink-declared` | 0 | | `pnpm check:nul-bytes` | 0 | | `pnpm check:pm-governed-merges` | 0 | | `pnpm check:pm-skill-id-lint` | 0, 「34 file(s) clean」 | | `pnpm check:pm-skill-ratchet` | 0, the five files at 40/60, 101/101, 183/183, 38/38, 77/77 | | `pnpm check:refd-timer-probe` | 0 | | `pnpm check:required-contexts` | 0 | | `pnpm check:skill-frame-sync` | 0 | | `pnpm check:watch-hint-literal` | 0 | Note: `check:doc-formula-expressions` first exited 3 (PREREQUISITE NOT MET: `@objectstack/formula` and `@objectstack/lint` were not built in the fresh worktree), so that first run measured nothing. After `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2` under the shared verify lock (VERDICT command-exit 0), it ran with exit 0 and a 58-case self-test. The same happened at `27e976d73` in the recreated worktree: first run exit 3, rebuild (a turbo cache hit), rerun exit 0. A raw control-byte scan over the four files found nothing. The full farm is CI's. No changeset: the diff publishes nothing (`.claude/**` only), so the PR takes `skip-changeset`. ## Acceptance notes - Resolved in review round 1: the ACCEPT path now names the prose check (sentence 7). `execution-duties.md` 〈复核〉 was not touched again, because its 「核对清单结论」 already carries the checklist into the ACCEPT. - The card's rationale cites a changeset claim re-read that asks authors to re-read pending changeset bodies. That facility is objectui's (`.github/workflows/changeset-presence.yml`, `scripts/render-changeset-claims-comment.mjs` there), and this repository's tree has 0 hits for it. On objectstack, the ACCEPT check is the only prose control before a release consumes the changeset. Noted, not filed; no carrier. - Landing: Tier S (`.claude/**` only). The dev does not ready, queue or arm this PR. The owning seat lands it after an isolated `CONTRACT_REVIEW_TIER` review of record PASS on the current head, with every check green. ## 维护者速读(草稿) **改了什么**:PM 规则里「哪些改动必须另起一个顶档 agent 做隔离契约复核」的清单,从五处缩到三处契约面:`Clause-②: yes` 申报、`packages/spec/src/**`(非测试)、受管规则文本(含 `.claude/**`)。changeset/CHANGELOG 与 `content/docs/**`、`apps/docs/**` 的散文改由派发席在 ACCEPT 时按本席档逐句对照 diff 核对,并在 ACCEPT 里点名核过的句子,不再另起 agent。另在 ACCEPT 复核清单(`review-checklist.md`)补一行,写明散文面逐句核、ACCEPT 点名、不起子代理。只动 `.claude/skills/pm-dispatch/references/` 下 5 个文件共 11 行,每个文件行数不变。 **为什么改**:卡片实测 objectui 最近 40 个合并 PR 中有 30 个带发布 changeset,按旧规则每个都要一次隔离顶档复核;单次约 23.6 万 token,那一例只多抓出一句散文偏松。您已裁 A(「我已经同意了,不需要严格的规则」),并对三个分叉答「同意,你负责派发。」。 **风险与代价(含回滚)**:契约面(条款②申报、spec、受管面)照旧走隔离顶档复核;入队闸门只读条款②两肢,本 PR 不碰。两条「同 head 达档 PASS 即确认」的例外条款原样保留。代价是散文核对的质量落在派发席本档,靠 ACCEPT 逐句点名留痕。回滚 = revert 本 PR,不牵连任何脚本或数据。 **席位意见**: **你要做的**:无需操作。本 PR 属 Tier S,由席位在隔离达档复核 PASS 后落地;对措辞有异议请在本 PR 留言。 --- _Generated by [Claude Code](https://claude.ai/code/session_016tKoy8NJa35Yih1FdzrVmn)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 55012df commit 5e5ce48

5 files changed

Lines changed: 11 additions & 11 deletions

File tree

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
## 复核归属与资格(按面)
66

7-
- 欠不欠按面判 ⛔ 不按车道:diff 碰下列任一面即欠达档复核,交付后当轮完成。
8-
- 复核面 = 出货给用户或 agent 的五处:`content/docs/**`、`apps/docs/**`、CHANGELOG/`.changeset` 散文。
9-
- 加已发布 schema(`packages/spec/src/**` 非测试)与 governed 规则文本(统一定义见 SKILL.md)。
7+
- 欠不欠按面判 ⛔ 不按车道:diff 或认领申报碰下列任一面即欠达档复核,交付后当轮完成。
8+
- 复核面 = 契约三面:`Clause-②: yes` 申报、已发布 schema(`packages/spec/src/**` 非测试)、governed
9+
规则文本(统一定义见 SKILL.md);`.changeset`/CHANGELOG、`content/docs/**`、`apps/docs/**` 散文面
10+
⛔ 不在其列:派发席按本席档在 ACCEPT 逐句对照 diff 核,ACCEPT 点名所核句。
1011
- 已发布面以包的 `exports` 映射为准:从入口类型图不可达、且 `exports` 不可寻址的 `.d.ts` 是
1112
出货字节,⛔ 不是已发布接受集,改它不触发 `Clause-②: yes`;legacy node10 深引用在契约之外。
12-
- 五面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。
13+
- 三面皆不碰 ⇒ CI 加席位自读 ⛔ 不起第二个 agent;谁跑 = 派发席,达档者席内审。
1314
- 复核记录 = 一条评论落 PR 或卡,席内与子代理同形;散文、dev 自评、`os-dev-report` 恒不算。
1415
- 同形 = `## Contract review` 题头、所审 head sha 独占码段、①②③ 逐项、独立性对、PASS/FAIL。
1516
- 同形含首行 `Served-tier:`:值写常量名 `CONTRACT_REVIEW_TIER`;无此行不成裁决,
@@ -23,8 +24,7 @@
2324
- 简报从 `node scripts/pm/record-recognisers.mjs --brief-template` 起稿:
2425
只读条款与输入集内建,⛔ 不删 ⛔ 行。
2526
- 隔离复核子代理暂存全写按所审 PR 命名的 `<scratchpad>/pr-<n>/`,⛔ 不读非本轮自写的暂存。
26-
- 独立性对:`Implemented-by:`/`Reviewed-by:` 取值见
27-
`node scripts/pm/record-recognisers.mjs --template`;子代理记采纳它的席位。
27+
- 独立性对:`Implemented-by:`/`Reviewed-by:` 取值同见 `--template`;子代理记采纳它的席位。
2828
- 轮次报告设复审清单专节,形状与代裁清单同为强制审计。
2929
- 落地前检两条,过则 Tier S 入队、Tier H 等人批:① 达档条款②复核 PASS 在案(同形记录)。
3030
- 例外:纯重生成 head 后移原记录继续管;判据机读已提交树;PR 落 `Regen-provenance:` 行。

‎.claude/skills/pm-dispatch/references/execution-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
- 机械放宽判别门禁落地前,入队前的席内契约复核是方向自述的补偿控制。
104104
- 豁免够不到的地板只有维护者裁决能设。
105105
- 席位档策略:skills 车道外的执行席与分诊席默认判断档会话。
106-
- 条款②自审资格按车道:spec 与 skills 席达档席内审;未达档 ⛔ 不自审,起隔离达档子代理。
106+
- 契约三面自审资格按车道:spec/skills 席达档席内审;未达档 ⛔ 不自审,起隔离达档子代理。
107107
- 降档出口两条:额度耗尽豁免(达档实测不可用才落默认判断档,⛔ 不再往下)与主动预降。
108108
- 额度墙只向下(降档或降并发)⛔ 永不向上;临时偏离记座位贴带结束条件,逐次巡检重读。
109109
- 降档的档位与理由记入认领评论 Container & model 行;档位逐次派发显式传参,永不省略。

‎.claude/skills/pm-dispatch/references/landing-operations.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- `--tier` 嫌疑行是提示非裁定;双肢命中任一 ⇒ 无达档条款②复核 PASS 在案 ⛔ 禁止入队。
1010
- 路径肢 = diff 触及契约面 `packages/spec/src/**` 非测试,含 error-code-ledger、`*.zod.ts` 契约 schema。
1111
- 声明肢 = 认领评论声明 `Clause-②: yes`,与路径无关;错误的 `no` 是可审计的假申报。
12-
- 交付后复核按面欠 ⛔ 不按车道(五面见 `references/contract-review.md`);双肢命中即 spec 车道。
12+
- 交付后复核按面欠 ⛔ 不按车道(三面见 `references/contract-review.md`);双肢命中即 spec 车道。
1313
- 子代理起不来 ⇒ 复核缺席,PR 带 `needs:contract-review` 留 draft 队列外;旁路仅维护者逐次亲审
1414
- PASS ⇒ ready、auto-merge;FAIL ⇒ 补丁轮;⛔ 免复核不放行。
1515
- DELIBERATE CORRECTION 红(`check-empty-changeset`):同 head 达档复核 PASS 记录即确认,⛔ 不等维护者。

‎.claude/skills/pm-dispatch/references/lanes/ui.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@
3535
- 零读数恒配点亮的正控,且正控须经被测机制本身生效;本仓 search 假零,查重只引命中。
3636
- 脚本能滚动不证明用户能滚动:可达性断言必须驱动真实输入管道。
3737
- 落地验证按内容,正控须在合并前证明会响,⛔ 不按 sha 判已落地。
38-
- 条款②复核本席适用:按面欠达档复核记录,落 PR 或卡,归属与资格见 `../contract-review.md`。
38+
- 契约三面复核本席适用:按面欠达档记录落 PR 或卡,散文面归 ACCEPT,见 `../contract-review.md`。

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
## 范围与 changeset
1717

1818
- 三条判据:无 `content/docs/releases/` 改动、用户可见改动有 changeset、无与卡无关的文件。
19+
- changeset/CHANGELOG、`content/docs/**`、`apps/docs/**`:逐句核 diff,ACCEPT 点名所核句,⛔ 不起子代理。
1920
- Tests/docs-only 按仓库分流:本仓库走 `skip-changeset` 标签,⛔ 不走空 changeset。
2021
- 空 changeset 在本仓库滞留发布;含读者可见生成产物时 dev 改选 changeset 亦对。
2122
- dev 挂 `skip-changeset` 遭分类器拒 ⇒ 席位自核 tests/docs-only 即自挂,评论写依据是席位复核。
@@ -45,8 +46,7 @@
4546
- 收敛期转红走补丁轮续派原 dev,⛔ 不作 REWORK 的理由;重量级卡可在派发令写本单等 CI。
4647
- 每个门禁读数先钉到 PR 当前 head:比对 run `head_sha` 与 `head.sha`,不一致的双向都不入账。
4748
- ⛔ 非当前 head 上的 `cancelled` 零动作、永不重跑:新推送自带全套 run。
48-
- dev 本地并集同样先钉 head:最后一次提交之后跑,`git rev-parse --short HEAD` 抄进报告与正文。
49-
- 与 PR 当前 `head.sha` 比一次,对不上即死树读数、双向都不入账;没抄 ⇒ 按没有读数处理。
49+
- dev 本地并集钉 head:所抄 `git rev-parse --short HEAD` 不符 PR `head.sha` 或没抄 ⇒ 双向都不入账。
5050
- 复核后又推提交而 HEAD 未动 ⇒ 补跑并集(至少棘轮族)再更新报告。
5151

5252
## 断言与收益

0 commit comments

Comments
 (0)