finding — two defects in ONE file, surfaced by the #19348 round's out_of_scope_findings (report 5770753883, PR #19640) and re-stated by the domain:spec seat, session session_01UDXER3sdqfeVYpEWZs5mZx. ⛔ Ungraded and unrouted: domain:*, type and priority are triage's. ⛔ Not claimed.
⚠️ Filed as one card on purpose, and triage may split it. Both defects live in scripts/ablation-replace.mjs and a taker fixes them in one pass. Filing two cards would manufacture a serial collision between them on the same file. They are nonetheless two distinct defects and are enumerated as such below.
⚠️ Both are reported by the dev; the seat re-states them and adds its own corroboration for ①. ⛔ Neither has been independently re-measured end to end by the seat — a taker re-measures before fixing.
① --restore restores from HEAD, not from the pre-mutation working copy — so it destroys an uncommitted edit while printing ok restored
Run over a tree carrying an uncommitted edit, --restore writes the HEAD blob over it and then compares only the post-restore blob against HEAD. That comparison succeeds by construction, so it reports success having silently discarded the author's work.
Measured by the round, quoting its report: it printed blob 4f6d6941d531 -> 22713e9104d8 going in and blob after restore 591ef264a023 coming out, compared only the latter against HEAD, and reported success; the uncommitted edit was gone.
Seat corroboration, first-hand and independent of the report. At 2026-09-22T03:22Z the seat found a stray 0-byte untracked file in the shared checkout named, literally, 22713e9104d8 going in and blob — the middle of that very log line, mangled into a filename by the calling shell. The seat inspected it (empty, untracked, 22713e9104d8 is not a valid git object in this repo) and removed it, restoring a clean tree. ⚠️ That is evidence the run happened and that this line was printed; it is ⛔ not evidence about the restore logic itself, which rests on the report.
Why it is worth fixing rather than documenting. The ablation discipline does require committing first, which makes this a gap rather than a contradiction — the tool is being used the way the discipline says not to. But the failure is silent and the loss is unrecoverable, and the tool already prints both blobs, so comparing them to each other is roughly one line. ⚠️ A dirty tree is also exactly the state a DELETE ablation's mutate leg is in by construction (that is what #19348 is about), so the two shapes meet.
Dedupe words: ablation-replace · --restore · restores from HEAD · uncommitted edit · ok restored
② Line 538 prints the follow-up pre-flight command using the SOURCE anchor — the one spelling that makes --absent pass vacuously
scripts/ablation-replace.mjs:538 hands the author the next command to run for a DELETE ablation, spelling the marker with the source anchor.
On any package whose build re-spells literals, that is precisely the spelling that makes the --absent dist reading pass vacuously — a marker that was never in dist under that spelling reads as "absent" and the ablation banks a green that measured nothing.
⭐ This is the same defect class #19348 just repaired one file over, from the other side. #19348 measured that the source spelling uses single quotes with a space after the colon while tsup emits double quotes with none, and that the dist and tree readings therefore demanded mutually exclusive spellings. PR #19640 gives ablation-dist-preflight.mjs a --source-marker flag so the two readings stop sharing one string. This file was never taught about it, so it still prints the wrong half of the pair. ⚠️ So the fix is likely cheap and already designed — teach line 538 to emit --source-marker — but that is the taker's call after reading PR #19640, ⛔ not a prescription from here.
Dedupe words: ablation-replace · line 538 · follow-up preflight command · source anchor · vacuous absent
Consumer, and why this is not cosmetic
Every agent running an ablation. The ablation is this repo's discriminating measurement — it is what separates "the fix works" from "something else was green anyway". ① loses work silently; ② returns a green that measured nothing. Both corrupt the instrument the evidence discipline leans on hardest.
Explicitly NOT in scope
Refs: #19348 / PR #19640 (the sibling repair and the --source-marker design) · #17508 (the round that first measured the re-spelling trap)
Generated by Claude Code
finding— two defects in ONE file, surfaced by the #19348 round'sout_of_scope_findings(report5770753883, PR #19640) and re-stated by thedomain:specseat, sessionsession_01UDXER3sdqfeVYpEWZs5mZx. ⛔ Ungraded and unrouted:domain:*,typeandpriorityare triage's. ⛔ Not claimed.scripts/ablation-replace.mjsand a taker fixes them in one pass. Filing two cards would manufacture a serial collision between them on the same file. They are nonetheless two distinct defects and are enumerated as such below.①
--restorerestores from HEAD, not from the pre-mutation working copy — so it destroys an uncommitted edit while printingok restoredRun over a tree carrying an uncommitted edit,
--restorewrites the HEAD blob over it and then compares only the post-restore blob against HEAD. That comparison succeeds by construction, so it reports success having silently discarded the author's work.Measured by the round, quoting its report: it printed
blob 4f6d6941d531 -> 22713e9104d8going in andblob after restore 591ef264a023coming out, compared only the latter against HEAD, and reported success; the uncommitted edit was gone.Seat corroboration, first-hand and independent of the report. At 2026-09-22T03:22Z the seat found a stray 0-byte untracked file in the shared checkout named, literally,⚠️ That is evidence the run happened and that this line was printed; it is ⛔ not evidence about the restore logic itself, which rests on the report.
22713e9104d8 going in and blob— the middle of that very log line, mangled into a filename by the calling shell. The seat inspected it (empty, untracked,22713e9104d8is not a valid git object in this repo) and removed it, restoring a clean tree.Why it is worth fixing rather than documenting. The ablation discipline does require committing first, which makes this a gap rather than a contradiction — the tool is being used the way the discipline says not to. But the failure is silent and the loss is unrecoverable, and the tool already prints both blobs, so comparing them to each other is roughly one line.⚠️ A dirty tree is also exactly the state a DELETE ablation's mutate leg is in by construction (that is what #19348 is about), so the two shapes meet.
Dedupe words:
ablation-replace·--restore·restores from HEAD·uncommitted edit·ok restored② Line 538 prints the follow-up pre-flight command using the SOURCE anchor — the one spelling that makes
--absentpass vacuouslyscripts/ablation-replace.mjs:538hands the author the next command to run for a DELETE ablation, spelling the marker with the source anchor.On any package whose build re-spells literals, that is precisely the spelling that makes the
--absentdist reading pass vacuously — a marker that was never indistunder that spelling reads as "absent" and the ablation banks a green that measured nothing.⭐ This is the same defect class #19348 just repaired one file over, from the other side. #19348 measured that the source spelling uses single quotes with a space after the colon while⚠️ So the fix is likely cheap and already designed — teach line 538 to emit
tsupemits double quotes with none, and that the dist and tree readings therefore demanded mutually exclusive spellings. PR #19640 givesablation-dist-preflight.mjsa--source-markerflag so the two readings stop sharing one string. This file was never taught about it, so it still prints the wrong half of the pair.--source-marker— but that is the taker's call after reading PR #19640, ⛔ not a prescription from here.Dedupe words:
ablation-replace·line 538·follow-up preflight command·source anchor·vacuous absentConsumer, and why this is not cosmetic
Every agent running an ablation. The ablation is this repo's discriminating measurement — it is what separates "the fix works" from "something else was green anyway". ① loses work silently; ② returns a green that measured nothing. Both corrupt the instrument the evidence discipline leans on hardest.
Explicitly NOT in scope
scripts/ablation-dist-preflight.mjs— that is ablation-dist-preflight --absent exits 1 on any dirty tree, so a DELETE ablation's mutate leg can never pass its own pre-flight #19348 / PR fix(scripts): split ablation-dist-preflight two readings so a DELETE ablation mutate leg can pass #19640 and is a live serial holder of that file.ablation-dist-preflight.mjsheader names.claude/skills/dogfood-verification/SKILL.mdas stating the script's invocation, and that file no longer mentions it; and the two documents that DO state it (.claude/agents/os-dev.md:255,packages/qa/dogfood/README.md:54) show only the default present-mode form..claude/**or doc surfaces with no behaviour attached; the round named the successor for the first as whoever lands ② (same header region) and NONE for the second.Refs: #19348 / PR #19640 (the sibling repair and the
--source-markerdesign) · #17508 (the round that first measured the re-spelling trap)Generated by Claude Code