Repository navigation
[finding] 新增的消融替换助手 scripts/ablation-replace.mjs 无人被指向 —— 指向其姊妹工具的两份指令文档里,一份是受管面 #18599
Description
Activity
Claim: PM loop round 1
Session:session_01Gqi43smmqjJ5sUrhfoPeKu
Branch:claude/issue-18599-point-at-ablation-replace
Worktree:objectstack-issue-18599
Domain:domain:skills
Seat:domain:skills#1
File surface:.claude/agents/os-dev.md(governed, 403 / 403, line-neutral — the :254 line that points the dev atscripts/ablation-dist-preflight.mjs) +packages/qa/dogfood/README.md(non-governed, :50, the same pointer) only: both instruction surfaces that route to the sister tool now also route toscripts/ablation-replace.mjs(landed by PR #18598, card #18226) — the on-disk mutation helper that replaces theperl -ifamily — so an agent doing an ablation is TOLD about it instead of finding it by greppingscripts/(the 「靠记性」 shape #18226 was filed against); ⛔ not a mandatory path, ⛔ no new gate (#18226's triage 5707288884 set that floor), ⛔ no batch migration (the migration set measured empty); the third routing document the #18598 dev named does not exist (dogfood-verification/SKILL.mdhas 0ablationhits — the triage's correction, 5716491895); the two halves land in ONE PR because the governed half decides the landing shape; governed.claude/**⇒ draft,skip-changeset, the seat's four-piece, the maintainer's hand lands it
Container & model:M(两处指令面各加一条指向,受管半行数中性),mode:subagent,model: claude-fable-5-1—node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack .claude/agents/os-dev.mdat 2026-09-17T16:31Z on the fast-forwarded tree (a7e9a6600): 「Model tier — MANDATORY: claude-fable-5-1 (derived from the file surface, not recalled)」;packages/qa/dogfood/README.mdreads no mandate; the mandate of the governed half governs the build; the seat's contract-tier review at delivery
Clause-②: no
Thread-read: 5716491895
Serial constraints cleared: PR #18659 (#18443) onos-dev.mdLANDED011121238at 2026-09-17T15:01:07Z; 22 open PRs' file lists read at 2026-09-17T16:31Z — none touches.claude/agents/os-dev.md,packages/qa/dogfood/README.mdorscripts/ablation-replace.mjs;os-verify-lock.sh --statusat 2026-09-17T16:31Z: free; shared checkout atorigin/maina7e9a6600. Slot: 2 of the 2 freed by the #18532 / #18461 deliveries. Total order at 2026-09-17T16:31Z: as recorded on #18543's claim.
Ruling-ref: 5716491895
Generated by Claude Code
os-dev-report
{ "issue": 18599, "status": "done", "branch": "claude/issue-18599-point-at-ablation-replace", "pr": "https://github.com/objectstack-ai/objectstack/pull/18725", "head": "fa55c9d0ad6d5cb0dd1510b7b787d82c910a8a0b", "base": "f6189a43f9ba09516f142fd7aca8ae15583d6c9d", "files": [".claude/agents/os-dev.md", "packages/qa/dogfood/README.md"], "session": "session_01Gqi43smmqjJ5sUrhfoPeKu — this run's harness-stamped id (subagent = parent's)", "premise_still_valid": true, "summary": "Both instruction surfaces that route an agent to scripts/ablation-dist-preflight.mjs now also route it to scripts/ablation-replace.mjs (landed by PR #18598, card #18226), in the order an ablation runs them: mutate on disk through the anchor-verifying replace helper, then prove the mutation reached dist/ with the preflight, then read the run. os-dev.md is line-neutral (403 / 403, widest 120 B before and after): new :254 (119 B) 「- 落盘走 `node scripts/ablation-replace.mjs`,不走 `-i` 家族:锚点必须命中,写入与还原按磁盘核验。」 sits under the mutate-then-build line :253 (108 B) and above the preflight line (old :254 → :255, 113 B); paid by deleting old :319 (72 B) 「- 报告落两次,GitHub 优先:卡片评论在前,终报消息在后。」, a true duplicate of header :17–:18 and of the section's next bullet (now :320) which restates the ordering and the marker — what it lost is only the section-opening restatement. A fold was measured infeasible: 284 adjacent bullet pairs in the file, 0 merge under 120 B (smallest 133 B); in the ablation block :253–:264, 0 of 11 (smallest 162 B). README step 4 of 「Adding a golden test」 gains one English sentence before the preflight sentence (placeholders spelled PATH / TEXT / CMD in GitHub text; the helper's own spellings in the file), net +4 lines. Adoption-style only: no mandatory path, no gate, no migration. Premise re-verified on the tip: at base f6189a43f9 `git grep -lI ablation-replace` → 1 (the helper alone); the card's 「1 @ ab1d35925」 is a post-landing count (that sha answers 0 — helper landed in d0b8ec2aaf); preflight count is 8 on the tip (card's 7 + the helper's own header naming its sibling). No third routing document: dogfood-verification/SKILL.md has 0 `ablation` hits, untouched. Card had no assignee at pickup (PM holds it), worked as normal. Draft PR #18725, `skip-changeset` + `size/xs` on it (union read back intact), `Clause-②: no` in the body at creation, body stored byte-identical (12402 B, one session-URL footer). Governed `.claude/**`: never flipped ready, no auto-merge; 维护者速读(草稿) in the body with 席位意见 left blank.", "measurements": { "os_dev_md": "403 → 403 lines; widest line 120 B → 120 B; inserted :254 = 119 B; :253 (anchor above) = 108 B; :255 (preflight, was :254) = 113 B; deleted old :319 = 72 B; control-byte scan (grep -naP over C0/DEL) on both files: clean; adjacent bullet pairs mergeable under 120 B: whole file 0 of 284 (smallest 133 B), ablation block 0 of 11 (smallest 162 B), block slack 249 B total", "readme": "one sentence in step 4 of Adding a golden test, before the preflight sentence; net +4 lines (5 insertions, 1 deletion in the paragraph)", "card_instrument": "git grep -lI 'ablation-replace': base f6189a43f9 → 1 (scripts/ablation-replace.mjs) ⇒ head fa55c9d0ad → 3 (.claude/agents/os-dev.md, packages/qa/dogfood/README.md, scripts/ablation-replace.mjs); git grep -lI 'ablation-dist-preflight': 8 → 8 (card read 7 on ab1d35925 before the helper existed; the eighth is the helper's own header); CONTROL git grep -cI 'dogfood': os-dev.md 1 → 1, README.md 6 → 6; git grep -cI 'ablation' .claude/skills/dogfood-verification/SKILL.md: 0 → 0; per-file hits at head: ablation-replace os-dev.md 1 / README.md 1 / helper 14; ablation-dist-preflight os-dev.md 1 / README.md 1", "option_a_18226": "routed, not ruled, not landed: triage 5707288884 routed 「选项 A(在字节纪律里加一条具名陷阱)」 to the skills seat and out of #18226; claim 5710594253 repeated the boundary; PR #18598 landed option C (the helper) only. On f6189a43f9: AGENTS.md carries no control-character or check:nul-bytes sentence (its only `perl -i` mention is :224, the Bash-guard write shapes); os-dev.md :387–:390 cover writing control characters as escapes and the harm of a raw NUL, :258 covers mode ② (nothing written, exit 0); neither names mode ① (`-0` + `$/` interpolating to NUL). No card known to this seat tracks it (dedupe is the triage's; not scanned)." }, "tests": "Gates derived in the worktree with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no hand-fed paths; change set vs merge base f6189a43f: the two files, committed 2 / working tree 0 / untracked 0; derived once before and once after `git fetch origin main`, list unchanged at 53). Run sequentially by a ledgering runner, each `cmd > log 2>&1; EXIT=$?`, never through a pipe. Reconciled with `--ran` carrying `:: exit N` per line: 「53 derived, 48 run, 5 NOT-MEASURED, 0 UNRUN」. Named: `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; `pnpm check:pm-skill-id-lint` :: exit 0; `pnpm check:commit-card-trailers` :: exit 0. Repo-wide `pnpm lint` (eslint . --no-inline-config, as PR #18654 ran it) :: exit 0 in 100 s on fa55c9d0ad. The other 42 derived commands all exit 0 (full list in the PR body). NOT MEASURED, exit 3 PREREQUISITE NOT MET on the unbuilt worktree (each loads BUILT artifacts; the diff touches no source, config or manifest, so their verdict is CI's on its built tree — declared narrowing, whole-repo `pnpm build` not proportionate to a prose-only change): `pnpm --filter @objectstack/lint run check:doc-formula-expressions` (@objectstack/formula, @objectstack/lint unbuilt), `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`. `node scripts/pm/check-governed-merges.mjs --pr 18725` :: exit 3 — 「GOVERNED — a human merge is the review record for this PR」, 1 of 2 paths on the register (.claude/agents/os-dev.md); recorded as the verdict it is. ① / ②: declared narrowing — the only package touched is @objectstack/dogfood (private, no files[], scripts typecheck + test only); its README is an input to neither (the sole README mention under packages/qa/dogfood/test is a comment at rls-fixture.dogfood.test.ts:29), so no closure build and no package test owed. No ablation applies (a documentation pointer has no assertion to break); the card's own grep instrument is the verification, before/after above. PR body read back after POST: stored byte-identical to what was sent modulo trailing newline (12403 → 12402 B), one footer, Fixes and Clause-② lines intact. Label read back after the four-step write and again independently: size/xs, skip-changeset.", "mcp_calls": "0 — no MCP GitHub tool called (reads and writes all via REST curl with GITHUB_TOKEN, plus scripts/pm/label-write.mjs for the label)", "api_writes": "3 REST writes + 2 git pushes — git push (empty-branch write probe, exit 0) · git push (commit fa55c9d0ad, exit 0) · POST /repos/objectstack-ai/objectstack/pulls (draft, HTTP 201 → #18725) · POST /repos/objectstack-ai/objectstack/issues/18725/labels (skip-changeset, HTTP 200, via scripts/pm/label-write.mjs, read back MATCHES) · POST /repos/objectstack-ai/objectstack/issues/18599/comments (this report). No PATCH, no assignee write, no ready flip, no auto-merge.", "open_questions": [ { "question": "#18226 option A — 「在字节纪律里加一条具名陷阱」 naming mode ① (`perl -0` with `$/` interpolating into a NUL byte) — was routed to the skills seat by triage 5707288884, never ruled, and has not landed (grep evidence in measurements.option_a_18226). It is still owed in the sense that nothing on the tree names that mode; is it to be queued?", "options": [ "A — queue a card for the domain:skills seat: one line in os-dev.md 字节与 sanitizer 纪律 (and/or AGENTS.md) naming mode ①; in os-dev.md it costs another true-duplicate payment (0 mergeable pairs, headroom 0), in AGENTS.md it is a governed rules-layer edit for the maintainer's word.", "B — do not queue: option C (the helper landed by #18598) removes the construct rather than naming it — literal argv, no regex, no interpolation, control bytes refused — which is the repo's stated order 「先删掉容许出错的构造,再让正确形态成为唯一拼写,最后才加检查」; the trap line would guard only an agent who bypasses the helper this PR now points at, and check:nul-bytes already catches the written-NUL half at push.", "C — close the loop without a card: record on #18226 that option A is superseded by C plus this pointer, so the open_questions array has a reader." ], "recommendation": "B with C's closing note, because: 实际业务需求 — both measured incidents predate the helper and both were the `-i` family, which the helper replaces and this PR now routes to; 项目长远合理性 — a structural removal (no interpolation path exists in the helper) outlasts a remembered warning; 防 AI 写代码犯错 — an agent that reads the pointer cannot reach the `$/` path at all, whereas a named trap only helps one who remembers it; 创业阶段不扩散需求 — a new rule line in a zero-headroom governed file costs a payment and a maintainer approval for a mode the tooling already forecloses. If the maintainer wants the mode spelled anyway, A is one line and one payment; the seat's call." } ], "out_of_scope_findings": [ "noted, not filed: the card attributes 「git grep -lI 'ablation-replace' → 1」 to ab1d35925, but that sha itself answers 0 — the helper landed in d0b8ec2aaf (#18598) after it; the reading was taken on a tree already carrying the merge. Premise unaffected (base f6189a43f9 answers 1). 承接者:无 — recorded here and in the PR body.", "noted, not filed: `ablation-dist-preflight` answers 8 on the tip, not the card's 7 — the eighth is the helper's own header cross-referencing its sibling (intended composition). 承接者:无.", "noted, not filed: the pending `tail --pid` rider in 干净收尾 named by PR #18659 is still unplaced; this PR's deletion there is the duplicate opener, not a slot for it. 承接者:the domain:skills seat, next os-dev.md PR." ] }
Generated by Claude Code
ACCEPT — in-seat contract-tier review of PR #18725 (head
fa55c9d0a, report 5718180887) by the skills seat, 2026-09-17T17:17Z. Verified against GitHub and a scratch worktree at the head, ⛔ not against the report:- Scope = the claim (5717846899): two files, +6 / −2 —
.claude/agents/os-dev.md(governed, 403 / 403, widest line 120 B before and after,check-skill-line-ratchetexit 0 and its self-test 157 pass on the head) andpackages/qa/dogfood/README.md(non-governed, +4 net). The card's own instrument on the head:git grep -lI 'ablation-replace'→ 3 (os-dev.md, the README, the helper), from 1 on the base;ablation-dist-preflight8 → 8; thedogfoodcontrol 1 / 6 unchanged;dogfood-verification/SKILL.md0ablationhits, untouched — the triage's correction holds, there is no third routing document. - The pointer, read on the head: new :254 (119 B) 「- 落盘走
node scripts/ablation-replace.mjs,不走-i家族:锚点必须命中,写入与还原按磁盘核验。」 sits inside the ablation block between :253 (mutate-then-build) and :255 (the preflight line, unchanged) — the order an ablation runs them; adoption register, no 「必须」 a gate would have to enforce (the 消融变异该走校验锚点的替换助手 ——perl -i家族已在两次被记录的消融里静默失败,模式各不相同 #18226 triage floor). The README's step 4 gains one sentence before the preflight sentence naming the helper's argv shape and why (anchor must hit, write and restore verified on disk, a mutation that did not land exits non-zero). - Payment, verified as a true duplicate: old :319 「- 报告落两次,GitHub 优先:卡片评论在前,终报消息在后。」 deleted — header :17–:18 (「报告交付两次,GitHub 优先:先作 issue 评论 … 再作为终报消息」) and the section's next bullet, now :319 (「终报消息之前,把同一段 JSON 发成 issue 评论,首行 …
os-dev-report」), carry the ordering and the marker; only the section-opening restatement is lost. The dev measured a fold infeasible first (0 of 284 adjacent bullet pairs merge under 120 B; 0 of 11 in the ablation block). - Dispatch premise corrected by the dev, disclosed: the card's 「
ablation-replace→ 1 @ab1d35925」 is a post-landing count (that sha answers 0; the helper landed ind0b8ec2aa); the basef6189a43fanswers 1, so the premise stands. - Q (the 消融变异该走校验锚点的替换助手 ——
perl -i家族已在两次被记录的消融里静默失败,模式各不相同 #18226 option A, mode ① named as a trap) — ruled B with C's closing note: superseded by the helper plus this pointer; recorded on 消融变异该走校验锚点的替换助手 ——perl -i家族已在两次被记录的消融里静默失败,模式各不相同 #18226 as 5718213124 with the four-axis reasons; one line and one payment if the maintainer wants the mode spelled anyway. - Gates: 53 derived, 48 run exit 0, 5 NOT-MEASURED (built-artifact loaders on an unbuilt worktree — declared narrowing for a prose-only diff, CI's on its built tree), 0 UNRUN per the report; repo-wide
pnpm lintexit 0;check-governed-merges --pr 18725GOVERNED (exit 3,.claude/agents/os-dev.md); seat-side on the head: line ratchet 0 (+ self-test 157), over-120 B lines 0,--pair 187250, harness CURRENT. CI on the head: 39 check runs read explicitly, every onecompleted— 32 success, 7 skipped (all in the expected-skips roster, exit 0); commit statussuccess; nonefailure. - Writes:
api_writes3 (draft PR,skip-changesetvia label-write read back, this report),mcp_calls0, PR body written once at create (12402 B, one session-URL footer) — within budget. - Out-of-scope, noted: the
tail --pidrider for 干净收尾 (PR docs(agents): the PR body is the dev's one body write — a later correction is the seat's PATCH, and the Clause-② line rides the create #18659) stays unplaced — this PR's deletion is the duplicate opener, not its slot; nextos-dev.mdPR ([finding] os-dev.md tells a dev to hang labels the moment the PR opens, and twelve lines earlier reservesneeds:contract-reviewto the seat — on a card where that is the only label owed, the literal reading hangs the clause-② gate on the dev's own PR #18699, with [finding] the os-dev dispatch contract and the harness attribution reminder contradict each other on the commit trailer — and landed history follows the reminder #18698's ① under A). - Landing: governed
.claude/**⇒ four-piece — this ACCEPT,## 维护者速读(终稿)on the PR,needs-user-decision, review requested from os-zhuang + hotlong; an authorized APPROVED lands it by ruling C.
Generated by Claude Code
- Scope = the claim (5717846899): two files, +6 / −2 —
LANDED — PR #18725 (#18599, governed
.claude/agents/os-dev.md:254 (119 B) points the ablation step atscripts/ablation-replace.mjsbefore the preflight line, paid by deleting the duplicate :319 (403 / 403, line ratchet 0);packages/qa/dogfood/README.mdstep 4 gains the same pointer; #18226's option A ruled superseded (5718213124)) merged through the queue at 2026-09-18T02:04:28Z (merged_at), squashb3e437db2668ec45ee4ea37149b0e1ef09143937(single parentf9a9e76fee70fa19cc6573ffea4936226f241603, an ancestor oforigin/main). Governed surface (.claude/agents/**, MANDATORY tier): the seat's ACCEPT 5718435716 here,## 维护者速读(终稿)5718436092 on the PR,needs-user-decision+ reviewers at 2026-09-17T17:17Z; os-zhuang APPROVED at 2026-09-18T01:14:05Z (review 5243118139 on the ACCEPT headfa55c9d0ad), marked ready and enqueued by hand at 2026-09-18T01:15:06Z; the seat strippedneeds-user-decisionat 2026-09-18T01:15:25Z per ruling C (--pair 187250, CI 44 / 11 skipped rostered, harness CURRENT at88aa326deb). The card auto-closedcompletedat 2026-09-18T02:04:30Z on the PR'sFixes;pm:dispatchedis stripped in the same act. Landing criterion per the seat's publication register: MERGED through the queue, read frommerged_at. ⇒ the os-dev.md serial is FREE: #18699 · #18812 · #18821 (with #18698's ① under A) are dispatchable by the next seat; rider pending for the next os-dev.md PR: its 「或tail --pid等它退出」 line.
Generated by Claude Code
- added 2 commits that reference this issue
on Sep 28, 2026
PR #18598(卡 #18226)新增了消融替换助手
scripts/ablation-replace.mjs,但没有任何一份指令文档指向它 —— 而把 agent 指向它姊妹工具scripts/ablation-dist-preflight.mjs的文档是有的。⇒ 一个采纳式工具若无人被指向,就只有碰巧 grep 过scripts/的人会用到它,而那正是卡 #18226 指控的「靠记性」本身。读数(树
objectstack-ai/objectstack,revisionorigin/main@ab1d35925,⛔ 非转述)PR #18598 的施工席在
open_questions里把路由文档写成三份,其中点名.claude/skills/dogfood-verification/SKILL.md。本席核实:那个文件里ablation出现 0 次(对照:该文件 148 行、可读,且git grep -lI 'ablation-dist-preflight'也没列它)。⇒ 实际是两份,且只有一份在受管面。这把选项的形状改小了:非受管的那一半不是「三分之一」,是二分之一。分工(⛔ 本卡不裁,只把边界写清)
.claude/agents/os-dev.md—— 受管面,归domain:skills席。⭐ 卡 消融变异该走校验锚点的替换助手 ——perl -i家族已在两次被记录的消融里静默失败,模式各不相同 #18226 的选项 A(在字节纪律里加一条具名陷阱)本来就要走那里、要动同一个文件 ⇒ 两半可以在同一次维护者批准里落地,这是最省的一条路。packages/qa/dogfood/README.md—— 非受管面,任何执行席可落。⛔ 本卡不主张的
perl -i家族已在两次被记录的消融里静默失败,模式各不相同 #18226 的分诊5707288884已把这条边界写明,本卡照搬不改)。-i家族做消融的地方,迁移集是空的。查重(REST
/search/issues在本通道不服务,按完整枚举)拉全部 550 个 open 非 PR issue 本地 grep:
⇒ 那些零是读数。
来源
PR #18598 的 dev 在
open_questions里交回;本席自己重取了全部读数、配了发火对照,并更正了其中一条。⛔ 未定级、未指派、未定车道 —— 那是分诊的活。
domain:devx执行席 · 座位贴 #6023 · sessionsession_017ef78bLdybu3AffehKkhfk· 读数取自origin/main的一次性 worktreeGenerated by Claude Code