Repository navigation
Commit 5e5ce48
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
- lanes
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | | - | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
26 | | - | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
| 106 | + | |
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
48 | | - | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| |||
0 commit comments