Filed by the domain:devx PM seat from PR #10018 (#9977)'s H3, ruled A (file it, but only with a mechanical narrowing named up front, so the card has an affordable remedy rather than "read the whole merged file").
Two findings, related but separately actionable. The second is the cheaper one and does not depend on the first.
Finding 1 — regions git auto-merges with NO conflict marker never enter the resolver's view
A three-stage conflict resolution reviews what git marks. Regions git merges silently are invisible to every conflict-shaped review habit — there are no :1: / :2: / :3: stages to read, and nothing in the merge output names them.
Two instances, in one file, in one resolution — PR #9826:
| region | outcome |
|---|
the second unmarked region in check-cross-package-test-inputs.mjs | fatal — report() bound census twice; the merged file did not parse |
turbo.json | never conflicted at all, so no stages existed to read |
the @objectstack/spec rationale at L141 | cosmetic — a stale clause survived while its twin at L393 was corrected in the marked region |
That last row is the diagnostic one: the create-objectstack twin was fixed and the spec copy was not, which is exactly the split you get when a resolver reviews the three-stage view and a silently merged region never enters it.
⇒ a blind spot that produces both a cosmetic defect and a fatal one is not a prose-hygiene problem.
⚠️ How far the evidence reaches
PR #10018's dev was explicit, unprompted: "I did NOT reconstruct the merge geometry of PR #9826 (which hunks carried markers) — I verified the resulting tree, not the three-stage view, so the mechanism is corroborated by its outcome rather than measured directly."
So the mechanism is inferred from the outcome. First job for whoever takes this: reconstruct PR #9826's merge geometry and confirm which hunks actually carried markers. If the spec copy was inside a marked region, this card's premise is wrong and closing it is the right outcome.
The remedy — and it is already demonstrated
⛔ Do not propose "review the whole merged file." That is what makes this class unfixable in practice.
Diff the resolved file against BOTH parents and list every region no conflict marker covered.
PR #9826's resolver did exactly this by hand for turbo.json — a file that never conflicted, so had no stages — and proved 0 inputs and 0 task keys lost against either parent. The remedy is a mechanisation of a step that already works, not a new idea.
Shape to consider: a scripts/pm/ helper taking the merge commit, emitting the unmarked-region list. ⛔ Not a gate — a conflict resolution is a human/agent act with no committed artifact to check at CI time, and there is no population to scan.
⚠️ Also worth knowing before building: node --check (or the language's parse) catches the fatal half for free, and PR #9826's resolver ran it explicitly because of the earlier PR #9712 incident. So the remedy's marginal value is over the cosmetic half — price that honestly before building anything.
Finding 2 — the cross-reference is what rots, not the sentence
Independent of finding 1, and cheaper. From PR #10018's H2 sweep: the "named in a comment rather than read" rationale appears at 4 sites, all inside scripts/check-cross-package-test-inputs.mjs (L141, L238, L327, L393), plus one inverse statement at L386. 3 were still true; 1 was stale — and it had now gone stale twice in eight days (#9651 retired it once; PR #9826 dropped a second copy; PR #10018 fixed the third).
The three durable sites all cite check-nul-bytes.mjs, which is structurally mention-only — a gate script no test has a reason to read. The one site that reached for a different example is the one that rotted. They did not survive by being written better; their example cannot change status.
The discipline it yields
A rationale may cite a sibling path as an example only when that path is structurally unable to change status.
check-nul-bytes.mjs qualifies. A script under active test does not — and sync-template-versions.mjs is precisely that: packages/create-objectstack/src/template-version-stamps.test.ts:47 builds its path and :97readFileSyncs it.
Cheapest form: a line in that file's header, next to the four sites it governs. ⛔ Not a gate — "is this path structurally unable to change status?" is a judgement, and a recognizer for it would be narrower than the shapes it judges (#9747's standing family).
Refs: PR #10018 / #9977 (both findings, and the honest limit on finding 1's evidence) · PR #9826 / #9763 (both silent auto-merges, and the by-hand remedy) · PR #9712 / #9680 (the earlier fatal instance that made node --check routine) · #9651 (the first retirement of the stale clause).
Generated by Claude Code
Filed by the
domain:devxPM seat from PR #10018 (#9977)'s H3, ruled A (file it, but only with a mechanical narrowing named up front, so the card has an affordable remedy rather than "read the whole merged file").Two findings, related but separately actionable. The second is the cheaper one and does not depend on the first.
Finding 1 — regions git auto-merges with NO conflict marker never enter the resolver's view
A three-stage conflict resolution reviews what
gitmarks. Regionsgitmerges silently are invisible to every conflict-shaped review habit — there are no:1:/:2:/:3:stages to read, and nothing in the merge output names them.Two instances, in one file, in one resolution — PR #9826:
check-cross-package-test-inputs.mjsreport()boundcensustwice; the merged file did not parseturbo.json@objectstack/specrationale at L141That last row is the diagnostic one: the create-objectstack twin was fixed and the spec copy was not, which is exactly the split you get when a resolver reviews the three-stage view and a silently merged region never enters it.
⇒ a blind spot that produces both a cosmetic defect and a fatal one is not a prose-hygiene problem.
PR #10018's dev was explicit, unprompted: "I did NOT reconstruct the merge geometry of PR #9826 (which hunks carried markers) — I verified the resulting tree, not the three-stage view, so the mechanism is corroborated by its outcome rather than measured directly."
So the mechanism is inferred from the outcome. First job for whoever takes this: reconstruct PR #9826's merge geometry and confirm which hunks actually carried markers. If the spec copy was inside a marked region, this card's premise is wrong and closing it is the right outcome.
The remedy — and it is already demonstrated
⛔ Do not propose "review the whole merged file." That is what makes this class unfixable in practice.
Diff the resolved file against BOTH parents and list every region no conflict marker covered.
PR #9826's resolver did exactly this by hand for
turbo.json— a file that never conflicted, so had no stages — and proved 0 inputs and 0 task keys lost against either parent. The remedy is a mechanisation of a step that already works, not a new idea.Shape to consider: a
scripts/pm/helper taking the merge commit, emitting the unmarked-region list. ⛔ Not a gate — a conflict resolution is a human/agent act with no committed artifact to check at CI time, and there is no population to scan.node --check(or the language's parse) catches the fatal half for free, and PR #9826's resolver ran it explicitly because of the earlier PR #9712 incident. So the remedy's marginal value is over the cosmetic half — price that honestly before building anything.Finding 2 — the cross-reference is what rots, not the sentence
Independent of finding 1, and cheaper. From PR #10018's H2 sweep: the "named in a comment rather than read" rationale appears at 4 sites, all inside
scripts/check-cross-package-test-inputs.mjs(L141, L238, L327, L393), plus one inverse statement at L386. 3 were still true; 1 was stale — and it had now gone stale twice in eight days (#9651 retired it once; PR #9826 dropped a second copy; PR #10018 fixed the third).The three durable sites all cite
check-nul-bytes.mjs, which is structurally mention-only — a gate script no test has a reason to read. The one site that reached for a different example is the one that rotted. They did not survive by being written better; their example cannot change status.The discipline it yields
check-nul-bytes.mjsqualifies. A script under active test does not — andsync-template-versions.mjsis precisely that:packages/create-objectstack/src/template-version-stamps.test.ts:47builds its path and:97readFileSyncs it.Cheapest form: a line in that file's header, next to the four sites it governs. ⛔ Not a gate — "is this path structurally unable to change status?" is a judgement, and a recognizer for it would be narrower than the shapes it judges (#9747's standing family).
Refs: PR #10018 / #9977 (both findings, and the honest limit on finding 1's evidence) · PR #9826 / #9763 (both silent auto-merges, and the by-hand remedy) · PR #9712 / #9680 (the earlier fatal instance that made
node --checkroutine) · #9651 (the first retirement of the stale clause).Generated by Claude Code