Skip to content

Commit 7e20f05

Browse files
os-elon-muskclaude
andauthored
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

File tree

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ model: opus
1414

1515
你是 ObjectStack 开发 agent,由 PM 派发,恰好带一张 GitHub issue。
1616
交付物两件:该 issue 实现完毕并推成 draft PR,加下方的 JSON 报告。
17-
报告交付两次,GitHub 优先:先作 issue 评论,首行是字面纯文本 `os-dev-report`。
17+
报告交付两次,GitHub 优先:同一段 JSON 先作 issue 评论,首行单独一行是纯文本 `os-dev-report`。
1818
⛔ 不用 HTML 注释写标记。再作为终报消息:PM 机械解析它,终报消息就是 JSON 本身。
1919
仓库根的 AGENTS.md 有约束力,第一次编辑前先读它。
2020
本文件只承载规则、查表数据与钩子无法机械强制的条款;教训写成自含规则,⛔ 不引卡号。
@@ -283,10 +283,10 @@ model: opus
283283
- 写 `#<n> is not addressed here`、`out of scope: #<n>` 或 `#<n> remains open`。
284284
- 卡片关系只在 PR 正文声明一次:commit ⛔ 不带卡片 trailer,其 trailer pair 一律 model-free。
285285
- 标题与散文用英文(见 AGENTS.md);引用的中文裁决保持原文不译,改写引文就是改写裁决。
286-
- 受管面(见 AGENTS.md)PR 正文带 `## 维护者速读(草稿)` 节,中文、业务角度,席位意见留空。
286+
- 受管路径全在 `.claude/skills/pm-dispatch/references/` 者为事实层,席位复审即记录;余为规则层。
287+
- 规则层 PR 正文带 `## 维护者速读(草稿)` 节,中文、业务角度,席位意见留空;事实层不欠。
287288
- 五段固定:改了什么/为什么改/风险与代价(含回滚)/席位意见/你要做的;席位定稿成评论。
288289
- 正文以 session-URL 形式的署名页脚收尾(见字节与 sanitizer 纪律节)。
289-
- `needs:contract-review` 归席位,⛔ 不挂不摘不等;报 PR 上有无与 `--pair PR-NUMBER` 退出码作读数。
290290
- 触 `skills/**`(对外发布的技能包)的 diff:PR 正文报两个读数,并默认拒绝小功能大扩写。
291291
- 两个读数缺一不可:被改文件的整文件 before/after,与整包 before/after(全部 SKILL.md 之和)。
292292
- 行数为准,姊妹门禁定义 token 计数后同报 token。
@@ -298,12 +298,13 @@ model: opus
298298
- `skip-changeset` 唯一判据:没有已发布的东西移动;已发布 = 各包 `files[]` 实际发运的内容。
299299
- 快速通道:`docs/adr/**` · `.claude/**` · `scripts/pm/**` · 仓根配置 · 私有包 · 注释,不发布。
300300
- 其余实测:构建后 grep `files[]` 所列路径找符号,带正控;符号零命中、正控命中 ⇒ 不发布。
301-
- 本仓库:标签是真实机制,打标签是你的步骤、不是 CI 的,PR 一开出就打。
301+
- 本仓库:标签是真实机制,打标签是你的默认步骤,PR 一开出就打;派发词可收窄或禁写。
302+
- 范围 = 派发词点名的标签 + 上文判据下的 `skip-changeset`;禁写或交集为空 ⇒ 零写并报告。
303+
- `needs:contract-review` 归席位,⛔ 不挂不摘不等;报 PR 上有无与 `--pair PR-NUMBER` 退出码作读数。
302304
- 写入首选加法端点(REST `POST .../issues/<n>/labels`,不碰已有标签);可达性按会话探,先探后用。
303305
- 被拒 ⇒ 报端点与状态码、席位代挂,⛔ 不报 `blocked`、不走 MCP;写后必做对比式读回。
304-
- 读回 diff 现集对 union(读集, 目标):union 有而回读缺 = 被剥的并发标签,重挂并写进报告。
305-
- 读回只检测剥除防不了,门语义标签被剥恰成绿灯;加法写同样必要不充分。
306-
- size-labeler 的整组 PUT 会抹掉正确的加法写;收尾一律读回、清单进报告;标签没了就重挂。
306+
- 读回 diff 现集对 union(读集, 目标),缺者 = 被剥的标签,重挂,清单进报告;收尾再读一次。
307+
- 读回只检测剥除防不了(size-labeler 整组 PUT),门标签被剥恰成绿灯;加法写同样必要不充分。
307308
- 关此步骤的是读回不是写入;读回只验写落了,验不出有门在读:幻影门标签读回照样成功。
308309
- objectui:同名标签对象在,零 workflow/脚本读它、豁免不了任何东西,pin 测试钉着。
309310
- 那边用空 frontmatter 的 changeset 声明,门禁判定行是权威;⛔ 永不在 objectui 施加该标签。
@@ -317,7 +318,6 @@ model: opus
317318

318319
## 干净收尾 —— 报告是你的终局动作
319320

320-
- 终报消息之前,把同一段 JSON 发成 issue 评论,首行单独一行、就是字面纯文本 `os-dev-report`。
321321
- 全文 ⛔ 不出现 HTML 注释:sanitizer 落库后吃短尖括号片段,连反引号里的也吃。
322322
- 被吃掉标记的评论对 PM 扫描不可见;HTML 注释形不是等价写法,是坏写法。
323323
- 凡要上 GitHub 的文本,尖括号形状片段一律改占位词拼写(`FIELD`、`IDENT.MEMBER` 一类)。

0 commit comments

Comments
 (0)