Repository navigation
gates mutate: X of Y where X can exceed Y — four lines from a fix I shipped two passes ago - #3221
Conversation
SKILL 542 fixed the DENOMINATOR of `tri gates mutate`'s equivalence
report -- claims_seen counted every marker textually, including claims no
mutant was built for. The numerator went untouched, four lines below, in
the same println. The units fan-out found it.
claims_seen += in_scope.len(); // distinct claim LINES
for (dir, _, _, survivors) in &scores { // ... once PER DIRECTION
claims_broken.extend(contradicted_claims(..));
}
println!("{} of {} ...", claims_broken.len(), claims_seen);
"X of Y" is an inclusion statement and both halves must count the same
thing. A claimed line that is a mutable site under two operators and dies
under both contributes two rows to a numerator whose denominator counted
it once. Under --all the command can print "2 of 1".
Measured, not hypothesised: of the eight `# mutant-equivalent:` markers
in tools/, exactly ONE is a site in two directions --
gft_backprop_microcode.py:742, `assert _magsub(10240, 9217) == 9984`,
both an assert site and a boundary site.
Fixed by counting each half in its own unit rather than deleting a
number:
1 of 8 equivalence claim(s) CONTRADICTED, in 2 (claim x operator) row(s):
The rows stay per direction, because which operator killed a claim is the
useful half: an assert mutant dying says something different from a
boundary mutant dying.
Tenth pass running that the wiring outlived the function. Three fresh
unit tests on distinct_claims all passed against a call site reverted to
claims_broken.len(); killed by a structural test reading it.
SKILL 580.
Refs #3195
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-05 01:40:55 UTC
Summary
Seal Status
|
PR DashboardGenerated at: 2026-09-05 02:02:25 UTC
Summary
Seal Status
|
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-05 02:37:12 UTC
Summary
Seal Status
|
# Conflicts: # .claude/skills/ci-gates/SKILL.md
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
1 similar comment
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-05 02:51:54 UTC
Summary
Seal Status
|
# Conflicts: # .claude/skills/ci-gates/SKILL.md
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
PR DashboardGenerated at: 2026-09-05 03:03:02 UTC
Summary
Seal Status
|
PR DashboardGenerated at: 2026-09-05 03:26:41 UTC
Summary
Seal Status
|
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
SKILL 542 fixed the denominator of
tri gates mutate's equivalence report —claims_seencountedevery
# mutant-equivalent:marker textually, including claims for which no mutant was ever built.The numerator went untouched, four lines below, in the same
println!. The units fan-out found it."X of Y" is an inclusion statement, so both halves must count the same thing. They do not. A
claimed line that is a mutable site under two operators and dies under both contributes two rows
to a numerator whose denominator counted it once. Under
--allthe command can print2 of 1.Measured, not hypothesised
Of the eight markers in
tools/, exactly one is a site in two directions:gft_backprop_microcode.pyassert _magsub(10240, 9217) == 9984One in eight, on real data, reachable through a flag the command documents.
Fixed by counting each half in its own unit
The rows stay per direction — which operator killed a claim is the useful half: an
assertmutantdying says something different from a
boundarymutant dying. What changes is that the ratio speaksabout claims, and the rows are counted as rows and labelled as such.
Half of a fix is not the fix
Two passes ago I corrected this function's denominator and wrote a skill section about it. The
numerator sat four lines below and I did not look at it. "The fix does not travel" has a shorter
form here: it did not travel four lines.
The mutant reverting the numerator to
claims_broken.len()survived three fresh unit tests ondistinct_claims, and was killed only by a structural test reading the call site — the tenth pass ina row where the wiring outlived the function.
743 crate tests. SKILL 580. Refs #3195