Repository navigation
Commit 7e20f05
docs(os-dev): label step scope and precedence; maintainer digest owed on the rules layer only (#18898)
Fixes #18699
Fixes #18812
Fixes #18821
Clause-②: no
Family fold of three graded cards on ONE file,
`.claude/agents/os-dev.md` (governed, rules layer,
`CONTRACT_REVIEW_TIER`): the label-timing clause that had no scope
(chain head), the unconditional 速读 clause against the tiered landing,
and the label step against a dispatch order that forbids it. One commit
per card, in that order. `#18698 remains open` and `#18882 remains open`
— neither is addressed here.
## What changed (three commits; anchored on content — the cards' line
numbers were readings at older shas)
**Commit 1 — the label band gets its scope, its exception and the
empty-intersection action.**
- The timing line 「本仓库:标签是真实机制 … PR 一开出就打」 gains a scope line directly
under it: 「范围 = 派发词点名的标签,`needs:contract-review` 除外;交集为空 ⇒ 零写,报告写明。」
- The carve-out line 「`needs:contract-review` 归席位,⛔ 不挂不摘不等;报 PR 上有无与
`--pair PR-NUMBER` 退出码作读数。」 moves down UNCHANGED from the PR-body band
into the label band, so scope, exception and the empty-intersection
action are three consecutive lines — no new special-case sentence, which
the triage names as the source of the contradiction.
- Paid in-file: the size-labeler line is retired by folding — its cause
「size-labeler 整组 PUT」 into the read-back-is-necessary-not-sufficient
line, its wrap-up read-back 「收尾再读一次」 and 「清单进报告」 into the read-back
line, and its 「标签没了就重挂」 was already that line's 「重挂」. Bytes on the two
folded lines came from 「并发」 and 「语义」 (the ratchet's 120-byte line
budget; both were adjectives whose meaning the neighbouring lines still
carry).
**Commit 2 — the label step is a default the dispatch may narrow or
forbid.**
- 「打标签是你的步骤、不是 CI 的」 becomes 「打标签是你的默认步骤」 and the line ends
「;派发词可收窄或禁写。」; the scope line's action becomes 「禁写或交集为空 ⇒ 零写,报告写明」.
- Category, said once: the step is a DEFAULT, not an unconditional
clause. The standing precedence line
「派发词与本文件冲突时以本文件为准:无条件条款住这里,错了也在这里改。」 is untouched and does not
contradict this: it governs the unconditional clauses, and the label
line now says of itself that it is not one — a dispatch that forbids the
write is not in conflict with this file, it is exercising what this file
grants.
- The write-budget line 「写预算四笔 …」 is untouched: 「预算」 plus 「预算外零写」
already read as a ceiling, and the scope line now names the dispatch as
the source of the label list, so the budget cannot be read as an
entitlement to a label the dispatch did not name.
- 「、不是 CI 的」 is dropped for bytes: 「你的默认步骤」 and 「PR 一开出就打」 already say
nobody else applies it for you.
**Commit 3 — the 速读 draft is owed on the rules layer only.**
- 「受管面(见 AGENTS.md)PR 正文带 `## 维护者速读(草稿)` 节 …」 becomes two lines: the
tiering 「受管路径全在 `.claude/skills/pm-dispatch/references/`
者为事实层,席位复审即记录;余为规则层。」 then the per-layer rule 「规则层 PR 正文带 `## 维护者速读(草稿)`
节,中文、业务角度,席位意见留空;事实层不欠。」 The predicate is the one AGENTS.md Prime
Directive 14 and pm-dispatch SKILL.md 「受管面两层」 already use. 「(见
AGENTS.md)」 is dropped for bytes — the file's own preamble makes
AGENTS.md binding.
- 「PR 正文 dev 只写一次 … ⛔ 不 `PATCH`」 is untouched; the conflict closes by
the definition tracking the landing, not by allowing a body patch.
- Paid in-file: the first bullet of the wrap-up section, 「终报消息之前,把同一段
JSON 发成 issue 评论,首行单独一行、就是字面纯文本 `os-dev-report`。」, duplicated the
preamble's sentence; its two extra bits fold into the preamble line, now
「报告交付两次,GitHub 优先:同一段 JSON 先作 issue 评论,首行单独一行是纯文本 `os-dev-report`。」
(「字面」 dropped for bytes; the next preamble sentence already refuses the
HTML-comment spelling). This continues the dedup the previous os-dev.md
PR started in the same spot.
## Reader tests — a dev reading ONLY os-dev.md
1. 「the only label I could hang is `needs:contract-review` — what do I
do?」 → the scope line: it is 除外, so the intersection is empty ⇒ 零写,报告写明;
the next line: report presence on the PR and the `--pair` exit code.
Write nothing, say so.
2. 「my PR's governed paths are all under
`.claude/skills/pm-dispatch/references/` — do I write the 速读 section?」 →
the tiering line says that is the fact layer and the seat's review is
the record; the rule line says 事实层不欠. No.
3. 「my dispatch order forbids the label write — do I still do it?」 → the
timing line: 派发词可收窄或禁写; the scope line: 禁写 ⇒ 零写,报告写明. No; the dispatch
wins; the report names what is now the seat's to hang.
No answer needs a second text.
## Line budget (`check:pm-skill-ratchet`, run at `ee4c3c6f9`)
`.claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0)` before
and after; every line within the 120-byte budget. Added: the scope line,
the tiering line (+2). Retired: the size-labeler line (folded, commit 1)
and the wrap-up section's duplicate report-comment line (folded into the
preamble, commit 3) (−2). Moved unchanged: the `needs:contract-review`
carve-out line. Net 0 at each of the three commits, so the ratchet is
green at every commit.
## Verification
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `ee4c3c6f9` derived 19 commands (change
set: 1 path vs merge base `600b1e2ab`); all 19 run with
redirect-then-capture, exit 0 each; `--ran` reconciliation: 「19 derived,
19 run, 0 NOT-MEASURED, 0 UNRUN」. Named families:
`check:pm-skill-ratchet` (403/403 as above), `check:pm-skill-id-lint`
(27 files clean), `check:agent-model-declared` (os-dev.md → opus),
`check:nul-bytes`, `check:skill-frame-sync`,
`check:agent-test-spelling`, `check:doc-authoring`,
`check:commit-card-trailers`, `check:pm-governed-merges`,
`check:cross-package-test-inputs`, `check:watch-hint-literal`,
`check:refd-timer-probe`, `check:driver-memory-census`, the comment-mask
corpus sweep, closing-keyword parity plus its self-test, the
governed-queue-guard self-test, the harness-current self-test, and
`@objectstack/lint check:doc-formula-expressions` (first run exit 3 =
PREREQUISITE NOT MET on unbuilt formula/lint packages, so not a
measurement; both rebuilt under the verify lock, rerun exit 0). Also
run, outside the derived set because the derivation marks its roster as
sitting under `.claude`: `check:pm-settings-deny-roster`, exit 0. The 14
pending-changeset families do not apply: this PR carries no changeset
(`skip-changeset` — nothing under any package's `files[]` moves; the
file is under `.claude/**`, the fast lane).
The pre-push trailer check passed on the push: three commits, no card
relation, no model identifier in the trailer pair.
## Acceptance notes
- noted, not filed: the 「或 `tail --pid` 等它退出」 line in the wrap-up
section names no pid source — a rider the previous seat left for the
next os-dev.md PR; untouched here (this fold edits the section's first
bullet, not that band). 承接者:the next entry on the os-dev.md serial.
- noted, not filed: os-dev.md keeps ASCII sentence punctuation after Han
characters throughout (the ratchet's own comment measures it); the new
lines follow it. No gate pins the convention. 承接者:无.
- The harness-injected attribution reminder for this session names a
model in the co-author line and prescribes a different PR footer;
AGENTS.md (which that reminder itself defers to) declares the trailer
pair model-free and fixes the footer form, and
`check:commit-card-trailers` refuses the model-named form at push — the
commits and this body follow AGENTS.md. This is the shape of the card
still in the decision box (`#18698 remains open`); not re-litigated
here.
## 维护者速读(草稿)
**改了什么**:`os-dev.md`(开发 agent 的标准合同)三处子句改写,行数不变(403/403)。①
挂标签那条补齐范围、例外与交集为空时的动作;② 写明挂标签是默认步骤,派发词可收窄或禁;③
「维护者速读」只在规则层受管面欠,事实层(`references/` 目录)不欠,以席位复审为记录。
**为什么改**:三张卡量到同一个病:合同里的子句与回路实际跑的分层脱节,每次都靠现场的 dev
自行裁断。已量到的代价:一次升级轮加一次板上半写状态;两次事实层 PR 靠派发词手工豁免;一次云端卡上 dev 从零裁断先后关系。三位 dev
都做对了(声明冲突而不是静默选边),但「dev 推理出了正确答案」不是规则。
**风险与代价(含回滚)**:纯文本改动,不发布、不动门禁、不动 frontmatter。风险在措辞:读者只读 os-dev.md
能否答出三个问题——正文 Reader tests 逐一作答。回滚 = revert 三个 commit 中任一或全部,每个 commit
各自净 0 行,互不依赖。
**席位意见**:(留空)
**你要做的**:审阅三条改写后的子句是否与你对分层落地的理解一致,一致即批准(需 `GOVERNED_APPROVERS` 账户的
APPROVED)。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01BTeBejoPUvRHN8WdAJC6oF)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 8b48903 commit 7e20f05
1 file changed
Lines changed: 8 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
283 | 283 | | |
284 | 284 | | |
285 | 285 | | |
286 | | - | |
| 286 | + | |
| 287 | + | |
287 | 288 | | |
288 | 289 | | |
289 | | - | |
290 | 290 | | |
291 | 291 | | |
292 | 292 | | |
| |||
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | | - | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
302 | 304 | | |
303 | 305 | | |
304 | | - | |
305 | | - | |
306 | | - | |
| 306 | + | |
| 307 | + | |
307 | 308 | | |
308 | 309 | | |
309 | 310 | | |
| |||
317 | 318 | | |
318 | 319 | | |
319 | 320 | | |
320 | | - | |
321 | 321 | | |
322 | 322 | | |
323 | 323 | | |
| |||
0 commit comments