Repository navigation
Commit 9a1d934
docs(os-dev): run the scoped platform-checklist check before push on an exported-symbol rename or removal (#23766)
Fixes #23665
Clause-②: no
## What lands
Two rule lines in `.claude/agents/os-dev.md` 〈本地验证范围〉, right after the
trigger-shaped line (`新 fake engine ⇒ …`) and before ④:
- `` - 改名或删除导出符号 ⇒ push 前跑 `node scripts/check-platform-checklist.mjs
--changed-from origin/main`。 `` — 119 B
- `` - 判定行原样记 `gates`;它非派生族,不在 `--commands` 清单,`--ran` 只把它列为派生外、不报错。 ``
— 119 B
They implement ruling record 6190922830 on #23653 (letter C, item 3;
maintainer 「C (推荐)」, 2026-10-15), verbatim:
> 3. **The dev-contract line** (`.claude/agents/os-dev.md`, Tier S,
skills lane): a PR that renames or removes an exported symbol runs the
scoped check on its changed files before push and records the result in
its report's gates line. One line, landing after item 1.
The command is the scoped mode's own spelling
(`scripts/check-platform-checklist.mjs`, header section "The scoped
mode", landed by PR #23677). Item 2 of the same ruling stands: no
`dispatch-gates.mjs`, `dispatch-gates.data.mjs` or
`dispatch-gates.self-test.mjs` edit, no derived family, no CI or
workflow change, and no edit to `docs/qa/platform-checklist/README.md`.
The trigger is decidable from the author's own diff (an `export`ed
symbol renamed or removed); it is deliberately not "every PR", so the
line stays a dev-contract duty and never a de facto gate on every push.
## Paying for the lines — route taken: ruled raise, not deletion
`os-dev.md` stood at 402/402 (headroom 0) on `origin/main` `140238a47`.
The `.claude/agents/os-dev.md` row of `CEILINGS` in
`scripts/pm/check-skill-line-ratchet.mjs` moves 402 → 404, delta +2,
with a comment block above the row in the shape of the
`execution-duties.md` precedent (PR #23676).
- Ordering ruling: record 6190922830 on #23653, letter C, item 3 (quoted
above).
- Authorizing ruling: record 6184799323 on #23606, letter B, item 1
(maintainer 「同意」, 2026-10-15), verbatim: 「A ruling of record that orders
text into a ratcheted file is the authorization to raise that file's
ceiling by the measured lines the text needs: the raising PR quotes the
ruling comment's id and the measured line delta in its body, and moves
the `CEILINGS` row in the same PR by at most that delta. No second word
from the maintainer is needed.」
- Measured delta: +2 (402 → 404). The ruling sized the text as "one
line"; under the ratchet's 120-byte cap the ruled content does not fit
one. Measured: the command alone is 70 B in its code span; the dispatch
order's example spelling is 137 B; the tightest one-line spelling that
keeps the verbatim command, the trigger and the `gates` clause is 125 B
(`` 改名或删导出符号 ⇒ push 前 `…`,记 `gates`。 ``). Trigger plus command alone
lands at 119 B, so the `gates` clause and the not-a-derived-family
reading take the second line (119 B). Every byte reading is `LC_ALL=C
awk length` on the file.
- Not taken: deletion. The file is rules-only, one rule per line; a full
read on the base found no duplicated rule and so no lossless deletion.
No neighbour was re-wrapped.
- `os-dev.md` is not a `CROSS_FILE_MOVES` destination, so no
`ruledRaises` record applies.
## Verification (final head `5e548689e`)
Ratchet, before → after (plain run, exit 0 both):
- before: `✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 402
lines (ceiling 402; headroom 0).`
- after: `✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 404
lines (ceiling 404; headroom 0).`
- `node scripts/pm/check-skill-line-ratchet.mjs --self-test` → `✓
check-skill-line-ratchet self-test: 164 cases pass.` exit 0, before and
after.
Live proof of the new line's own command, run as written on this branch,
exit 0: `check-platform-checklist --changed-from origin/main: 0 anchored
files in the change set — nothing judged. 2 changed file(s) since merge
base 140238a, and none of them is the target of a checklist symbol
anchor.` (followed by the mode's standing caveat that this is not the
full gate's verdict).
Mechanism reading for "records the result in its report's gates line":
`--ran` neither refuses nor warns on an extra command. With `node
scripts/check-platform-checklist.mjs --changed-from origin/main :: exit
0` appended to the run record, `dispatch-gates --ran` still exits 0,
keeps `39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN`, and prints `Outside
this card's derivation (1) — recorded, and named by nothing this run
derived. Not an error: a run beyond the union costs nothing.` Hence the
second line: the verdict line goes into `gates` verbatim; the run is not
a derived family and does not enter reconciliation.
Derived gates: `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` with no paths, at `5e548689e`, derived 39
commands (identical to the dispatch order's list). All 39 ran locally
with exit codes captured before any pipe; reconciliation: `Run
reconciliation — 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN.` exit 0.
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions`
first exited 3 (PREREQUISITE NOT MET: `@objectstack/formula` and
`@objectstack/lint` not built). Built both under the verify lock
(`VERDICT command-exit 0 · held the lock 11s · waited 0s`) and re-ran:
exit 0. The exit-3 reading is not a measurement and was replaced in the
record.
- `pnpm check:pm-dispatch-gates` (fast tier, 1884 cases, 229.4 s on this
box): exit 0.
- `pnpm check:pm-skill-id-lint`: `✓ check-skill-id-lint: 87 file(s)
clean` — no issue number entered the operating text.
- Clause ⑤ (a gate script was edited): the ratchet has no `*.test.ts`;
its own suite is its `--self-test` (164 cases, exit 0), and the one
other test file naming it, `scripts/pm/dispatch-gates.self-test.mjs`,
ran inside `check:pm-dispatch-gates` (exit 0).
- Local-only families `check:dev-prereqs` and
`check:skill-frame-freshness` are not owed: the diff touches neither
`packages/spec` nor a four-axis frame file.
- CI runs the full farm; this PR's check-runs are the record for every
family CI runs.
## A conflict named, not quietly settled
`os-dev.md` L295 (unchanged here) reads 「删不出等量内容 ⇒ 报 `blocked`,⛔ 不抬
ceiling」, and L186–187 make the file win over a dispatch word and
require conflicts to be named. The raise route here follows ruling
record 6184799323 (letter B, item 1) and the ratchet header that lands
it; both post-date L293–295 and explicitly admit a ruled raise, and item
5 of that ruling names `os-dev.md` lines among the raises in force. The
clause is stale against the ruling; rewording it at equal line count is
a separate skills-lane act, not this card's. L296's exception (land the
line, leave the row, report red) does not apply: the dispatch order
names the raise route, not measurement-first.
## Acceptance notes
- `os-dev.md`'s report JSON template has no `deviations` key while L139
and other lines name one (dispatch §2(e)). Out of scope here and
untouched; neither new line references `deviations`.
- The ratchet's `--self-test` case "every live ruled-raise record quotes
its ruling" covers `ruledRaises` records on `CROSS_FILE_MOVES`
destinations. An ordinary raise's comment block is read by the seat's
contract-review record and the queue guard's reader, not by the script
(ratchet header, ruled-raise clause).
- No changeset: the diff publishes nothing (`.claude/**`,
`scripts/pm/**`). The `skip-changeset` label is the seat's to write.
- Governed, Tier S (`.claude/**`): lands by the owning seat after an
at-tier `## Contract review` PASS. The draft stays a draft; no
auto-merge is armed.
## 维护者速读(草稿)
- **改了什么**:给开发 agent 的工作契约(`.claude/agents/os-dev.md`)加两行规则:凡 PR
改名或删除了导出符号,push 前先跑一遍平台测试清单的「只看改动文件」模式,并把判定行原样写进报告的 `gates`
字段;同时把该文件的行数上限从 402 抬到 404(按裁决记录授权的抬高,附测量说明)。
- **为什么改**:平台测试清单反复变红,根因常是某个 PR 改名/删除了清单锚定的符号,而清单不是逐 PR
门禁,红只在合并后被日巡发现。裁决选了「不加门禁、加开发契约」:让作者在 push 前自己跑一次范围检查,把发现提前到合并之前。
- **风险与代价(含回滚)**:零运行时影响,不发布任何包;只给开发 agent 增加一步秒级自检。两行而非一行,是因为 120
字节的单行上限装不下完整命令加说明;上限抬 2 行按裁决记录授权。回滚 = 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 49700e4 commit 9a1d934
2 files changed
Lines changed: 23 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
| 142 | + | |
| 143 | + | |
142 | 144 | | |
143 | 145 | | |
144 | 146 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1432 | 1432 | | |
1433 | 1433 | | |
1434 | 1434 | | |
1435 | | - | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
1436 | 1456 | | |
1437 | 1457 | | |
1438 | 1458 | | |
| |||
0 commit comments