Skip to content

Commit 6db53ac

Browse files
docs(os-dev): admit the ruled ceiling raise in the ratchet block and point at the ratchet header (#23868)
Fixes #23770 Clause-②: no ## What lands Two lines of the ratchet block in `.claude/agents/os-dev.md` (L296–L297 on the base) are rewritten in place. Net 0 lines (404 → 404), no `CEILINGS` row moves, no line is freed or added, and the file is the only path in the diff. - L296 before (90 B): `` - 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行。 `` - L296 after (120 B): `` - 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行;不买者 ⛔ 不当筹行拒。 `` - L297 before (116 B): `` - ⛔ 不把不买内容的密度修复当筹行拒掉;删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬 ceiling。 `` - L297 after (117 B): `` - 删不出等量内容 ⇒ 报 `blocked`,⛔ 不自抬 ceiling;裁决记录下令写入者除外(见棘轮头部)。 `` Every byte reading is `LC_ALL=C awk length` on the file at `7ba991b9a`. ## Why The stale clause told a dev 「删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬 ceiling」 with no exception, while ruling record 6184799323 on #23606 (letter B, item 1, maintainer 「同意」) admits one: a ruling of record that orders text into a ratcheted file authorizes the raise, quoted with its id and measured delta in the raising PR. The ruling's single source in the tree is the ratchet header (`scripts/pm/check-skill-line-ratchet.mjs`, section 「The ratchet discipline」, the RAISING bullet, L66–77 on this base) and the `SKILL.md` guard-index row (L291). The new L297 admits the exception in one clause and points at the header — it restates nothing: the form (ruling id plus delta in the PR body; at most that delta; no tolerance band) stays where it is landed. What each clause keeps (dispatch §2(d)): - 「删不出等量内容 ⇒ 报 `blocked`」 — a dev with no ruling behind its lines still reports `blocked` when it cannot delete equal content. - 「⛔ 不自抬 ceiling」 — never on its own word, never on a dispatch word alone (a dispatch order is not a ruling of record). - 「裁决记录下令写入者除外(见棘轮头部)」 — the one admitted raise: text a ruling of record ordered written; its form is the header's. - The exception sits after both prohibitions behind a 「;」 so it governs both: with ruled text, neither 「报 `blocked`」 nor 「不抬」 applies, and the ruled raise is the route. - 「头部」 rather than the card's 「头注」: the file already names script headers 「头部」 twice (L1 and the nul-bytes rule), so the pointer reads like the others. ## Paying for the bytes — a move within the block, not a deletion and not a raise Measured first, as dispatch §3 asked: keeping L297's first clause and appending the ruled-raise tail lands at 179 B; the card's example tail alone, as a line, at 126 B; the tightest tail that keeps 「报 `blocked`」, the ⛔ and the header pointer at 117 B. So the first clause 「⛔ 不把不买内容的密度修复当筹行拒掉」 could not stay on L297. Instead of deleting it, it moves onto L296, compressed to 「不买者 ⛔ 不当筹行拒」 — the same permission (a density edit that buys no content is not refused as a 筹行), now beside the dividing line whose negative branch it is (「分界只问折行有没有为新增内容买行」). L296 goes 90 → 120 B. Nothing is dropped, so no deletion is named and no single source is claimed for one. Why this is not re-wrapping: 「新增以删减付账」 and the ⛔ on re-wrap are about LINES — merging lines to free one and spending it on new content. Here no line is freed and no line is added; two adjacent rule lines are edited in place under the ratchet header's 120-byte line convention (its 「Why 120 bytes」 section). The ratchet's count is unchanged, so there is nothing to pay. - No `CEILINGS` move: no ruling orders this text, so item 2 of the ruling applies. - L294 (the PM's net budget, 「抬它归维护者」) and L298 (the measurement-first exception) are untouched; neither is the `CEILINGS` clause. ## Mechanism assumptions (dispatch §2), measured on the base - (a) holds. `origin/main` moved `0af559e80` → `f7e836da1` (PR #23751) between the order and this branch; `git diff 0af559e f7e836d -- .claude/agents/os-dev.md` is empty. 404 lines, L297 at 116 B, headroom 0, L292–298 as the order read them. - (b) holds. Both sources re-read on `f7e836da1`: the ratchet header's RAISING bullet (L66–77; the paragraph runs two lines past the card's L75) and the `SKILL.md` guard row (L291: 「抬上限凭下令写入的裁决记录……无裁决 id 即红……不买内容的密度修复允许」). - (c) holds, and the suggested route in §3 does not: the first clause cannot stay (179 B). Net 0, every edited line at most 120 B, no `CEILINGS` move, no re-wrap. No deletion was needed, so none is named. - (d) preserved — the clause-by-clause reading above. No conflict between the file's current text and the order was met: the order's budgets add to the file's rules without contradicting any line of it. ## Verification (final head `7ba991b9a`) Ratchet verdict for the file, plain run, exit 0 both times: - before (`f7e836da1`): `✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 404 lines (ceiling 404; headroom 0).` - after (`7ba991b9a`): `✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 404 lines (ceiling 404; headroom 0).` - `pnpm check:pm-skill-ratchet` (self-test then gate): `✓ check-skill-line-ratchet self-test: 164 cases pass.` and the line above; exit 0. Derived gates: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths at `7ba991b9a` derived 20 commands, identical to the dispatch order's list. All 20 ran locally, each exit code captured before any pipe (output redirected to a log first, the status read next), all exit 0. Reconciliation: `Run reconciliation — 20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN.` exit 0. - `pnpm --filter @objectstack/lint run check:doc-formula-expressions` needs `@objectstack/formula` and `@objectstack/lint` built: their dependency closures were built under the verify lock (`VERDICT command-exit 0 · held the lock 112s · waited 0s`), then the gate exited 0. A first attempt without the closure stopped at `tsup` dts on an unbuilt `@objectstack/spec` (`VERDICT command-exit 1`) — a build-order fact, not a measurement, superseded by the closure build. - `pnpm check:pm-skill-id-lint`: `✓ check-skill-id-lint: 87 file(s) clean` — no issue number enters the operating text (the ruling is reached through its header, not by id). - `pnpm check:skill-frame-sync`: exit 0 — the file carries no second copy of the decision frame. - `pnpm check:nul-bytes`: exit 0; the edited file also passes the raw control-byte grep from the file's own byte discipline (no match). - Local-only families (readings only): `pnpm check:skill-frame-freshness` exit 0 (`1/1 framework files are byte-identical to the ref`). `pnpm check:dev-prereqs` exit 1 — 「The workspace is not built — 1 unmet precondition」: 65 of 69 packages have no `dist/` in this fresh worktree, where only the formula/lint closure was built. A box-state reading, not a verdict on the diff; CI's fresh checkout builds the workspace. - Clause ⑤ (a gate or tool script edited): not owed — the diff touches no script. - No ablation: the diff changes no tested behaviour (a rule line in an agent definition). - CI runs the full farm; this PR's check-runs are the record for every family CI runs. ## Acceptance notes - The report-JSON template in `os-dev.md` names no `deviations`, `line_budget` or `files_changed` key, while dispatch §7 asks for them as machine-checkable fields and the file's own L139 writes to `deviations`. PR #23766 noted the `deviations` half. Out of scope here and untouched; the report carries the keys anyway. Carrier: none — noted, not filed. - The ratchet prints an info line for `.claude/skills/spec-property-retirement/SKILL.md` (max-table-row pin 326, measured 324: 「lower the pin to 324」) — an opportunistic tightening the gate itself suggests, on a path not this card's. Carrier: none — noted, not filed. - No changeset: the diff publishes nothing (`.claude/**`). The `skip-changeset` label is the seat's to write; this PR writes no label. - Governed, Tier S (`.claude/**`): lands by the owning seat after an at-tier `## Contract review` PASS. The draft stays a draft; no auto-merge, no reviewer request. ## 维护者速读(草稿) - **改了什么**:改开发 agent 工作契约(`.claude/agents/os-dev.md`)里关于「行数上限」的两行。原来写死「删不出等量内容就报 blocked,绝不抬上限」;现在加上唯一的例外——维护者裁决记录下令写进去的文字,可以按棘轮门禁脚本头部写明的格式抬上限(PR 正文引裁决评论 id 与实测增量)。另一句「不买内容的密度修复不拒」原样保留,只是挪到上一行并压缩。总行数不变、上限不动、不发布任何包。 - **为什么改**:这条规则早于您的裁决(记录 6184799323,B 项),与裁决矛盾:按字面读,开发 agent 遇到裁决下令的加行也会报 blocked 停工(上一张卡 PR #23766 的 agent 正是读到这里、在 PR 里点名冲突后才照裁决做的)。把契约文字和裁决对齐,后续 agent 不再卡在这一句;规则本身不复述裁决,只指向它的唯一出处(棘轮脚本头部),两处文字不再各自漂移。 - **风险与代价(含回滚)**:零运行时影响,只改 agent 读的文字。风险在措辞:压缩后的「不买者 ⛔ 不当筹行拒」依赖同一行前半句的语境,席位复核若认为不够清楚可再调;该行已顶满 120 字节(120/120),再加字需另起一行。回滚 = revert 本 PR,两行各回原文。 - **席位意见**:(留空) - **你要做的**:无需操作;本 PR 为 Tier S,由席位在达档复核 PASS 后入队落地。 --- _Generated by [Claude Code](https://claude.ai/code/session_01VqGhCg9wdsBXPz54uAEWg7)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 41e84c0 commit 6db53ac

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ model: opus
293293
- 行数为准,姊妹门禁定义 token 计数后同报 token。
294294
- 净增预算装不下 ⇒ 按 `blocked` 报缺口;⛔ 不自行扩写或抬预算:预算归 PM,抬它归维护者。
295295
- 付行数棘轮的唯一合法货币是删内容:⛔ 不拿 re-wrap(折行合并)当筹行,新增以删减付账。
296-
- 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行。
297-
- ⛔ 不把不买内容的密度修复当筹行拒掉;删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬 ceiling。
296+
- 密度优化只随净减内容的 PR;分界只问折行有没有为新增内容买行;不买者 ⛔ 不当筹行拒。
297+
- 删不出等量内容 ⇒ 报 `blocked`,⛔ 不自抬 ceiling;裁决记录下令写入者除外(见棘轮头部)。
298298
- 例外:派发令点名测量优先的零余量受管账本 ⇒ 落行、不动上限行、红着报实测行数。
299299
- 发布面动了要 changeset;`skip-changeset` 判据是没动:已发布 = 各包 `files[]` 实际发运内容。
300300
- 快速通道:`docs/adr/**` · `.claude/**` · `scripts/pm/**` · 仓根配置 · 私有包 · 注释,不发布。

0 commit comments

Comments
 (0)