Skip to content

Commit a81a9d6

Browse files
claude[bot]claude
andauthored
docs(pm,agents,checklist-test): four rules-layer lines catch up with lock 1, the two-tier landing and ruling C (#18119) (#18182)
Fixes #18119 **Governed rules layer** — `.claude/skills/pm-dispatch/SKILL.md` + `AGENTS.md` + `.claude/skills/checklist-test/SKILL.md`. This PR opens as DRAFT and draft is its finished state: it waits for an authorized APPROVED review by an account in `GOVERNED_APPROVERS`, after which the claiming seat lands it (Prime Directive 14; ruling C, maintainer verbatim, untranslated: 「C. approve 后不管后续改动都由席位落地:」, recorded on #17971). Never ready, never queued, never auto-merge, and no seat approves it under any account. Base `origin/main` `fffe3e5e7f` (fetched 2026-09-14T11:14Z); this branch `claude/issue-18119-rules-layer-four-lines` at `6dc9ac3e52`, one commit, three files, net 0 lines in each (`git diff --numstat`: 1/1 · 3/3 · 3/3). ## What changed — seven equal-line edits, no other line moves Every rewritten line stays within the enforced 120-byte cap (`MAX_LINE_BYTES = 120` in `scripts/pm/check-skill-line-ratchet.mjs`); byte widths after each row. | File | Line | Before | After | |---|---|---|---| | pm-dispatch `SKILL.md` | 378 | ``- ⛔ `issue_write` 会替换标签集并清空未传字段:写入时必须回传 `assignees`。`` (96 B) | ``- 标签/assignee 写恒经 `scripts/pm/label-write.mjs`(四步、回读);⛔ 永不 MCP `issue_write`(锁 1 已拒)。`` (119 B) | | pm-dispatch `SKILL.md` | 615 | `- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人合清单,随合并或撤回判决离开。` (116 B) | `- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人批清单,随获批或撤回判决离开。` (116 B) | | pm-dispatch `SKILL.md` | 626 | `- 规则层四件套等人合;事实层 PR(受管路径全在该目录)经席内达档复核后 ready → 入队。` (115 B) | `- 规则层四件套等人批;事实层 PR(受管路径全在该目录)经席内达档复核后 ready → 入队。` (115 B) | | `AGENTS.md` (PD 14) | 273 | `uncertified recompute, drift or a hand-authored sibling keeps it governed. Unapproved, the bypass direct merge` (114 B) | `uncertified recompute, drift or a hand-authored sibling keeps it governed. Unapproved, no seat lands it: the` (112 B) | | `AGENTS.md` (PD 14) | 274 | `(人工直合) is the only landing. **Landing is tiered**: a PR whose governed paths all lie under` (102 B) | `ending is that approval, then the owning seat. **Landing is tiered**: a PR whose governed paths all lie under` (113 B) | | `AGENTS.md` (PD 14) | 284 | `human merge IS the review record, ⛔ not a relaxation. Behind it: the queue guard refuses an unpinned governed` (115 B) | `spent approval IS the review record, ⛔ not a relaxation. Behind it: the queue guard refuses an unpinned governed` (118 B) | | checklist-test `SKILL.md` | 123 | ``用 `issue_write`(github MCP)立单:`` (36 B) | ``经 REST 代理 `POST .../issues` 立单(`Content-Type: application/json`;⛔ 永不 MCP `issue_write`,锁 1 已拒):`` (117 B) | Notes on the wording, each taken from the facts layer rather than invented: - :378 uses `rest-channel.md` :38–:39's words (`scripts/pm/label-write.mjs`, 四步、回读, ⛔ 永不 MCP `issue_write`, 锁 1 已拒); the full four-step rule already lives at SKILL.md :148, so the parenthetical is a pointer, not a restatement. - :615 — 等人合清单 → 等人批清单; the exit clause 随合并…离开 → 随获批…离开 keeps the same semantics in the ruling-C mechanism: :617 has the seat clear the label (清标) as the first landing step, on the approval, so the label leaves on approval or on a withdrawn verdict, not on the merge. - :626 — 等人合 → 等人批, the operative token of `landing-operations.md` :28 (「四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地」). The 获授权批准后认领席落地 half already stands at SKILL.md :616–:617 (「席位落地 = 过落地前检、清标、ready、auto-merge」), and no spelling that carries both halves fits the 120-byte cap with the 事实层 half unchanged (the shortest measured 131 B), so the line carries the token and :617 carries the mechanism. - AGENTS.md :273–:274 — the 人工直合 ending becomes the ending `lanes/ui.md` :25 states (「⛔ 未获授权批准不 ready 不入队不自合、永不批准,获批后认领席落地」): unapproved, no seat lands it; the ending is that approval (the authorized APPROVED review by a `GOVERNED_APPROVERS` account named four lines above), then the owning seat. The sentence says nothing about what the maintainer may do by hand, so it does not contradict the queue guard's own refusal text (see Consistency, item 5). - AGENTS.md :284 — "a human merge IS the review record" is the phrase the queue guard's self-test asserts ABSENT from its refusal text (`check-governed-queue-guard.mjs` :2436, "never … calls that merge the record"); under ruling C the maintainer's word is spent once, as the approval, so "a spent approval IS the review record" — same sentence, same line count. - checklist-test :123 — the REST channel in `rest-channel.md`'s own spelling (`POST .../issues`, request body as JSON). The field list that follows (标题 · 标签 · 正文, :125–:150) is already the shape of a REST issue body — title, labels, body — so no line below :123 needed to move. ## Premise readings (all against `origin/main` `fffe3e5e7f`) - **P1 content** (2026-09-14T11:16Z) — all five anchors matched by content at the named numbers: SKILL.md :378, :615, :626; AGENTS.md :274 (「(人工直合) is the only landing.」 inside PD 14); checklist-test :123. A sixth line of the same shape sits at SKILL.md :610 (not named by the card; see Consistency item 1). - **P2 ratchets** (2026-09-14T11:16Z) — `pnpm check:pm-skill-ratchet` exit 0 on the tip: SKILL.md 812/812 (widest row 342/342), AGENTS.md 1075/1075 (widest row 768/768), checklist-test 234/238 (widest row 221/221), core-rules 151/151. Frame block :733–:754 md5 `3327d02c56f8a0eca88569dad2270f32` before and after — identical. - **P3 core-rules.md** — the target grep `issue_write|等人合|人工直合` reads 1 hit, NOT 0: :128 「…代裁清单、等人合项、受管合并审计与五指标。」 — the round-report rule, which mirrors SKILL.md :672 (「awaiting a human merge 项」), not any of the four lines. The control `grep -c 'label-write\|四件套'` reads 0 in that file as well (neither control word is in core-rules today; stated as read). Per the dispatch's branch, core-rules.md is untouched; the mirrored pair is listed under Consistency item 2. - **P4 facts layer** — quoted verbatim: `rest-channel.md` :37 「✓ 标签加法 `POST .../issues/{n}/labels`,定向删 `DELETE .../issues/{n}/labels/{name}`;加法优先。」 :38 「标签/assignee 写恒经 `scripts/pm/label-write.mjs`:四步内建、回读、回退整组 PATCH 回传 assignees。」 :39 「⛔ 永不 MCP `issue_write`(锁 1 已拒);会话分类器拒改动 ⇒ 无通道,交有通道席位立卡。」; `lanes/ui.md` :25 「⇒ 命中即停 draft;⛔ 未获授权批准不 ready 不入队不自合、永不批准,获批后认领席落地。」; `landing-operations.md` :27 「受管路径全在本技能 `references/` 者事实层:席内达档复核过落地前检三条即转正式入队。」 :28 「其余为规则层:四件套留 draft 等人批,⛔ 不翻正式不入队;获授权批准后认领席落地。」 :29 「⛔ 两层不由席位批准;清标即落地同受此闸,漏判会被队列守卫在 merge group 里拒收。」 - **P5 serial** (2026-09-14T11:16Z) — `GET /pulls?state=open` returns exactly the six the dispatch named (18176, 18175, 18173, 18131, 18096, 17076); each `/files` list read via REST; zero hits on the three files. - **P6 lock 1** — `permissions.deny` on the tip carries **14** entries, not 15, with `mcp__github__issue_write` first among them; the same 14 at lock 1's own commit `7ef05f997`. The 15 was a miscount; the substance (the tool is denied) holds. ## Consistency — sentences of the same retired shape this PR does NOT move (the card's fence: no other line) 1. pm-dispatch `SKILL.md` :610 「② PR 留给维护者看得见地悬着;终局两条:人工直合即审核记录;授权批准 ⇒ 席位落地。」 — still two endings, with the human direct merge as the review record (the exact phrase retired at AGENTS.md :284 here and in the queue guard). Not named by the card; left as is. An equal-line candidate within the cap, for the seat to accept or reject: 「- ② PR 留给维护者看得见地悬着;终局一条:授权批准即审核记录 ⇒ 席位落地。」 2. pm-dispatch `SKILL.md` :622 「④ 轮次报告单列 awaiting a human merge。」 and :672 「…awaiting a human merge 项…」 with its core-rules mirror :128 「等人合项」 — the round-report item still named after the human merge; per 〈优先级〉 :44 the :672 ↔ :128 pair moves together, in one PR. 3. `AGENTS.md` :255 (the PD 14 headline) — "confirmed and merged by the maintainer, by hand — or confirmed by an authorized approval and then landed by the owning seat" still names the hand merge as ending one. NOT changed on purpose: `scripts/pm/check-governed-prose.mjs` :148 anchors its AGENTS.md region on that exact sentence (`start: 'A governed surface is confirmed and merged by the maintainer, by hand'`), so the sentence and the anchor must move in the same PR — outside this card. 4. `AGENTS.md` :799 (Skills section) — "human-merge only, or queued under Prime Directive #14's pinned-approval path" — outside PD 14, outside the card. 5. The mechanism layer still names 人工直合 for the unapproved case: `scripts/pm/check-governed-queue-guard.mjs` :1197 and :1273 print "Unapproved, the maintainer's own direct merge (人工直合) is the only landing this pull request has", and its self-test :2441 pins that word present; `landing-operations.md` :49 keeps 人工直合 as the main-red one-line exception; `lanes/director.md` :44 says 「等人合清单」. The :274 wording chosen here is compatible with all of them (it constrains seats, not the maintainer). 6. Script header comments still carrying the phrase: `scripts/pm/check-governed-merges.mjs` :140 and `scripts/check-required-contexts.mjs` :288 ("human merge IS the review record") — comments, not rules. ## Gates (foreground, exit captured before any pipe, all on `6dc9ac3e52`) Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (18 families; the seat's derivation named the same set). Each ran with stdout and stderr redirected into its own log file and the exit status captured immediately after, before any pipe: | # | Family | Exit | Verdict line | |---|---|---|---| | 1 | `node scripts/check-closing-keyword-parity.mjs` | 0 | OK (3 parsers agree on all 9 keywords…) | | 2 | `… --self-test` | 0 | 30 assertions, 5 mutations each driven to red | | 3 | `node scripts/check-comment-mask-corpus.mjs` | 0 | 6752 files, 0 disagree, 0 unparseable | | 4 | `node scripts/pm/check-governed-queue-guard.mjs --self-test` | 0 | 238 cases pass | | 5 | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 3 → 0 | first run PREREQUISITE NOT MET (not a verdict: `@objectstack/formula`, `@objectstack/lint` unbuilt); built under `scripts/pm/os-verify-lock.sh` (`VERDICT command-exit 0 · held the lock 5s · waited 0s`), re-run exit 0: 58 self-test cases, 22 record-scoped examples / 438 files clean | | 6 | `pnpm check:agent-test-spelling` | 0 | 0 violations — 508 files | | 7 | `pnpm check:doc-authoring` | 0 | 15340 strings across 978 spec sources clean | | 8 | `pnpm check:docs-audit-scope` | 0 | 14 release-owned pages review-only; scope injection live | | 9 | `pnpm check:driver-memory-census` | 0 | every declaration ledgered | | 10 | `pnpm check:nul-bytes` | 0 | scanned 8655 text files, no raw ASCII control bytes | | 11 | `pnpm check:pm-governed-merges` | 0 | 328 assertions; the real generator declared 9 outputs and certified this tree | | 12 | `pnpm check:pm-governed-prose` | 0 | 2 instruction surfaces name all 5 registered governed surfaces and claim no others | | 13 | `pnpm check:pm-skill-id-lint` | 0 | 27 files clean | | 14 | `pnpm check:pm-skill-ratchet` | 0 | SKILL.md 812/812 (342/342) · AGENTS.md 1075/1075 (768/768) · checklist-test 234/238 (221/221) · core-rules 151/151 | | 15 | `pnpm check:refd-timer-probe` | 0 | 6747 files swept | | 16 | `pnpm check:required-contexts` | 0 | 7 required contexts pinned; 6 instruction surfaces scanned against 2 retired names | | 17 | `pnpm check:skill-frame-sync` | 0 | the one declared copy is internally coherent; 74 markdown files scanned for undeclared copies | | 18 | `pnpm check:watch-hint-literal` | 0 | 70 declarations across 4 rostered names | Reconciliation (`--ran`, exit codes recorded per command): `Run reconciliation — 18 derived, 18 run, 0 NOT-MEASURED, 0 UNRUN.` … `✓ dispatch-gates --ran: 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).` Also outside the derivation: the pre-push hook `check:commit-card-trailers` on the push (1 commit, no card relation, no model identifier in the trailer pair); the control-byte self-scan `grep -naP` over the three files reads none. Changeset: none owed. The three paths are `.claude/**` and `AGENTS.md` — nothing any package's `files[]` ships. The `changeset-check` job in `pr-automation.yml` has two exemptions (the `skip-changeset` label and the release PR) and no path exemption, so the label is applied through the additive endpoint `POST /issues/{n}/labels` right after this PR opens and read back; the read-back is recorded in the os-dev-report comment on the card (this body is not re-sent). ## 维护者速读(草稿) - 改了什么:四行规则文本(加同段两句)追上已落地的锁 1、两级落地与裁决 C —— `issue_write` 已被拒、规则层等的是批准而不是人合、批准后由认领席落地。 - 为什么改:规则层与它自己的 references 说法相反,会把席位训练回已退役的机制;文档以实际实现为准。 - 风险与代价(含回滚):零机制变化,纯文案,等行数;回滚即 revert 本 PR。 - 席位意见:(留空) - 你要做的:一次授权批准(os-zhuang / hotlong 任一账号 APPROVE);之后由认领席落地,不需要你再点合并。 ## Acceptance notes - noted, not filed: Consistency items 1–6 above — same retired-shape residue in lines the card's fence excludes (SKILL.md :610/:622/:672, core-rules :128, AGENTS.md :255/:799, the guard's refusal text and two script comments). 承接者: the `domain:skills` seat (owner of SKILL.md, `references/**` and `scripts/pm/**`); items 3 and 5 need a gate/anchor edit in the same PR as the prose. - noted, not filed: the dispatch's P6 count (15) versus the measured 14 — a miscount in the dispatch text, no file to fix. 承接者: 无. - Deviation, declared: the dispatch asked for a three-line 速读; `.claude/agents/os-dev.md` fixes five segments, and that file wins on conflict — five compact bullets above. - No footer block was sent with this body (the platform appends one on create per `platform-readings.md` :338); the body was read back after creation. Clause-②: no --- _Generated by [Claude Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent ba9b498 commit a81a9d6

3 files changed

Lines changed: 7 additions & 7 deletions

File tree

‎.claude/skills/checklist-test/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ expected-fail 探针 —— 永不在真实缺陷上把条款打成绿。
120120
**issue 是纯文本 —— 永不放图。** 截图只为让你和子代理**现场**得出判定;它们是判断辅
121121
助,随运行环境一起丢弃。持久报告需要的是**复现规则,不是图片**。
122122

123-
用 `issue_write`(github MCP)立单:
123+
经 REST 代理 `POST .../issues` 立单(`Content-Type: application/json`;⛔ 永不 MCP `issue_write`,锁 1 已拒):
124124

125125
- **标题** —— `QA run · <selector> (<已判定>/<总数>) · <sha8> · <date> · <counts>`:恰好
126126
一种形状、严格解析,`(<已判定>/<总数>)` **强制**;语法与退役写法见

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
375375
- 三类内再过时前提检查,三选一:晋级 / 关闭 not planned / hold;判级只在此轮,不在立单时。
376376
- ⛔ 写入前对每张卡现读当前状态;任何列表快照读数一律作废。
377377
- ⛔ 带 `pm:dispatched` / assignee / 任何 open 或 merged PR 引用的卡,一律不动。
378-
- ⛔ `issue_write` 会替换标签集并清空未传字段:写入时必须回传 `assignees`。
378+
- 标签/assignee 写恒经 `scripts/pm/label-write.mjs`(四步、回读);⛔ 永不 MCP `issue_write`(锁 1 已拒)。
379379
- 车道席可附证据/前提重验,⛔ 不定级不改标;skills 车道 finding 由该席自分诊,全仓轮跳过。
380380
- 域分批与 sweep 打包晋级五条照用;每批约定与积压告警见 `references/dispatch-runbook.md`。
381381
- `pm:retriage` 每 fire 先答异议评论所求,答后同笔摘标;须维护者答的进收件箱,标照摘。
@@ -612,7 +612,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
612612
- 速读五段固定:改了什么/为什么改/风险与代价(含回滚)/席位意见/你要做的(一个动作)。
613613
- 草稿归 dev:受管面 PR 正文带 `## 维护者速读(草稿)`,中文、业务角度,席位意见留空。
614614
- 终稿 = 席位对照自己读的 diff 校正草稿、填席位意见后贴评论;维护者只读评论。
615-
- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人合清单,随合并或撤回判决离开。
615+
- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人批清单,随获批或撤回判决离开。
616616
- 批准判定单源 = 队列守卫常量 `GOVERNED_APPROVERS`:授权账户 APPROVED 即算,⛔ 不卡 `commit_id`。
617617
- 批准后再推亦不过期;席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。
618618
- ③ 在 draft PR 上向两个授权批准账户 `os-zhuang` 与 `hotlong` 都 request review,主动推。
@@ -623,7 +623,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
623623
- 已入队才读到本条 ⇒ 转 draft 与 disable 都做;出队以阳性探针答,ref 缺席只旁证。
624624
- skills 车道自有 PR:纯代码面如 `scripts/pm/` 由本席按达档自审(清单不减)后落地。
625625
- 受管面两层:事实层仅本技能 `references/`,其余为规则层(含发布 `skills/**` 与 SKILL.md)。
626-
- 规则层四件套等人合;事实层 PR(受管路径全在该目录)经席内达档复核后 ready → 入队。
626+
- 规则层四件套等人批;事实层 PR(受管路径全在该目录)经席内达档复核后 ready → 入队。
627627
- 路径面干净的才转 ready → 入队;队列是唯一被认可的落地路径,⛔ 永不队列外合并。
628628
- 入队资格 = PR 上每一个 check 全绿,⛔ 不是 required 子集;required 集是队列强制的地板。
629629
- 非必查红是真缺陷或坏门,归 PM 入队前处置;第三种按设计而红,三条全立才可带红入队:

‎AGENTS.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ localStorage / auth gotchas.
270270
spent once per PR: the OWNING seat then lands it, later pushes included, re-queuing after an ejection or a rebase on
271271
its own pre-landing check; this gate does not re-review it. Hand-authored governed content needs that approval; a PR
272272
whose only governed paths are register rows the queue leg regenerates byte-exact clears with zero approvals — an
273-
uncertified recompute, drift or a hand-authored sibling keeps it governed. Unapproved, the bypass direct merge
274-
(人工直合) is the only landing. **Landing is tiered**: a PR whose governed paths all lie under
273+
uncertified recompute, drift or a hand-authored sibling keeps it governed. Unapproved, no seat lands it: the
274+
ending is that approval, then the owning seat. **Landing is tiered**: a PR whose governed paths all lie under
275275
`.claude/skills/pm-dispatch/references/` lands through the queue after the skills seat's contract-tier review; every
276276
other governed path is the rules layer and waits for the maintainer's word, which the director seat requests as ONE
277277
batch of at most five rows — the approval stays the maintainer's click. ⛔ **No agent seat submits an approving
@@ -281,7 +281,7 @@ localStorage / auth gotchas.
281281
**Already armed or queued when you read this?** Convert it back to **draft** AND disable auto-merge — draft is
282282
what removes queue membership, disabling alone drops only the arming — then confirm from the remote that it is in
283283
neither the queue nor `origin/main`. **Draft is no barrier by itself — the barrier is this directive**, and a
284-
human merge IS the review record, ⛔ not a relaxation. Behind it: the queue guard refuses an unpinned governed
284+
spent approval IS the review record, ⛔ not a relaxation. Behind it: the queue guard refuses an unpinned governed
285285
diff; CODEOWNERS routes review requests for `docs/adr/` only, so nothing summons the maintainer on the other four;
286286
the post-merge audit (`scripts/pm/check-governed-merges.mjs`) lists every governed-surface merge with its approver
287287
and merger — a merger the maintainer does not recognise, or any agent approval, is a seat violation, filed and

0 commit comments

Comments
 (0)