Skip to content

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

Draft
os-justin wants to merge 1 commit into
mainfrom
claude/issue-18599-point-at-ablation-replace
Draft

os-justin wants to merge 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 <[email protected]>
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
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 needs-user-decision size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants