INSTR-01: grade diff()'s suppression rule at the level it is written at, one case per clause #72

Merged
admin merged 3 commits from INSTR-01 into release/1.0 2026-09-09 01:05:37 +02:00
Owner

SAFETY-44 produced three inert controls for this one rule, each inert differently, and split the two remaining fixes out rather than ship them unmeasured. This is that card.

Why the end-to-end route could never have worked

moved_to is one comprehension carrying five conditions with five different reasons to exist, and run() builds both snapshots from one state file. So "the destination was already latched" and "the destination was made by this transition" are the same file answering two incompatible questions: the arrangement that reaches one forecloses the other. That is why rebuilding a fixture to reach clause N kept moving the others — it is not a fixture problem.

The rule is now graded where it is written

diff() on constructed Snapshots, one case per clause. On the shipped tree, before any fix, the table already separated both known defects:

row shipped answer
R1 rename (legitimate) migrated correct
R2 narrowing vanished correct
R3 provenance migrated ⚠️ the defect
R4 same value vanished correct
R5 injectivity both migrated ⚠️ the defect
R6 machine_read vanished correct

The two reverted one-line fixes are back; R3/R5 flip, R1/R2/R4/R6 do not — the legitimate rename is still suppressed, so this is not an over-correction.

And each clause removal flips exactly its own row — the acceptance criterion this card was filed with:

C1 machine_read  -> ['R6-machine-read']      C6 injectivity -> ['R5-injectivity']
C3 same value    -> ['R4-value']             C7 provenance  -> ['R3-provenance']
C5 off-roster    -> ['R2-narrowing']

M12 is deleted, and that is the finding

M12 was SAFETY-44's end-to-end control for the narrowing and it was a real control. Adding the provenance clause disarmed it, and no fixture can restore it — measured both ways. So the card's second acceptance criterion, "M12 still turns red with the new clauses in", is unsatisfiable, and the honest answer is to remove a control that has become inert rather than keep it. R2 measures C5 strictly better; part 5 keeps the end-to-end coverage.

What review should push on

  1. The Snapshot construction is synthetic — object.__new__ plus eleven fields. If diff() grows a dependency on a field the driver does not set, the rows go green on a None. Is that a trap I have walked into?
  2. The mutation targets are string edits against the shipped text. SAFETY-44 established these pin spelling, not rule. Which of the five would survive a plausible refactor?
  3. My claim that no fixture can restore M12. I measured two arrangements. Find a third.
  4. The unsatisfiable-criterion argument — is deleting M12 right, or am I removing a control because it became inconvenient?

28/28 pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU

SAFETY-44 produced **three inert controls** for this one rule, each inert differently, and split the two remaining fixes out rather than ship them unmeasured. This is that card. ## Why the end-to-end route could never have worked `moved_to` is one comprehension carrying five conditions with five different reasons to exist, and `run()` builds **both snapshots from one state file**. So "the destination was already latched" and "the destination was made by this transition" are the same file answering two incompatible questions: the arrangement that reaches one forecloses the other. That is why rebuilding a fixture to reach clause N kept moving the others — it is not a fixture problem. ## The rule is now graded where it is written `diff()` on constructed Snapshots, one case per clause. On the **shipped** tree, before any fix, the table already separated both known defects: | row | shipped answer | | |---|---|---| | R1 rename (legitimate) | migrated | correct | | R2 narrowing | vanished | correct | | **R3 provenance** | **migrated** | ⚠️ the defect | | R4 same value | vanished | correct | | **R5 injectivity** | **both migrated** | ⚠️ the defect | | R6 machine_read | vanished | correct | The two reverted one-line fixes are back; R3/R5 flip, R1/R2/R4/R6 do not — the legitimate rename is still suppressed, so this is not an over-correction. **And each clause removal flips exactly its own row** — the acceptance criterion this card was filed with: ``` C1 machine_read -> ['R6-machine-read'] C6 injectivity -> ['R5-injectivity'] C3 same value -> ['R4-value'] C7 provenance -> ['R3-provenance'] C5 off-roster -> ['R2-narrowing'] ``` ## M12 is deleted, and that is the finding M12 was SAFETY-44's end-to-end control for the narrowing and it was a **real** control. Adding the provenance clause disarmed it, and **no fixture can restore it** — measured both ways. So the card's second acceptance criterion, *"M12 still turns red with the new clauses in"*, is **unsatisfiable**, and the honest answer is to remove a control that has become inert rather than keep it. R2 measures C5 strictly better; part 5 keeps the end-to-end coverage. ## What review should push on 1. **The `Snapshot` construction is synthetic** — `object.__new__` plus eleven fields. If `diff()` grows a dependency on a field the driver does not set, the rows go green on a `None`. Is that a trap I have walked into? 2. **The mutation targets are string edits against the shipped text.** SAFETY-44 established these pin spelling, not rule. Which of the five would survive a plausible refactor? 3. **My claim that no fixture can restore M12.** I measured two arrangements. Find a third. 4. **The unsatisfiable-criterion argument** — is deleting M12 right, or am I removing a control because it became inconvenient? 28/28 pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
admin added 1 commit 2026-09-08 23:51:57 +02:00
SAFETY-44 produced THREE inert controls for this one rule, each inert
differently, and split the two remaining fixes out rather than ship them
unmeasured. This is that card, and the first thing it did was explain why the
end-to-end route could never have worked.

⚠️ `moved_to` IS ONE COMPREHENSION CARRYING FIVE CONDITIONS WITH FIVE DIFFERENT
REASONS TO EXIST, AND `run()` BUILDS BOTH SNAPSHOTS FROM ONE STATE FILE. So
"the destination was already latched" and "the destination was made by this
transition" are the same file answering two incompatible questions: the
arrangement that reaches one forecloses the other. That is why rebuilding a
fixture to reach clause N kept moving the others, and it is not a fixture
problem.

⭐ SO THE RULE IS GRADED WHERE IT IS WRITTEN - `diff()` on constructed
Snapshots, ONE CASE PER CLAUSE. Six rows, and on the SHIPPED tree before any
fix they already separated the two known defects:

    R1 rename (legitimate)   migrated                      correct
    R2 narrowing             vanished                      correct
    R3 provenance            MIGRATED                      ⚠️ the defect
    R4 same value            vanished                      correct
    R5 injectivity           BOTH migrated                 ⚠️ the defect
    R6 machine_read          vanished                      correct

The two one-line fixes SAFETY-44 reverted are back, and R3/R5 flip while
R1/R2/R4/R6 do not - so the legitimate rename is still suppressed and this is
not an over-correction.

⭐ AND EACH CLAUSE REMOVAL FLIPS **EXACTLY ITS OWN ROW**, which is the
acceptance criterion this card was filed with:

    C1 machine_read  removed -> ['R6-machine-read']
    C3 same value    removed -> ['R4-value']
    C5 off-roster    removed -> ['R2-narrowing']
    C6 injectivity   removed -> ['R5-injectivity']
    C7 provenance    removed -> ['R3-provenance']

A removal that flips nothing is an unmeasured clause; a removal that flips
someone else's row means the cases are not separable after all. Neither
happened.

⚠️ AND M12 IS DELETED, WHICH IS THE MOST USEFUL THING THIS CARD FOUND. M12 was
SAFETY-44's end-to-end control for the narrowing and it was a REAL control -
red when the narrowing was removed. Adding the provenance clause disarmed it,
and NO FIXTURE CAN RESTORE IT, measured both ways: with the sibling latched in
its own right, C7 rejects the destination before C5 is consulted, so the
mutation is reported whether or not C5 exists; making the destination
transition-made means a flat latch, which makes the shipped run dirty and
breaks M12's own precondition. The second half of the card's acceptance
criterion - "M12 still turns red with the new clauses in" - is therefore
UNSATISFIABLE, and the honest answer is to remove the control rather than keep
one that has become inert. R2 measures C5 strictly better. Part 5 keeps the
end-to-end coverage; discrimination lives in 5e.

