Skip to content

Commit 87f776b

Browse files
os-elon-muskclaude
andauthored
docs(agents): os-dev.md — releases ban scoped to code PRs, force-push per landing repo, label-step scope, classifier-denial cell (#19038)
Fixes #18908 Fixes #18882 Fixes #19002 Fixes #19004 Clause-②: no Four cards on one file, `.claude/agents/os-dev.md`, one branch, three line-neutral commits (`2300b8938`, `65d09a3b9`, `7f28ee186`). Governed surface (`.claude/**`) ⇒ draft; landing is the maintainer's word. `skip-changeset`: `.claude/**` is the fast path — nothing any package's `files[]` ships moves. ## What changed, line by line (bytes exclude the newline; before = `main` `75c0dacff`, after = `7f28ee186`) | line | before (B) | after (B) | card | |---|---|---|---| | :67 | 113 · 「4. ⛔ 永不编辑 `content/docs/releases/`、推 `main`、合并任何东西;force-push 只按 AGENTS.md §3。」 | 117 · 「4. ⛔ 永不推 `main`、合并任何 PR、在代码 PR 里改 `content/docs/releases/`;改错另开 docs-only PR。」 | #18908 | | :68 | 53 · 「 - 用户可见的改动需要 `.changeset/*.md`。」 | 119 · 「 - force-push 按落地仓 AGENTS.md:objectui/cloud 绝对禁;objectstack §3 五条全立才 `--force-with-lease`。」 | #18882 | | :298 | 116 · 「- `skip-changeset` 唯一判据:没有已发布的东西移动;已发布 = 各包 `files[]` 实际发运的内容。」 | 120 · 「- 发布面动了要 changeset;`skip-changeset` 唯一判据是没动:已发布 = 各包 `files[]` 实际发运内容。」 | pays :68 | | :301 | 114 · 「- 本仓库:标签是真实机制,…」 | 116 · 「- objectstack:标签是真实机制,打标签是你的默认步骤,PR 一开出就打;派发词可收窄或禁写。」 | #19002 | | :304 | 118 · 「- 写入首选加法端点(REST `POST .../issues/N/labels`,不碰已有标签);可达性按会话探,先探后用。」 | 115 · 「- 写恒经 `scripts/pm/label-write.mjs`:取现集、加法 POST、回读比 union、缺者重挂一次并报告。」 | #19004 | | :305 | 114 · 「- 被拒 ⇒ …;写后必做对比式读回。」 | 119 · old :307 moved up unchanged (read-back detects stripping only) | #19004 | | :306 | 115 · 「- 读回 diff 现集对 union(读集, 目标),缺者 = 被剥的标签,重挂,清单进报告;收尾再读一次。」 | 119 · old :308 moved up unchanged (read-back closes the step; phantom gate label) | #19004 | | :307 | 119 · old :307 | 105 · 「- 被拒 ⇒ 报端点与状态码、席位代挂,⛔ 不报 `blocked`、不走 MCP;收尾再读一次。」 | #19004 | | :308 | 119 · old :308 | 119 · 「- 分类器拒外部写 ⇒ 停手,`deviations` 记命令与拒因,席位代做;⛔ 不换路重发(curl/MCP/手工)。」 | #19004 | | :309 | 105 · 「- objectui:同名标签对象在,零 workflow/脚本读它、豁免不了任何东西,pin 测试钉着。」 | 119 · 「- objectui:路径标签归 `labeler.yml`,逐 push 同步;无门禁读你打的标签 ⇒ 派发词未点名即零写。」 | #19002 | | :310 | 114 · 「- 那边用空 frontmatter 的 changeset 声明,门禁判定行是权威;⛔ 永不在 objectui 施加该标签。」 | 119 · 「- objectui 的 `skip-changeset` 零读者;空 frontmatter changeset 即声明,门禁判定行为准,⛔ 永不施加。」 | #19002 | Ratchet reading: `check-skill-line-ratchet: .claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0)` — before 403 / 403, after 403 / 403; the 120-byte max-line rule's budget line reads `budget is 120 bytes`; longest changed line is 120 B (:298). ### The folds that paid for the three new lines 1. :68's changeset sentence folds into :298, which already carried the precise criterion (`skip-changeset` ⇔ nothing published moved); the fuzzier 「用户可见」 spelling is replaced by its complement 「发布面动了要 changeset」 on the same line. AGENTS.md's Post-Task Checklist step 3 remains the binding text. 2. :304 + :306 (the four steps written by hand) fold into one line naming the single spelling that already performs them — `scripts/pm/label-write.mjs` (`references/rest-channel.md`: 「标签/assignee 写恒经 `scripts/pm/label-write.mjs`」; the four steps, the once-only re-apply and the report are its own contract). The reachability probe of old :304 is the tool's exit 3; 「收尾再读一次」 keeps its place on the refusal line. 3. old :309 + :310 (objectui's `skip-changeset`) fold into one line: 「零读者」 subsumes 「零 workflow/脚本读它、豁免不了任何东西」; dropped as evidence rather than rule: 「同名标签对象在」 and 「pin 测试钉着」 (the pin is `objectui/scripts/__tests__/ci-cd-pipeline-doc.test.ts`, `never wires the phantom skip-changeset label into a workflow or a gate`). Not a re-wrap anywhere: every line that changed changed its content; old :307/:308 moved, byte-identical. ## The rulings this PR executes (verbatim) **#18908 — ruling #18854 B** (comment 5725503560, maintainer 「同意」 2026-09-18T05:13Z): > 1. **Text**: `.claude/agents/os-dev.md:67` becomes 「⛔ never edit `content/docs/releases/` **in a code PR**; a factual error on a releases page is a dedicated docs-only PR, per `AGENTS.md`'s Documentation Guardrails」 — the same clause `SKILL.md:32` already carries. A `domain:skills` card (filed by the director with this ruling) carries it; governed ⇒ human merge by the approver. It unlocks the class, ⛔ not just this line. Aligned texts on `main`: `SKILL.md:32` 「⛔ 永不在代码 PR 里改 `content/docs/releases/`。」; `AGENTS.md:685` 「`content/docs/releases/` | RELEASE-OWNED | ❌ Never edit in a code PR. … Factual error on a releases page → dedicated docs-only PR or an issue, never a rider on code changes.」 The pointer to the Documentation Guardrails did not fit the 120-byte line; os-dev.md :19 already binds AGENTS.md whole. **#18882 — ruling objectui#9666 C** (comment 5724939229, maintainer 「其他同意」 2026-09-18T03:58Z): > - Neither text changes. The divergence is deliberate: objectui is the busier shared tree and its ban was measured and refused an exception by name; objectstack's allowance was ruled on its own facts a week ago. > - objectui `AGENTS.md`'s cross-repo section gains one sentence: **a force-push is governed by the `AGENTS.md` of the repository the branch lives in — objectui and cloud forbid it absolutely, objectstack allows `--force-with-lease` under its five criteria; a seat working across repositories reads the landing repo's rule before instructing a dev.** objectstack's `.claude/agents/os-dev.md` force-push twin, which today says 「see §3」, is re-pointed at **the landing repository's** §3 (a sibling objectstack card, `domain:skills`, filed by the director with this ruling). The two shapes, read on today's trees: objectstack `AGENTS.md:471-:478` (§3) — 「**Never force-push a *shared* branch, and never push `main`.** … A branch is unshared, and `--force-with-lease` allowed, only while ALL FIVE hold: ① it is named `claude/issue-*`; ② this worktree created it; ③ nobody else has ever pushed it …; ④ no open PR on it carries a reviewer or an approval …; ⑤ the push spells the lease against the sha you last pushed — ⛔ never bare `--force`. One criterion failing ⇒ the branch is shared.」; objectui `AGENTS.md:316` (read at objectui `origin/main` `a017617`) — 「**绝不 `git push --force`/`--force-with-lease`,绝不推 `main`**(会覆盖并行 agent 的工作;`main` 共享,一律走 PR)。**禁令不按「这条分支是不是只有我一个人用」分档**…所以它一律绝对,单人 feature 分支同样不例外。」; cloud `AGENTS.md:63` is cited by the ruling's words only (outside this session's scope). The new :68 says 「落地仓 AGENTS.md」 rather than 「落地仓 §3」 because objectui's rule carries no section number; objectstack's is named `§3` where the five criteria live. **#19002** (triage 5729068374): the deliverable is the label step's SCOPE, no new rule. Measured on objectui `origin/main` `a017617`: `.github/workflows/labeler.yml` runs `actions/labeler@v7` with `configuration-path: .github/labeler.yml` and `sync-labels: true` on every `pull_request` open/synchronize/reopen — path labels are written by it and re-synced on every push; across all 40 workflow files, zero read a PR label (`grep -rn -E "labels\.\*\.name|pull_request\.labels|event\.label\b|\.labels\b" .github/workflows/` → no hit); the only scripts that read labels are `scripts/pm/check-half-states.mjs` (the PM board's `pm:*` states) and `scripts/check-governed-queue-guard.mjs` (`CONTRACT_REVIEW_LABEL = 'needs:contract-review'`, the seat's, os-dev.md :303) — neither a label a dev writes. On objectstack, `.github/workflows/pr-automation.yml:290` reads `skip-changeset` in a job condition, so 「标签是真实机制」 is now attributed to `objectstack` by name. The filing seat's measured four PRs (objectui#9804/#9812/#9826/#9854, labels present with no dev write) agree with the mechanism. No maintainer word needed: the two mechanisms decide the scope, nothing is presumed beyond them. **#19004** (triage 5729095625): 「契约里该写的是停手并上报,⛔ 不是换一条手工路径继续」. The new :308 is the classifier cell beside the endpoint cell (:307): the trigger is an external write the session classifier refuses (「外部写」 — not any denied local tool, since the card's line is 「never re-issue the same EXTERNAL write by another route」), the conduct is stop, record the command and the classifier's reason under `deviations` (a dispatch-carried report field, `SKILL.md:536`), hand the act to the seat, and never re-issue it by another route, the three routes named. It covers every tool the dispatch names, labels included; the seat-side half already lives in `references/rest-channel.md` (「会话分类器拒改动 ⇒ 无通道,交有通道席位立卡」). ## Gates (run at `7f28ee186`, exit codes captured before any pipe; ledger reconciled with `dispatch-gates.mjs --ran`) Derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` off merge base `75c0dacff` (1 path): 19 commands. `--ran` verdict: `19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED`. - `pnpm check:pm-skill-ratchet` :: exit 0 — `os-dev.md is 403 lines (ceiling 403; headroom 0)` - `pnpm check:pm-skill-id-lint` :: exit 0 — `27 file(s) clean (pattern /#[0-9]{3,}/g)` - `pnpm check:agent-model-declared` :: exit 0 — `1 agent definition(s) under .claude/agents/ all declare a model` - `pnpm check:nul-bytes` :: exit 0 - `pnpm check:skill-frame-sync` :: exit 0 · `pnpm check:watch-hint-literal` :: exit 0 · `pnpm check:refd-timer-probe` :: exit 0 - `pnpm check:pm-governed-merges` :: exit 0 · `node scripts/pm/check-governed-queue-guard.mjs --self-test` :: exit 0 (253 cases) · `node scripts/pm/check-harness-current.mjs --self-test` :: exit 0 - `pnpm check:commit-card-trailers` :: exit 0 (and the pre-push hook: 3 commits, no card relation, model-free trailer pair) - `pnpm check:doc-authoring` :: exit 0 · `pnpm check:agent-test-spelling` :: exit 0 · `pnpm check:cross-package-test-inputs` :: exit 0 · `pnpm check:driver-memory-census` :: exit 0 - `node scripts/check-closing-keyword-parity.mjs` :: exit 0 (+ `--self-test` :: exit 0) · `node scripts/check-comment-mask-corpus.mjs` :: exit 0 (6861 files, 0 disagree) - `pnpm --filter @objectstack/lint run check:doc-formula-expressions` :: first run exit 3 = PREREQUISITE NOT MET (`@objectstack/formula` not built — nothing measured); after `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under `os-verify-lock.sh` (VERDICT command-exit 0), re-run :: exit 0 — `22 record-scoped formula example(s) across 438 files … judged clean` - `node scripts/pm/check-governed-merges.mjs --test .claude/agents/os-dev.md` :: exit 3 = its GOVERNED code — 「混合 diff 一条命中即整 PR 分叉」; this PR stays draft. - `pnpm check:pm-dispatch-gates` (named by the dispatch, outside the derived 19): detached at PR-open time; its verdict is reported in the `os-dev-report` comment, NOT MEASURED if the container cut it. Not run locally, by declaration: the repo-level `pnpm lint` sweep and the rest of CI's artifact-roster families — a Markdown-only diff under `.claude/` touches no package, so ① and ② of the local scope are empty. ## Acceptance notes - noted, not filed: the report JSON template in os-dev.md (:361-:377) carries no `deviations` field; `SKILL.md:536` names it as a field the dispatch adds (`gates / line_budget / deviations / files_changed`). The new :308 names the field as the dispatch does. 承接者: the skills seat, if the template should ever list it. - noted, not filed: the dispatch's byte readings for :67/:301/:305/:308 (114/115/115/120) each include the trailing newline; measured without it they are 113/114/114/119. 承接者:无. - noted, not filed: objectui's labeler runs `sync-labels: true`, so a dev-written `package: *` label that stops matching the diff is stripped on the next push — one more reason the objectui scope reads 「零写」. 承接者:无. ## 维护者速读(草稿) **改了什么**:只动 `.claude/agents/os-dev.md` 一个文件,403 行进 403 行出,四张卡合一。① 第 67 行:原来「永不编辑 `content/docs/releases/`」改成「永不在代码 PR 里改」,改错另开 docs-only PR —— 与 SKILL.md、AGENTS.md 已有的口径对齐;② 第 68 行:force-push 改为「按落地仓的 AGENTS.md」,并写明两种形态(objectui/cloud 绝对禁;objectstack 五条全立才 `--force-with-lease`);③ 第 301/309/310 行:打标签这一步写明仓别 —— objectstack 是 dev 的默认步骤,objectui 的路径标签归 labeler、派发词不点名就一个标签也不打;④ 第 308 行:新增「会话分类器拒了一笔外部写」这一格 —— 停手、把命令和拒因记进报告、交席位代做,⛔ 不换 curl/MCP/手工路线重发。 **为什么改**:①② 是维护者已裁的两条(#18854 裁决 B、objectui#9666 裁决 C),这里只是把裁决落到 dev 的角色文件;③ 是一处作用域写死 —— 同一份文件此前既说「本仓库打标签是你的步骤」,又只为 objectui 划了一个标签的例外,dev 在 objectui 得自己猜,实测 objectui 零门禁读 dev 打的标签;④ 是一次实测的绕过:一个 dev 被分类器拒了 `label-write.mjs` 之后用手在 REST 上重做了那四步,结果对了,但下一次的保障就只剩执行者的记性。 **风险与代价(含回滚)**:全是规则文本,不发布、不改代码。代价是第 304 行把「四步手写」换成点名 `scripts/pm/label-write.mjs`(那四步是它内建的),第 310 行把 objectui 的 `skip-changeset` 两行并成一行(丢的是「pin 测试钉着」这类证据句,不是规则)。回滚 = revert 这一个文件的三个 commit,零副作用。 **席位意见**:(留空) **你要做的**:确认四张卡的裁决/分诊意图都落到了对应行(67 / 68 / 301 / 308 / 309 / 310),然后按受管面流程由你合并;不需要任何决策 —— #19002 的作用域由两仓的机制决定,本 PR 没有替维护者预设答案。 --- _Generated by [Claude Code](https://claude.ai/code/session_01BTeBejoPUvRHN8WdAJC6oF)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9150b79 commit 87f776b

1 file changed

Lines changed: 9 additions & 9 deletions

File tree

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ model: opus
6464
- 就地修欠两样:认领申报的文件面同轮增补;PR 正文点名该修复并附证据。
6565
- 优先扩展一个守卫关掉整个类;任一条不成立 ⇒ 回默认:无 assignee 立单、列出、不碰。
6666
- 本轮改动令其变假或触碰的已发布缺陷必修;其余立卡并记明已发布面,PR 照常落地。
67-
4. ⛔ 永不编辑 `content/docs/releases/`、推 `main`、合并任何东西;force-push 只按 AGENTS.md §3。
68-
- 用户可见的改动需要 `.changeset/*.md`。
67+
4. ⛔ 永不推 `main`、合并任何 PR、在代码 PR 里改 `content/docs/releases/`;改错另开 docs-only PR。
68+
- force-push 按落地仓 AGENTS.md:objectui/cloud 绝对禁;objectstack §3 五条全立才 `--force-with-lease`。
6969
5. **Contract-first。** 修复若诱使你在消费端加宽容回退(`??` 别名、宽松解析),缺陷在上游。
7070
- 去生产者或 spec 修,或返回 `needs_decision`。
7171
6. **issue 正文是线索,不是规格。** 动手前对 `origin/main` 核验其前提。
@@ -295,19 +295,19 @@ model: opus
295295
- 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行。
296296
- ⛔ 不把不买内容的密度修复当筹行拒掉;删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬 ceiling。
297297
- 例外:派发令点名测量优先的零余量受管账本 ⇒ 落行、不动上限行、红着报实测行数。
298-
- `skip-changeset` 唯一判据:没有已发布的东西移动;已发布 = 各包 `files[]` 实际发运的内容。
298+
- 发布面动了要 changeset;`skip-changeset` 唯一判据是没动:已发布 = 各包 `files[]` 实际发运内容。
299299
- 快速通道:`docs/adr/**` · `.claude/**` · `scripts/pm/**` · 仓根配置 · 私有包 · 注释,不发布。
300300
- 其余实测:构建后 grep `files[]` 所列路径找符号,带正控;符号零命中、正控命中 ⇒ 不发布。
301-
- 本仓库:标签是真实机制,打标签是你的默认步骤,PR 一开出就打;派发词可收窄或禁写。
301+
- objectstack:标签是真实机制,打标签是你的默认步骤,PR 一开出就打;派发词可收窄或禁写。
302302
- 范围 = 派发词点名的标签 + 上文判据下的 `skip-changeset`;禁写或交集为空 ⇒ 零写并报告。
303303
- `needs:contract-review` 归席位,⛔ 不挂不摘不等;报 PR 上有无与 `--pair PR-NUMBER` 退出码作读数。
304-
- 写入首选加法端点(REST `POST .../issues/<n>/labels`,不碰已有标签);可达性按会话探,先探后用。
305-
- 被拒 ⇒ 报端点与状态码、席位代挂,⛔ 不报 `blocked`、不走 MCP;写后必做对比式读回。
306-
- 读回 diff 现集对 union(读集, 目标),缺者 = 被剥的标签,重挂,清单进报告;收尾再读一次。
304+
- 写恒经 `scripts/pm/label-write.mjs`:取现集、加法 POST、回读比 union、缺者重挂一次并报告。
307305
- 读回只检测剥除防不了(size-labeler 整组 PUT),门标签被剥恰成绿灯;加法写同样必要不充分。
308306
- 关此步骤的是读回不是写入;读回只验写落了,验不出有门在读:幻影门标签读回照样成功。
309-
- objectui:同名标签对象在,零 workflow/脚本读它、豁免不了任何东西,pin 测试钉着。
310-
- 那边用空 frontmatter 的 changeset 声明,门禁判定行是权威;⛔ 永不在 objectui 施加该标签。
307+
- 被拒 ⇒ 报端点与状态码、席位代挂,⛔ 不报 `blocked`、不走 MCP;收尾再读一次。
308+
- 分类器拒外部写 ⇒ 停手,`deviations` 记命令与拒因,席位代做;⛔ 不换路重发(curl/MCP/手工)。
309+
- objectui:路径标签归 `labeler.yml`,逐 push 同步;无门禁读你打的标签 ⇒ 派发词未点名即零写。
310+
- objectui 的 `skip-changeset` 零读者;空 frontmatter changeset 即声明,门禁判定行为准,⛔ 永不施加。
311311
- 报告在本地验证走完时交付,CI 收敛等待归 PM 不归你:⛔ 不为等 CI 结论推迟报告。
312312
- 门禁状态如实记录,`in_progress` 是诚实值;PR 开出后 ⛔ 永不 sleep、定时等待或空转轮询 CI。
313313
- 你报告之后才转红的门禁,会作为同一认领上的补丁轮回来。

0 commit comments

Comments
 (0)