Repository navigation
tools: a confirmation that was never answered no longer claims the promise - #328
Conversation
…omise Two things, both from #322, and the first is not the one it reported. `widened` says every survivor really was re-run against the whole suite -- CONTRIBUTING.md states it, and `Report.widened` says "there is exactly one way to earn it". There were two grant sites and neither checked: a probe that timed out or broke re-ran nothing, and `confirm` set the flag anyway. So a sweep where every confirmation timed out wrote `"widened": true` into its `--json`, which `tools/reached.py` reads back as a survivor checked against everything. It is now earned only when every confirmation was answered. The issue said the flag stayed false, "which is honest", and that nobody was told. Neither holds: the warning has printed since #223, a week before the issue was filed, and the flag was set. The failure was not quiet-but-honest, it was a documented guarantee claimed while unmet. Second, the reported bug: a confirmation probe is one serial pass over the whole suite, so it cannot share `--timeout`, which bounds a mutation against a module or two. 249.7s of suite under a 300s bound left every lane timing out. The bound is now derived from the per-test costs `sweeps/killers.json` already persists, so it follows the suite as that grows; `--timeout` is its floor. Nobody moved the old number -- the suite moved under it, which is why this is measured rather than a second constant to keep in step. Not taken: confirming against a sharded run, which would put a pool inside a lane, and confirming against a narrower module set, which weakens the guarantee. Both are design calls beyond one issue. Closes #322. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`test (3.10)` failed with `749.100000000002 != 749.0999999999999` while 3.12 and 3.14 passed. CPython 3.12 gave `sum()` compensated summation for floats, so a fixture of 2.497 accumulates to 249.7 there and a few ulps away on 3.10, and the assertion compared that against the literal `3.0 * 249.7`. Halves sum exactly under either algorithm. The story is unchanged -- a ~250s suite under a 300s bound -- and the test is now about the arithmetic it claims to be about rather than about which summation the interpreter ships. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
CI caught a brittle assertion of mine on 3.12 and 3.14 passed and 3.10 did not, which is the interesting part: CPython The fixture now uses Re-verified that it still earns its place: Worth noting against the PR body's claim that the generated sweep came back 24 Generated by Claude Code |
Closes #322.
The issue's premises, checked first
Two of them do not hold, and the second reverses the story.
"Nobody is told that the correction pass did not happen." A warning has
printed since #223 (2026-08-18), a week before the issue was filed
(2026-08-25).
"
widenedstays false, which is honest." It does not.confirmsetwidened=Truewhenever nothing was corrected — including when everyconfirmation timed out.
CONTRIBUTING.mdsays the flag is true "only whenevery survivor in the file really was re-run against the whole suite", and
Report.widened's own docstring says "there is exactly one way to earn it, sothat is what sets it". There were two grant sites and neither checked.
Proven before changing anything — one survivor, one probe, hung on purpose:
So the failure was not quiet-but-honest. It was a documented guarantee claimed
while unmet, written into
--json, wheretools/reached.pyreads it back as asurvivor that had been checked against everything. That is worse than what was
filed, and it is the half the issue could not see.
What changed
1.
widenedis earned, not assumed.kept = not unsure, applied at bothreturn paths. One unanswered probe voids the promise however many neighbours
were answered — the promise is about every survivor.
2. The bound is derived. A confirmation probe is one serial pass over the
whole suite;
--timeoutbounds a mutation against a module or two. One numbercannot be right for both, and 249.7 s of suite under a 300 s bound left every
lane timing out.
confirm_timeoutderives it from the per-test costssweeps/killers.jsonalready persists and refills every run, so it followsthe suite as that grows.
--timeoutis its floor — someone who raises it means"give things longer", and a derived bound that came back shorter would answer
the opposite. No remembered costs means the floor, which is today's behaviour: a
guess dressed as a derivation would read as measured in the output and be a
number nobody chose.
The bound is printed (
confirming 3 survivor(s) against the whole suite, 300s each...) because a derived number the reader cannot see is one they cannotcheck.
Not taken, and why. The issue's option 2 (confirm against a sharded run)
puts a pool inside a lane;
run's docstring records that queueing the baselinealongside the rows was measured at two thirds of the wall clock, so reversing
that is a design call, not a bug fix. Option 3 (confirm against a narrower
module set) is explicitly a weaker claim than
CONTRIBUTING.mdmakes. Both arebeyond one issue.
CONTRIBUTING.mdgains the fourth case forwidenedbeing false, and theparagraph on why the bound is derived.
Verification
Hand table — every row a different way to be wrong, run against the whole of
tests.test_mutate:Generated sweep,
python -m tools.mutate --base main, 24 of 24 caught:The first sweep had three survivors, and they were real
Worth recording, because "24 of 24" above is the second run:
All three were output-honesty gaps on lines this diff touches. Making
if unsure:unconditional prints "0 confirmation(s) could not be answered ... thereport is not marked widened" beside a report that is marked widened.
Making
if not corrected:unreachable prints "0 of them were caught by a testthe selection had not run" after correcting none. And
merged or None→merged and Nonesilently discards the timingsKillersbudgets thecheap-first prefix from.
Two false sentences, in the pass whose entire job is to stop a reader trusting a
wrong row. They were killed by asserting what
confirmmust not say — theexisting suite asserted only what it does say.
Preflight green:
ruff check,ruff format --check,mypy,shellcheck, andCI=true WOSWOAR_HYPOTHESIS_PROFILE=ci python -m tools.run_tests—OK (0 failures, 0 errors, 4 skipped).One note on the sweep's own output
This sweep mutates
tools/mutate.py, so it ran the changedconfirmagainstitself:
confirming 3 survivor(s) against the whole suite, 300s each...is thenew line, showing the floor because
sweeps/killers.jsonwas empty on thismachine. That is the intended fallback, observed rather than argued.
🤖 Generated with Claude Code