`state-both-latched.json` goes with it. Nothing referenced it once M12 was
gone, and the first draft of that paragraph said it was "kept, because 5e's
R2/R3 are derived from the arrangements it represents" - a nice sentence and
not a reference. An unused fixture a comment calls load-bearing is an inert
check one directory over.

TWO THINGS THE DRIVER GETS RIGHT ON PURPOSE:
  - it is written to a TEMPDIR, not beside the tool. `checks / unit` mounts the
    checkout READ-ONLY, so writing into the tree works on a dev box and is
    `OSError: Read-only file system` in CI - green for whoever wrote it and red
    on every PR. Caught by running it in the check image before committing.
  - the TABLE stays in the test file and the driver goes into the tree under
    test, so a mutation to the tool cannot also move the answer it is graded
    against.

28/28 files pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
admin added 1 commit 2026-09-09 00:29:03 +02:00
Review found two things this PR asserted about itself that were false. Both are
mine and both are worse than the defect the card was filed for.

⚠️ "NO FIXTURE CAN RESTORE IT, MEASURED BOTH WAYS" WAS NOT TRUE, AND TWO
MEASUREMENTS ARE NOT AN IMPOSSIBILITY PROOF. I deleted M12 - SAFETY-44's
working end-to-end control for the off-roster narrowing - on the argument that
the provenance clause made it unrestorable. The structural claim behind it,
that `run()` builds both snapshots from one state file so "already latched" and
"made by this transition" are incompatible, IS TRUE OF SAME-STEP AND FALSE OF
STAGED: `snapshot_over()` starts the after-leg over the file the BEFORE-leg
wrote, so a transition-made destination is available there. Both arrangements I
measured were same-step shaped. Review found the third.

RESTORED, and it discriminates with all six clauses in:

    staged leg, legacy+shed, shipped     _m12_new = VANISHED unit/shed/sign_tripped
    ...C5 narrowing removed              _m12_new = []          ⚠️ suppressed

⚠️ AND MY FIRST RESTORATION DIDN'T DISCRIMINATE EITHER, for a reason worth
recording: `data.pop(k, False)` RETURNS the value, so shed lost the KEY and
kept the LATCH - `_grade_store_migration()` saw `on_roster_latched`, never
re-armed garage, and there was no transition-made destination. The finding was
reported whether or not C5 existed and the control looked restored. `and False`
is the difference between "the key is gone" and "the LATCH is gone", and only
the second reaches the re-arm this arrangement needs.

⚠️ WHAT ACTUALLY BROKE WAS M12's exit-0 PRECONDITION, NOT M12. A legacy-shaped
fixture is never clean. That precondition is the one SAFETY-44's own commit
called "belt-and-braces, load-bearing only if the exit-0 requirement is ever
relaxed", saying what closed the gap is `_m12_new` BEING A SET DIFFERENCE - and
a stable dirty baseline is fine for a set difference. So I deleted a control on
the strength of a precondition the same commit had already called not
load-bearing. That is removing coverage rather than failing to add it, which is
the worse of the two directions.

⭐ AND THE BARE-KEY CLAUSE HAD NO ROW AT ALL. Review deleted
`k.rsplit("/", 1)[-1] == bare` and the whole 28-file suite stayed GREEN. 5e
mutated five clauses; the comprehension carries more, and this one is
load-bearing: a vanished SAFETY-02 `sign_tripped` was suppressed by a SAFETY-42
`delivery_tripped` on a roster unit - a DIFFERENT FAILSAFE's key. The rule's own
comment says "THE TEST IS NOT 'the name appears somewhere'. It is: the SAME bare
key", and nothing measured that sentence. `unit/*/delivery_tripped` is
machine-read, so it is reachable on any real two-latch store. R7 added; C2 now
flips exactly R7.

All six clause-removals now flip exactly their own row:

    C1 machine_read   -> ['R6-machine-read']    C5 off-roster  -> ['R2-narrowing']
    C2 same bare key  -> ['R7-bare-key']        C6 injectivity -> ['R5-injectivity']
    C3 same value     -> ['R4-value']           C7 provenance  -> ['R3-provenance']

THREE DANGLING CITATIONS TO A CONTROL THIS PR HAD DELETED, one of them in the
shipped tool eight lines below the paragraph condemning exactly that ("a
citation is the worst possible carrier, because it reads as having been
checked"). The tool no longer names a check; it states the property - every
clause has a row, and each removal flips its own.

A STALE SAFETY-44 BLOCK saying both fixes were "REVERTED OUT OF THIS CARD,
because THIS SUITE CANNOT MEASURE EITHER ONE" - describing a tree this PR
replaced. Rewritten as a map of where each clause is now measured. A comment
that outlives its subject is the same defect as a citation that outlives its
check.

AND A SELF-CONTRADICTION about the driver, in the file and in the last commit
message: "THE DRIVER IS WRITTEN INTO THE TREE UNDER TEST" eight lines above
"THE DRIVER GOES IN A TEMPDIR, NOT IN THE TREE". The code does the tempdir; the
first sentence stated the read-only-CI bug the same commit says it fixed, as if
it were the design. It now says the driver IMPORTS the tree and is WRITTEN to a
tempdir.

ONE HOLE REMAINS OPEN AND IS STATED AS UNMEASURED: attribution. `sorted()`
decides which vanished key claims a destination, so a deleted key can sort
first and be named as the one that migrated while the key that really moved is
reported VANISHED. Review measured that `sorted(` -> `list(` leaves the suite
green - every 5e case has at most one candidate, so no row can see ordering.
Still exit 1, so a wrong sentence rather than a hidden loss. Recorded rather
than left looking guarded.

28/28 files pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
admin added 1 commit 2026-09-09 00:58:06 +02:00
Review APPROVED f6f3f22 plainly. Three LOW notes, all applied - the first is a
real gap and the other two are one line each.

⚠️ M12's ASSERTION WAS KIND-BLIND. It matched on the key and ignored the
finding kind, so renaming `diff()`'s `"VANISHED STORE KEY"` to
`"GONE STORE KEY"` left M12 GREEN - review measured it. A vanished latch
quietly downgraded to a softer heading is exactly what part 3 of this same file
requires every mutation to be graded against ("the SPECIFIC finding it should
produce"), so the file was not holding itself to its own doctrine. Inherited
from SAFETY-44's original M12, not introduced here, and fixed now:

    ("VANISHED STORE KEY", "unit/shed/sign_tripped") in _m12_new

Driven: the kind rename is exit 1 and M12 is among the reds where it was green
before, and C5's removal still turns M12 red, so the strengthening did not cost
the discrimination it exists for.

C4 IS NAMED IN THE CLAUSE MAP. It has no 5e row deliberately - part 3's M9
reaches `vanished_unit is not None` end-to-end and a synthetic row would
duplicate that rather than add separability - but C5 lives in the same `if`,
and listing one guard while omitting the other reads as an oversight rather
than a boundary. Review's own recommendation was not to add the row.

AND THE PRINTED SET SAYS WHAT IT LOSES. The finding regex captures the first
TOKEN of each text, so two findings of one kind collapse into one tuple; the
line now says "first token only" so nobody reads it as an inventory. Harmless
for M12 - the difference is one-directional and the pair it asserts on is exact
- but the display was lossier than it looked. Unused `_m12_out` dropped.

28/28 files pass. `rehearse_roster.py` is untouched by this round; review
confirmed its AST is identical between 91b0d5e and f6f3f22, so every
measurement made against the shipped rule still stands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
admin merged commit 587751b115 into release/1.0 2026-09-09 01:05:37 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#72