Two blockers, one of them mine to fix and one a mis-measurement to undo. No
`app/` change in either: the shipped `sum` is correct.
1. A ZERO-BYTE SURVIVOR AT THE CALL SITE ONE LINE BELOW THE PINNED VALUE.
Round 1 pinned `site_standing` and never pinned WHERE IT GOES. Swapping the
detector's first two arguments at main.py:1620 -
`evaluate(site_standing, self.grid, ...)` -> `evaluate(self.grid, site_standing, ...)`
- is a ZERO-BYTE edit and left the round-1 tree fully green. The cost is the
banner: the site stands at -500 W of charge into a +2500 W import and the
LATCHING, SITE-STOPPING alarm reads "commanded +2500 W against a meter
reading -500 W" - which instrument read what, inverted, on the one line
somebody woken by it reads first (watchdog.py:658-665).
Round 1's check could not reach it. It asserted `"-500 W"` appears SOMEWHERE
in the sentence; under the swap it still does, IN THE METER SLOT. A substring
test grades PRESENCE, never ARRANGEMENT. It now asserts the ORDERED PAIR:
`f"commanded {sum:+.0f} W against a meter reading {grid:+.0f} W"`. Measured:
red in test_watchdog.py on that one named check, green in the other twenty.
2. THE M3 ATTRIBUTION WAS FALSE, AND HOW IT BECAME FALSE IS THE USEFUL PART.
Round 1 recorded `list(standing.values())[0]` as closed by SAFETY-32's
package-wide pin and told future authors NOT TO RE-COVER IT. Re-measured on
release/1.0 @ 86eaef2 carrying only that edit: the full 21-file suite is
GREEN and test_peakguard.py is PASS PASS PASS PASS PASS in isolation. THE
MUTATION SURVIVES. It was originally measured once, that run hit CI-06's
~20% flake, and the red was recorded as a kill.
The mechanism, read off 12j's own enumeration rather than argued: 12j taints
names BOUND to roster values and lists ACCUMULATED in a loop. `standing` is a
dict filled by SUBSCRIPT assignment (main.py:1554/1558), so it never enters
the taint set and 1599 is not a roster site. On the mutated tree 12j lists
main.py:1553, 1555 and 1690 - not 1599. Part 9a and 9b close it.
Corrected in all four places it was committed: DECISIONS section 1 and
section 4, CHANGELOG, and the part 9 header that carried the instruction.
MEASUREMENT, all on 86eaef2, fresh copy per mutation, mounted :ro, bytecode
purged by tools/mutation_run.sh, edit re-read from disk, byte delta printed:
* M1-M10 re-run INDEPENDENTLY rather than carried forward - all 10 red, at
the deltas the table records (M1/M2/M4 re-run in the exact wrapped form).
* M11, the argument swap: 0 bytes, red on one check in one file.
* W1 `"sign_site": SCOPE_SITE -> SCOPE_UNIT`: 0 bytes, red; part 9a is one of
the two killers.
* W2 `"circulation": SCOPE_SITE -> SCOPE_UNIT`: 0 bytes, red - but ENTIRELY
on pre-existing checks. This card adds nothing to circulation and does not
claim it.
Control: 21/21 green before and after. The suite is 21 files, not 20 - TEL-07
added test_mqtt.py in the rebase onto 86eaef2.
DECISIONS section 6a enumerates what was NOT closed: SAFETY-31's circ_wd
detector itself, the other eight CLAIM_SCOPE entries, actuator_of()'s body, the
n_units > 1 guard, and the fact that the "green in the other twenty files" half
of the ledger was re-verified on 86eaef2 only for M3 and M11.
MUTATION.md gains habit 14 - assert the ordered pair, not the substring - and
records this as the tenth instance of the family, found INSIDE THE FIX WRITTEN
TO CLOSE THE NINTH, for the second time in that list.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU