Skip to content

docs(agents,dogfood): point both ablation instruction surfaces at scripts/ablation-replace.mjs beside its sibling preflight - #18725

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-18599-point-at-ablation-replace
Sep 18, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-18599-point-at-ablation-replace

Conversation

@os-justin

Copy link
Copy Markdown
Collaborator

Fixes #18599

Clause-②: no

Governed surface (.claude/**): draft, skip-changeset, an authorized approval lands it and the domain:skills seat lands it from there. File surface: .claude/agents/os-dev.md + packages/qa/dogfood/README.md only. Head fa55c9d0ad, base f6189a43f9 (origin/main at worktree creation; the card's readings were taken on ab1d35925 and re-read here on the tip). Line-neutral on the governed file: 403 / 403, widest line 120 B before and after, zero lines over the ratchet's 120-byte cap.

The defect

PR #18598 (card #18226) landed scripts/ablation-replace.mjs — the on-disk mutation step of an ablation: replace through an anchor that must hit, with the write and the restore verified against the disk rather than an exit code, in place of the sed -i / perl -i family that silently failed in two recorded ablations (2026-08-20, a -0 run whose $/ interpolated into a NUL byte; 2026-09-14, an argument swallowed and nothing written, exit 0). No instruction surface pointed at it, while the two that route an agent to its sibling scripts/ablation-dist-preflight.mjs do exist — so the helper could only be found by grepping scripts/, which is the memory-dependent shape #18226 was filed against. This PR adds the pointer to exactly those two surfaces, in the order an ablation runs the two tools: mutate on disk through the replace helper, then prove the mutation reached dist/ with the preflight, then read the run. Adoption-style only: not a mandatory path, no gate, no migration of existing ablation scripts (#18226's triage 5707288884 set that floor; the migration set measured empty in #18598's census).

.claude/agents/os-dev.md — one line in, one true duplicate out

Inserted, new :254 (119 B), directly under the mutate-then-build line of the ablation step (:253 「每一腿(变异与还原)都是:改动 → 证明它真落到了磁盘 → …」, 108 B) and above the preflight line (old :254, now :255, 113 B):

  • 落盘走 node scripts/ablation-replace.mjs,不走 -i 家族:锚点必须命中,写入与还原按磁盘核验。

-i 家族」 is the name the file's existing :258 already gives the trap (sedperl -istr.replacere.sub 零命中也 exit 0). The line is a routing line in the register of the preflight line beside it: one instrument, the reason in the same breath, no 「必须」, no gate.

Paid by deleting old :319 (72 B), the opening bullet of 「干净收尾」:

  • 报告落两次,GitHub 优先:卡片评论在前,终报消息在后。

What it lost: nothing the file does not state elsewhere, twice. Its three claims — two deliveries, GitHub first, comment before terminal message — are the header's :17 (「报告交付两次,GitHub 优先:先作 issue 评论,…」) and :18 (「…再作为终报消息…」), and the very next bullet of the same section (now :320, 「终报消息之前,把同一段 JSON 发成 issue 评论,…」) restates the ordering together with the marker. The section now opens on that bullet.

Why a payment and not a fold: measured on this tree, of the file's 284 adjacent bullet pairs ZERO merge under the 120-byte cap (smallest merged 133 B), and in the ablation block :253–:264 ZERO of 11 (smallest 162 B); the block's total slack is 249 B spread over lines holding 0–61 B each, none of which fits a 35-byte script path plus its reason. Re-wrap funding is refused by the ratchet rule in any case.

Whole file: 403 → 403 lines; widest line 120 B before and after; control-byte scan (grep -naP over the C0/DEL range) on both files: clean.

packages/qa/dogfood/README.md — one sentence

Step 4 of 「Adding a golden test」, placed before the existing preflight sentence (mutate, then prove dist/); the helper's usage placeholders are written as words here because the platform sanitizer eats tag-shaped fragments in a PR body — in the file they are the helper's own spellings:

Make the revert itself through node scripts/ablation-replace.mjs --file PATH --anchor TEXT --replacement TEXT -- CMD rather than sed -i / perl -i: the anchor must hit, the write and the restore are verified against the disk, and a mutation that did not land exits non-zero instead of handing you a green run.

Non-governed, no line budget, the README's English register. Net +4 lines in that paragraph.

Verification by the card's own instrument (tree objectstack-ai/objectstack)

reading card @ ab1d35925 base f6189a43f9 head fa55c9d0ad
git grep -lI 'ablation-replace' 1 as reported (that sha itself answers 0 — the helper landed in d0b8ec2aaf after it) 1 (the helper itself) 3.claude/agents/os-dev.md, packages/qa/dogfood/README.md, scripts/ablation-replace.mjs
git grep -lI 'ablation-dist-preflight' 7 8 (the card's 7 plus the helper's own header, which names its sibling) 8, unchanged
control git grep -cI 'dogfood' os-dev.md / README.md 1 / 6 1 / 6 1 / 6, unchanged
git grep -cI 'ablation' on .claude/skills/dogfood-verification/SKILL.md 0 0 0 — the third routing document named in #18598's report does not exist; not touched

Per-file hits at head: ablation-replace — os-dev.md 1, README.md 1, the helper 14; ablation-dist-preflight — os-dev.md 1, README.md 1.

#18226 option A — a reading, not implemented here

Option A (「在字节纪律里加一条具名陷阱」: name the perl -0 + $/-interpolates-to-NUL trap in the byte-discipline rules) was routed, not ruled, and has not landed. #18226's triage 5707288884 routed it to the skills seat (「选项 A(在字节纪律里加一条具名陷阱)要走 skills 席,⛔ 不在本卡内落地」), the claim 5710594253 repeated the boundary, and PR #18598 landed option C (the helper) only. On this tree: AGENTS.md carries no control-character or check:nul-bytes sentence at all (its only perl -i mention is :224, the Bash-guard write shapes); os-dev.md :387–:390 (字节与 sanitizer 纪律) covers writing control characters as escapes and the harm of a raw NUL, and :258 covers mode ② (nothing written, exit 0) — neither names mode ① (-0 + $/). Left untouched here (this card is the pointer only) and reported in open_questions for the seat to queue.

Gates (worktree at fa55c9d0ad; every exit code captured by redirect-then-$?, never through a pipe)

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from the worktree, no hand-fed paths (change set vs merge base f6189a43f: the two files; committed 2, working tree 0, untracked 0). 53 commands; reconciled with --ran carrying :: exit N per line: 53 derived, 48 run, 5 NOT-MEASURED, 0 UNRUN.

Named by the dispatch:

  • pnpm check:pm-skill-ratchet :: exit 0 — 「.claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0)」 · 「widest table row is 0 bytes (pin 0; headroom 0)」
  • pnpm check:nul-bytes :: exit 0 — 「OK (scanned 8814 text file(s) … no raw ASCII control bytes)」
  • pnpm check:agent-model-declared :: exit 0 — 「1 agent definition(s) under .claude/agents/ all declare a model」
  • pnpm check:pm-governed-merges :: exit 0 (the post-merge audit). node scripts/pm/check-governed-merges.mjs --pr NUMBER needs this PR's number, so it runs after creation; its verdict (expected GOVERNED, exit 3, which is a verdict and not a failure) is recorded in the report comment on the card.
  • pnpm lint (repo-wide, eslint . --no-inline-config, as PR pm(half-states): H19 founds every verdict on the set it judges #18654 ran it) :: exit 0, 100 s, on fa55c9d0ad

The other 43 that ran, all exit 0: check-ci-filter-parity, check-closing-keyword-parity (+ --self-test), check-comment-mask-adoption (+ --self-test), check-comment-mask-corpus, check-keyed-text-bounds (+ --self-test), check-platform-object-tenancy-census (+ --self-test), check-plugin-teardown-shape (+ --self-test), check-registry-log-declared (+ --self-test), check-rest-log-spy-declared (+ --self-test), check-system-context-census (+ --self-test), check-undeclared-dep-imports (+ --self-test), docs-audit/check-affected-docs, docs-audit/check-drift-comment, pm/check-governed-queue-guard --self-test, pm/check-harness-current --self-test, spec check:empty-state · check:liveness · check:strictness-ledger · check:variant-docs, check:agent-test-spelling, check:commit-card-trailers, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:org-identifier, check:page-declaration-shape, check:pm-skill-id-lint, check:published-files, check:refd-timer-probe, check:skill-frame-sync, check:slot-lookup, check:test-source-alias, check:tier-file-adoption, check:type-source-resolution, check:watch-hint-literal.

NOT MEASURED (exit 3, PREREQUISITE NOT MET — each loads BUILT artifacts and refuses on this unbuilt worktree; the diff touches no source, config or manifest, so their verdict is CI's on its correctly built tree): pnpm --filter @objectstack/lint run check:doc-formula-expressions (@objectstack/formula and @objectstack/lint not built), pnpm check:dts-closure, pnpm check:dual-build-cjs-loads (101 packages without dist/), pnpm check:lean-entry-closure (packages/objectql/dist absent), pnpm check:sourcemap-no-sources-content. Their only remedy is a whole-repo pnpm build, not proportionate to a prose-only change; declared, not hidden.

① / ②: the only package touched is @objectstack/dogfood (private, no files[], scripts typecheck + test only); the README is an input to neither (the sole README mention under packages/qa/dogfood/test is a comment in rls-fixture.dogfood.test.ts:29), so no closure build and no package test is owed — a declared narrowing.

skip-changeset: .claude/** is on the fast lane and @objectstack/dogfood is private with no files[] — nothing published moves.

Acceptance notes

维护者速读(草稿)

改了什么 — 只动两处文档。.claude/agents/os-dev.md(行数不变 403 / 403)在消融步骤里加一行,把 dev 指向 PR #18598 新落地的锚点核验替换助手 scripts/ablation-replace.mjs,与已有的 ablation-dist-preflight.mjs 指向并排、按消融实际执行顺序(先落盘变异、再证明到达 dist/、再读结果);付账是删掉「干净收尾」节开头一条与文件头部及同节下一条重复的「报告落两次」句。packages/qa/dogfood/README.md 的「Adding a golden test」第 4 步加一句同样的指向。

为什么改 — 这个助手落地了,却没有任何一份指令文档指向它;而指向其姊妹工具的文档有两份。一个采纳式工具若无人被指向,只有碰巧 grep 过 scripts/ 的人会用到 —— 这正是卡 #18226 要消灭的「靠记性」。⛔ 不做成必经路径、不加门禁、不批量迁移旧消融脚本(#18226 分诊已定这条地板)。

风险与代价(含回滚) — 零代码、零 changeset、零门禁改动;唯一的内容损失是被删的那条重复句,它的三个主张在文件头部(:17–:18)与同节下一条(:320)各有原文。回滚 = revert 本 PR,无其它文件牵连。

席位意见 — (留空,席位定稿)

你要做的 — 读新 :254 一行与被删 :319 一行;批准即由席位落地。若不同意付账形态,点名另一条重复句,席位代改。


Generated by Claude Code

…ipts/ablation-replace.mjs beside its sibling preflight

The two documents that route an agent to `scripts/ablation-dist-preflight.mjs`
now also route it to `scripts/ablation-replace.mjs`, in the order an ablation
runs them: mutate on disk through the anchor-verifying helper, then prove the
mutation reached `dist/` with the preflight, then read the run.

`.claude/agents/os-dev.md` stays line-neutral (403 / 403): the new pointer sits
under the mutate-then-build line of the ablation step; it is paid for by
deleting the 干净收尾 opener that restated the header's two-delivery rule and the
following bullet's ordering. `packages/qa/dogfood/README.md` gains one sentence
in step 4 of "Adding a golden test", beside the existing preflight sentence.

Adoption-style pointer only: not a mandatory path, no gate, no migration of
existing ablation scripts.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu
@os-justin os-justin added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 17, 2026 — with Claude
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/qa/dogfood/README.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/qa/dogfood/README.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 2 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 02e19a796c0de5e06bb3b260994850257f2ac17cpackageMentionDocs.

Copy link
Copy Markdown
Collaborator Author

维护者速读(终稿)

skills 席 session_01Gqi43smmqjJ5sUrhfoPeKu,2026-09-17T17:17Z。对照本席自己读的 diff 校正 dev 草稿;席位意见已填。

改了什么 — 两处把 agent 指向姊妹工具 ablation-dist-preflight.mjs 的指令面,现在也指向 PR #18598 新落的 scripts/ablation-replace.mjs:os-dev.md 消融段新增 :254「落盘走 node scripts/ablation-replace.mjs,不走 -i 家族:锚点必须命中,写入与还原按磁盘核验。」(119 B),位置在「改动→证明落盘→build」与「再证明到达 dist/」之间,即消融的执行顺序;为保 403 行,删掉 :319「报告落两次,GitHub 优先……」—— 本席核对它是头部 :17–:18 与下一条 bullet 的原样复述,是真重复(dev 先量了折行:全文 284 对相邻 bullet 无一能合进 120 B)。dogfood README 第 4 步加一句英文,说明该助手的调用形状与为什么(锚点必须命中、写入与还原按磁盘核验、没落盘就非零退出)。

为什么改 — 新工具若无人被指向,只有碰巧 grep 过 scripts/ 的人会用 —— 正是 #18226 要消灭的「靠记性」。实测:git grep -lI 'ablation-replace' 从 1(仅它自己)到 3;dogfood-verification/SKILL.mdablation 0 次,dev 报告里的「第三份路由文档」不存在(分诊已更正)。

风险与代价(含回滚) — 两行指向,不设必经路径、不加门禁、不迁移旧脚本(迁移集实测为空);行数中性、线宽 ≤120 B、line ratchet 绿;门禁 48 族绿、5 族需构建产物留给 CI。回滚 = revert 一个提交。顺带一件已结的:#18226 的选项 A(在字节纪律里点名 perl -0 的 NUL 陷阱)本席判为被助手 + 本指向取代、不立卡,记在 #18226(5718213124);您要它写进去,一行一付即可。

席位意见 — 荐合。把已落地的正确形态写进 dev 每次都读的那份定义,是最小改动。

你要做的(一个动作) — Approve 本 PR(或直接人工合并);席位随后按裁定 C 落地。


Generated by Claude Code

This was referenced Sep 17, 2026
This was referenced Sep 17, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review September 18, 2026 01:14
@os-zhuang
os-zhuang enabled auto-merge September 18, 2026 01:14
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit b3e437d Sep 18, 2026
48 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-18599-point-at-ablation-replace branch September 18, 2026 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants