Skip to content

Commit 628e55d

Browse files
huangyiireneclaude
andauthored
pm: retire the needs:contract-review label from the tree (ruling B step ③) (#19737)
Part of #19061 ## 维护者速读(草稿) **改了什么**:按裁决记录 5770886272(B 字母,第 ③ 步)把 `needs:contract-review` 标签从代码树里退役。`ensure-pm-labels.sh` 不再创建它;队列守卫 `check-governed-queue-guard.mjs` 的标签腿(退出码 6/7、标签读取、载体判定与渲染、#17040 电池)整段删除;`check-half-states.mjs` 里围绕该标签巡查的五行(H31/H35/H51/H53/H61)连同扫描点、汇总句、计数键、分带登记与自测一起删除,仓库级 issue-event 窗口读取随之消失;`check-changeset-no-major.mjs` 只读 PR 正文的 `Clause-②:` 行,标签载体轴与对 `check-half-states.mjs` 的 import 删除;`.claude/**`、`AGENTS.md`、两个 workflow 注释里叫 agent 去挂/读/等这个标签、`--pair`、双载体或降档保险丝的句子改成只认 `## Contract review` 记录。每个受管 PR 一条记录的契约原样保留。 **为什么改**:维护者原话「不需要 AI 不能自审契约改动 这种」与「我们系统开发了太多无用的门禁,反而在浪费时间」;裁决 B 把三层(标签 + `--pair` + 记录)收成一层,只留记录给队列守卫读。第 ① 步(抽出 `readClause2Line`)和第 ② 步(规则文本)已落地;这是最后一步。 **风险与代价(含回滚)**:队列守卫少一条腿,`groupExitCode` 变成两腿(governed → size),退出码 6/7 从登记表移除;半态巡查少五个家族(自测 5170 → 4897 例,`gate` 分带保留但暂无成员);changeset 门禁不再把标签当声明载体,以后没写 `Clause-②:` 行的 PR 读作未声明。回滚 = revert 本 PR 的四个提交(每类一个提交,可单独回退)。⛔ GitHub 上的标签对象本 PR 不删,由席位在合并后、确认没有开着的卡或 PR 还挂着它时移除。一处残留:`check-clause2-carriers.mjs` 把该标签常量改为文件内局部常量——它的 `--pair` 扫描已被裁决退役、无人运行,但队列守卫仍懒加载它的记录识别器与 `--template`,所以文件还不能删;把识别器抽成小模块后整文件连同这个常量一起删,是下一步(见下方 Remainder)。 **席位意见**:**建议批准并合并。** 这是裁决 5770886272(B)的最后一步,做的是「减」:标签的创建者、读者、巡查行、changeset 门禁的标签载体轴和九处叫 agent 去挂/读/等标签的句子全部退休,净 −2650 行;裁决要保留的东西一样没少 —— 队列守卫仍先看授权批准、再看 `## Contract review` 记录(席位在头上逐段核过守卫的两腿与半态巡查保留的记录读取器),`AGENTS.md` :275–:281 把 Tier S 写成只认记录。四个自测(279 / 4897 / 339 / 1140 例)与十二个门禁族在席位工作树上重跑全绿。一处残留是量出来的而非选的:`check-clause2-carriers.mjs` 还不能删,因为队列守卫懒加载它的六个记录识别器与 `--template`;dev 给它留了本文件内的退休常量并禁止新引用。席位把「抽出识别器、整文件删除」定为 #19061 的第 ④ 步(合并后由 `Release:` 记在卡上,不另立卡),所以本 PR 首行是 `Part of`。合并后席位删除 GitHub 上的标签对象、关闭因它而起的 objectui#9867,并放行压在这些文件后面的 #19146 / #19129 ② / #19244 ② ③。复核记录:PR 评论 5779366929(PASS,在席按服务档渲染);ACCEPT 在卡 #19061。CI 读数:33 latest-per-name check runs — 24 success, 9 skipped, 0 in progress, 0 other (the seat's read at 00:13 UTC of this date; the lint-and-repo-gates job success)。 **你要做的**:本 PR 是 Tier H(`AGENTS.md` 在登记表上),草稿状态由您手动合并;合并后席位移除 GitHub 标签对象,并为「抽出记录识别器、删除 `check-clause2-carriers.mjs`」立单。 ## Summary Ruling record 5770886272 on #19061 (letter B), step ③: the `needs:contract-review` label leaves the tree. Every mechanism that created, read, hung, cleared or expected it is retired; the one `## Contract review` record per governed PR — the thing the queue guard reads to release `.claude/**` in the merge group — stays exactly as it was. `Part of` rather than `Fixes`: one measured remainder is named below. ## Per-path disposition (18 label sites on the base, plus the prose riders) | path | class | what changed | |---|---|---| | `scripts/pm/ensure-pm-labels.sh` | CODE | the `needs:contract-review` row (comment block + `gh label create`) removed; the pointer in the `repo:*` block reworded. The GitHub label object is NOT deleted here. | | `scripts/pm/check-governed-queue-guard.mjs` | CODE | the carrier leg retired: `EXIT_REFUSED_CARRIER` (6) and `EXIT_REFUSED_CARRIER_UNREADABLE` (7), `CONTRACT_REVIEW_LABEL`, `CARRIER_LEG_NAME`, `carrierVerdict`, `runCarrierGuard`, `renderCarrierVerdict`, `makeLabelReader`, the main-dispatch call, the exit table rows, the header's SECOND-leg section; `groupExitCode` is two-legged (governed, size); `carrierPullsInGroup` (still read by the size leg) renamed `queuedPullsInGroup`; the module-eval-cycle explanation moved onto the surviving `REVIEW_OF_RECORD_LOCATION` mirror; the `#17040` battery (39 cases) removed, floor 24 → 23, its enumeration cases and the two zero-cost-clear scoping pins re-homed in the `#19036` size battery; the Tier S prescriptions stop naming `--pair N`. | | `scripts/pm/check-half-states.mjs` | CODE | H31 (carrier split), H35 (gate-label removal events, with `GATE_SEMANTIC_LABELS`, `isGateSemanticLabel`, the event-window constants and `listRecentIssueEvents`), H51 (verdict without label stroke), H53 (carrier without increment) and H61 (landed carrier) removed: rows, sweep sites, summary clauses and count keys, band entries and self-test sections; `CONTRACT_REVIEW_LABEL` removed. KEPT: `bindingClosesCard`, the record readers (`CONTRACT_REVIEW_HEADING_MARKER`, `H51_SHA_MIN_HEX`, `H51_SHA_SPAN`, `contractReviewHeadMatch`, `latestContractReviewOnHead`) with their pins re-homed under a "record readers" section. The `#13947` ledger fixtures move from H31 to a `stall` family (H12); the `gate` band stays declared, rank 0, with no live member; the H52 reservation pin now asserts the spent number is never re-used. | | `scripts/check-changeset-no-major.mjs` | CODE | the label carrier axis retired: `declarationFromPullRequest` reads the `Clause-②:` body line only (no `labels` read, no `carrier` field), `judgeLevel`/`renderLevel` drop `carrier`/`carrierUnread` and every sentence that named the label; the `check-half-states.mjs` import goes (the gate's first-party closure is now `clause2-line.mjs` alone); the `#17229` battery (25 cases) removed, floor 20 → 19; the payload-snapshot docblock rewritten around the body. | | `scripts/pm/check-clause2-carriers.mjs` | CODE (remainder) | NOT deleted — measured: `check-governed-queue-guard.mjs` lazily imports six record recognisers from it (`locateReviewOfRecord`, `deliveredCardNumber`, `servedTierStands`, `isModelIdentifierToken`, `REVIEW_OF_RECORD_THREADS`, `REVIEW_OF_RECORD_LOCATION`) and `contract-review.md` points at its `--template`, so the ruling's deletion precondition ("nothing but the extracted module is imported") does not hold on this base. Its two imports of the retired symbols become a LOCAL `CONTRACT_REVIEW_LABEL` / `isGateSemanticLabel`, docblocked as retired and import-forbidden; nothing else in it moves. This is the one CODE site still spelling the label. | | `scripts/pm/check-widening-tells.mjs` | PROSE in code | no label leg; the design-note sentence reworded ("a review-gate label"); the dated 2026-09-16 census line at :673 is HISTORY and stays. | | `scripts/pm/check-label-desc-cap.mjs` | PROSE in code | the 97-char/101-byte specimen sentence stops naming the label; the self-test keeps the description string as a fixture (renamed case). Floor `MIN_DESCRIPTIONS` 12 vs 38 found — untouched. | | `scripts/pm/check-skill-line-ratchet.mjs` | HISTORY + rows | the two raise-provenance comments naming the label stay (they explain past ceilings); rows lowered: `os-dev.md` 403 → 402, `state-machine.md` 42 → 41 (`AGENTS.md` stays 1116 — the paragraph re-wrapped to the same count). | | `scripts/pm/dispatch-gates.mjs` | PROSE in code | the `CONTRACT_REVIEW_TIER` docblock no longer names the re-review sub-round, the fuse or the label bullets; the rulebook pointer goes to `references/contract-review.md`. | | `scripts/pm/clause2-line.mjs` | PROSE in code | the "STEP ① … nothing else has landed yet" paragraph rewritten to the landed state; the provenance sentence at :11 and the measured incident at :307 stay. | | `scripts/pm/check-governed-merges.mjs` | CODE strings | Tier S landing prose and the `--test` rendering stop prescribing `--pair N`; two self-test pins flipped to assert its absence; the mirror docblock points at `REVIEW_OF_RECORD_LOCATION`. | | `scripts/pm/post-stamped.mjs` | CODE string | the near-miss row stops prescribing `--pair`. | | `.github/workflows/lint.yml` | PROSE | the desc-cap specimen comment and the clause-② self-test step comment (the step itself stays: it keeps the recognisers loadable). | | `.github/workflows/pr-automation.yml` | PROSE | the WHICH LEVEL prose names the one carrier left. | | `.claude/agents/os-dev.md` :303 | PROSE | line deleted. | | `.claude/skills/pm-dispatch/SKILL.md` :769 | PROSE | 三职 = 契约复核记录事后审计 … | | `references/lanes/director.md` :27/:31/:33/:35 | PROSE | duty one audits the records; 落地前检③ → ②; handoff by `pm:*` label, record stays on PR or card. | | `references/lanes/ui.md` :38 | PROSE | record-only contract, pointer to `../contract-review.md`. | | `references/state-machine.md` :8/:10 | PROSE | H29/H30 authority; the card-side-first line deleted. | | `references/dispatch-runbook.md` :161 | PROSE | 独立性件 → 达档复核记录. | | `references/platform-readings.md` :26 | PROSE | the label row generalised to the still-true `mergeable_state: blocked` reading. | | `references/contract-review.md` :13/:19 | PROSE (unchanged) | the `--template` pointers stay valid because the script stays; they follow the file at the extraction step. | | `AGENTS.md` :278 | PROSE | Prime Directive #14 Tier S: the `--pair N` clause removed, paragraph re-wrapped at the 120-byte budget. | | `.changeset/console-87af769e9a3e.md`, `docs/adr/0131-…`, `docs/audits/**` | HISTORY | untouched. | ## What stays, on purpose - One `## Contract review` record per governed PR, `Served-tier:` line, the queue guard's Tier S leg and its lazy import of the recognisers — ruling B, not A. - `CONTRACT_REVIEW_TIER` in `dispatch-gates.mjs` (path-mandate role) and `readClause2Line` in `clause2-line.mjs` (step ①). - The GitHub label object: the seat removes it after MERGED once no open card or PR carries it. ## Remainder (why `Part of`) `check-clause2-carriers.mjs` still spells the label in a local constant because its deletion — the ruling's own end state for the file — waits on extracting the six record recognisers and `--template` into a module the queue guard can lazily import (a sibling of step ①, roughly the 2,700-3,000 to 4,300 line band of that file plus its record batteries). Retiring the C1/C3/gate-history rows inside a file that is slated for deletion would rewire the retired `--pair` sweep for nothing. The seat files that extraction as its own card; with it the last label site goes and `objectui#9867` falls moot. ## Tests All on the merged head `8671754c9` (base `106d4c8dd`, `origin/main` `342808cf5` merged clean, no file overlap), exits captured before any pipe: - `node scripts/pm/check-governed-queue-guard.mjs --self-test` — exit 0 — `✓ check-governed-queue-guard self-test: 279 cases pass` - `node scripts/pm/check-half-states.mjs --self-test` — exit 0 — `✓ check-half-states self-test: 4897 cases pass` (5170 before; batteries H66 182/172 and H67 152/142 each lost one cross-family pin) - `node scripts/check-changeset-no-major.mjs --self-test` — exit 0 — `339 assertions`; `--base origin/main` exit 0 (level axis NOT APPLICABLE with no `pull_request`) - `node scripts/pm/check-clause2-carriers.mjs --self-test` — exit 0 — `1140 cases pass` - `pnpm check:pm-governed-merges` exit 0 · `pnpm check:pm-post-stamped` 596 cases · `pnpm check:pm-dispatch-gates` 1905 cases (748 s) · `pnpm check:pm-widening-tells` 525 cases · `pnpm check:pm-label-desc-cap` self-test + gate (38 descriptions, all ≤100) · `pnpm check:pm-skill-ratchet` exit 0 (`total ceilings down 9 lines`) · `pnpm check:pm-skill-id-lint` 30 files clean · `pnpm check:pm-governed-prose` 6/6 surfaces · `pnpm check:nul-bytes` 9231 files clean · `pnpm check:commit-card-trailers` 5 commits clean - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` derives 84 commands (identical before and after the merge); `--ran` reconciled — run locally: 80 of them; declared to CI: `pnpm --filter @objectstack/lint run check:doc-formula-expressions` (needs the package build), `pnpm check:partof-closing-keyword` (reads the PR body), `pnpm check:pm-expected-skips` (reads the board); `pnpm check:type-check-debt` exit 3 = PREREQUISITE NOT MET (needs the packages build closure; this diff touches no package) — NOT MEASURED. - Narrowed lint: `pnpm exec eslint --no-inline-config --format json` over the 11 touched `.mjs` files — exit 0, 11 files, 0 errors, 0 warnings. Population read from `eslint.config.mjs` (the `**/*.{ts,…,mjs,cjs}` block); the config never enables type-aware linting (`eslint.config.mjs` :326-:328, "no `parserOptions.project`, no typed `@typescript-eslint` rules for ANY file"), so this diff moves no untouched file's verdict; the whole-repo `pnpm lint` is CI's run. - `node scripts/pm/check-harness-current.mjs`: STALE before and after — it compares the shared checkout's HEAD with `origin/main`, which this branch does not move. - `node scripts/pm/check-governed-merges.mjs --pr N`: run after the PR exists (expected GOVERNED, Tier H via `AGENTS.md`); reported on the card. ## Deviations - `check-clause2-carriers.mjs` keeps a local retired-label constant (see Remainder) — the one departure from "the label retired from the tree", measured and named rather than forced. - `pnpm check:type-check-debt` not measured locally (build prerequisite); `pnpm install --frozen-lockfile && pnpm build` after the merge was not run because this diff touches no package and every gate run here reads scripts, workflows or `.claude/**`. ## Acceptance notes - class: b · `scripts/pm/check-widening-tells.mjs` still describes `--pair`'s C5 row as its live consumer (:85, :241, :1338) — that consumer is retired by ruling B; the gate's own self-test is what CI runs. Not touched here (not the label); carrier: the extraction card above. Dedupe words: widening-tells --pair C5 consumer retired. - `scripts/pm/check-expected-skips.mjs` :118 still names `check-clause2-carriers.mjs` as the read ladder it mirrors — true while the file exists; follows the extraction. --- _Generated by [Claude Code](https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc)_ --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3f9e2ea commit 628e55d

22 files changed

Lines changed: 405 additions & 3055 deletions

‎.claude/agents/os-dev.md‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ model: opus
301301
- PR 改到已有的 `.changeset/*.md`:⛔ 永不打 `skip-changeset`,门禁红着是对的,确认走 PR 文字。
302302
- objectstack:标签是真实机制,打标签是你的默认步骤,PR 一开出就打;派发词可收窄或禁写。
303303
- 范围 = 派发词点名的标签 + 上文判据下的 `skip-changeset`;禁写或交集为空 ⇒ 零写并报告。
304-
- `needs:contract-review` 归席位,⛔ 不挂不摘不等;报 PR 上有无与 `--pair PR-NUMBER` 退出码作读数。
305304
- 写恒经 `scripts/pm/label-write.mjs`:取现集、加法 POST、回读比 union、缺者重挂一次并报告。
306305
- 读回只检测剥除防不了(size-labeler 整组 PUT),门标签被剥恰成绿灯;加法写同样必要不充分。
307306
- 关此步骤的是读回不是写入;读回只验写落了,验不出有门在读:幻影门标签读回照样成功。

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
766766
- `AskUserQuestion` 只是在场加速器:仅当维护者在本会话 ~30 分钟内有过人类输入才可发。
767767
- 每问必带推荐项,被 Skip 或长挂即转卡通道,⛔ 不重弹。
768768
- 项目总监席:维护者在所在仓召唤 `/pm-dispatch director`;⛔ 无 Routine/cron;未回字 = 不在 = 停。
769-
- 三职 = `needs:contract-review` 事后审计、决裁勤务、维护者动作台账。
769+
- 三职 = 契约复核记录事后审计、决裁勤务、维护者动作台账。
770770
- 每场召唤把带席内 ACCEPT 的受管草稿呈为一批 ≤5 行决裁;批准与合并仍是维护者的点击。
771771
- 总监席档位由维护者按项目人工定,每场记入摘要台账;⛔ 无档位硬门、无免档整理态。
772772
- 总监席是唯一裁决者:决策箱、代裁与一类自裁只出自本席,⛔ 无子代理无自述。

‎.claude/skills/pm-dispatch/references/dispatch-runbook.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158

159159
- 衍生 sub-issue:认领席同笔写父卡域与优先级、附查重词后派发;父卡 checklist 评论记一行。
160160
- 无主阻塞项:只做 `Blocked-by:` 点名的那一张,做完即回,⛔ 不顺手接第二张。
161-
- 无主阻塞项的契约面(含 `packages/spec`)走 `contract-review.md` 独立性件的隔离达档复核。
161+
- 无主阻塞项的契约面(含 `packages/spec`)按 `contract-review.md` 欠达档复核记录。
162162
- 在飞阻塞项:等待者在阻塞卡留一行点名自卡;父卡 p0/p1 ⇒ 阻塞卡同笔升同级,沿链重复。
163163

164164
## 停摆复位梯度

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424
- 创业阶段不渐进:废弃别名与能力退役默认立即退休,无窗口、无双拼写宽限。
2525
- 一次裁清:子问题、分叉与执行参数(字母、车道、级别)同笔裁定,⛔ 不留 dev 另立决策卡。
2626

27-
## 职责一:`needs:contract-review` 事后审计与抽查(可选)
27+
## 职责一:契约复核记录事后审计与抽查(可选)
2828

2929
- 本职是审计位,非放行链:放行常设归派发席席内复核,归属与全链见 `../contract-review.md`。
30-
- 召唤时枚举载体(卡与 PR 两侧)与近期落地的条款② PR,查复核质量与漏网。
30+
- 召唤时枚举近期落地的受管 PR 及其 `## Contract review` 记录,查复核质量与漏网。
3131
- 非机械 CI 红交回具名读者;机械红可接手,经派发 dev 执行。
3232
- 处理三分支之一,收尾 PASS 且工已完 ⇒ 跟到合并为止。
33-
- 非受管 code PR 走清标即落地全链;受管面两层落地见 `../contract-review.md` 落地前检③。
33+
- 非受管 code PR 绿加 ACCEPT 即入队落地;受管面两层落地见 `../contract-review.md` 落地前检②。
3434
- 到合并 = 推进到就绪并点名等待,⛔ 不代维护者合并。
35-
- 之二,大的错误 FAIL 或 REWORK ⇒ 改标签即交接,端态按 `../contract-review.md` 载体纪律。
35+
- 之二,大的错误 FAIL 或 REWORK ⇒ 改 `pm:*` 标签即交接,记录留在 PR 或卡上。
3636
- ⛔ 散文点名不是交接:标签才是收件箱,散文对候选查询与 sweep 全不可见。
3737
- 之三,卡在决策卡 BLOCKED ⇒ ⛔ 不擅断:并入决裁批次,按基本原则格式与维护者讨论。
3838

‎.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-
- 条款②复核本席适用:默认判断档自审加门禁,标照挂;豁免只有独立性件与降档保险丝。
38+
- 条款②复核本席适用:按面欠达档复核记录,落 PR 或卡,归属与资格见 `../contract-review.md`。

‎.claude/skills/pm-dispatch/references/platform-readings.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
- `list_pull_requests` 的 `fields` 请求 `merged_by` 不返回该字段 ⇒ 字段缺席不是值读数。
2424
- `mergeable_state` 惰性计算,`unknown` 不是读数 —— 挂 unknown 等于挂在可能脏的头上。
2525
- `dirty` 即入队否决(冲突对象是当前 main);draft PR 照答 `clean`/`blocked`/`unknown`,不答 `draft`。
26-
- `needs:contract-review` 是合并闸:实测 `blocked` 而 `mergeable: true`,无标签同形兄弟回 `clean`。
26+
- `mergeable_state: blocked` 且 `mergeable: true` = 规则或必需检查在挡,非冲突;无阻兄弟回 `clean`。
2727
- ready 翻转实测两序列 `clean→blocked→clean` 与 `blocked→unstable→clean`;`unstable` 瞬态非失败。
2828
- `unstable` 可源自 check-runs 看不见的 commit STATUS(如 `Vercel`)⇒ ③ 另读 `/commits/{sha}/status`。
2929
- 零 legacy status 的仓恒答空集默认值 `pending`+`total_count: 0`,⛔ 非门禁读数,门禁读 check-runs。

‎.claude/skills/pm-dispatch/references/state-machine.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
## 跨状态通则
66

77
- 六态 = `pm:{queue,dispatched,blocked,on-hold,awaiting-maintainer}` 加 `needs-user-decision`。
8-
- 六态 ONE-OF 的成因恒是半写的转换;判定以 `check-half-states.mjs` 的 H29/H30/H31 为权威。
8+
- 六态 ONE-OF 的成因恒是半写的转换;判定以 `check-half-states.mjs` 的 H29/H30 为权威。
99
- 生成物不分叉:`skills/**` 生成器产物跑 `check-governed-merges.mjs --test`,⛔ 不按路径手判。
10-
- `needs:contract-review` 卡侧先挂而 PR 尚不存在是合法中间态,⛔ 不读作半写。
1110
- 交接即标签:只写交接评论而不同笔挂标 = 空交接,收件箱只认标签。
1211

1312
## `pm:on-hold`

‎.github/workflows/lint.yml‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -916,9 +916,9 @@ jobs:
916916
# over-long -d means the label is never created on a repo that lacks it
917917
# and a rerun can never repair it. Headroom is thin (one description sits
918918
# at exactly 100), and the only previous enforcement was the author
919-
# counting by hand. Measured in characters, never bytes: the live
920-
# needs:contract-review description is 97 characters / 101 bytes, so a
921-
# byte-length guard would red a label GitHub accepts. Unconditional, like
919+
# counting by hand. Measured in characters, never bytes: the specimen
920+
# that fixed the measure was 97 characters / 101 bytes, so a byte-length
921+
# guard would red a label GitHub accepts. Unconditional, like
922922
# the other self-tested gates above.
923923
- name: PM label description cap
924924
run: pnpm check:pm-label-desc-cap
@@ -1254,16 +1254,15 @@ jobs:
12541254
# else's pair is a fact about the board, not about the PR that happens to
12551255
# run CI next, and failing that PR would punish the wrong actor.
12561256
#
1257-
# ⛔ Do not "promote" the live sweep into this step. The script's own
1258-
# `--pair <pr>` mode is the per-PR predicate, and it is a PRE-ARM tool a
1259-
# seat runs against its own pair — deliberately not a merge gate, because
1260-
# a new blocking context over board state is a required-set change and
1261-
# the required set is the maintainer's.
1257+
# ⛔ Do not "promote" the live sweep into this step. The script's `--pair`
1258+
# landing pre-check is retired (ruling record 5770886272 on #19061) and
1259+
# nothing runs it; the file stays only because the Governed Surface Queue
1260+
# Guard lazily imports its contract-review record recognisers and
1261+
# `--template`, and this self-test is what keeps those loadable.
12621262
#
12631263
# The self-test is offline and imports `check-half-states.mjs` for the
1264-
# label constant, the `prDeliversCard` delivery relation and the shared
1265-
# PREREQUISITE-NOT-MET exit code — one source for each, so this checker
1266-
# and H31 cannot come to disagree about which PR delivers which card.
1264+
# `prDeliversCard` delivery relation and the shared PREREQUISITE-NOT-MET
1265+
# exit code — one source for each.
12671266
- name: Clause-② carrier checker self-test
12681267
run: pnpm check:pm-clause2-carriers
12691268

‎.github/workflows/pr-automation.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,8 +784,8 @@ jobs:
784784
WHAT THE AXIS DOES NOT JUDGE, in its own words: "WHICH of the
785785
packages above received that widening is NOT something this gate
786786
can read, and it does not claim to. Clause ② is declared ONCE, FOR
787-
THE PR" -- neither the carrier label nor the declaration line in
788-
the PR body names a package. The axis cross-checks a declaration
787+
THE PR" -- the declaration line in the PR body names no package.
788+
The axis cross-checks a declaration
789789
against the levels; it never reads the diff to find the act.
790790
Judging the act is still yours, this paragraph is still where the
791791
rule lives, and everything in it the axis does not reach is still

‎AGENTS.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,12 @@ localStorage / auth gotchas.
275275
spent once per PR — the OWNING seat then lands it, later pushes included; the director seat requests the word as
276276
ONE batch of at most five rows, and the click stays the maintainer's. **Tier S** (席内达档复核落地: all of
277277
`.claude/**`): those four lift once the PR thread or its card carries a `## Contract review` record for the PR's
278-
current head with `Served-tier: CONTRACT_REVIEW_TIER` and a PASS verdict, `check-clause2-carriers.mjs --pair N`
279-
reads 0 on its definite rows (⛔ never C5) and every check is green — the owning seat then lands it through the
280-
queue; the post-merge audit is the compensating control. A PR whose only governed paths are register rows the queue
281-
leg regenerates byte-exact clears with zero approvals — an uncertified recompute, drift or a hand-authored sibling
282-
keeps it governed. ⛔ **No agent seat submits an approving review on a governed-surface PR, under any account** —
283-
an authorized account is agent-operated too; "CI is green" carries no information about a governance change.
278+
current head with `Served-tier: CONTRACT_REVIEW_TIER` and a PASS verdict and every check is green — the owning
279+
seat then lands it through the queue; the post-merge audit is the compensating control. A PR whose only governed
280+
paths are register rows the queue leg regenerates byte-exact clears with zero approvals — an uncertified
281+
recompute, drift or a hand-authored sibling keeps it governed. ⛔ **No agent seat submits an approving review on a
282+
governed-surface PR, under any account** — an authorized account is agent-operated too; "CI is green" carries no
283+
information about a governance change.
284284

285285
**Already armed or queued when you read this?** Convert it back to **draft** AND disable auto-merge — draft is
286286
what removes queue membership, disabling alone drops only the arming — then confirm from the remote that it is in

0 commit comments

Comments
 (0)