Skip to content

The blind-spot ratio flaked on the reference, not on the thing measured - #7

Merged
kmoneil merged 1 commit into
mainfrom
fix-blind-spot-flake
Aug 25, 2026
Merged

The blind-spot ratio flaked on the reference, not on the thing measured#7
kmoneil merged 1 commit into
mainfrom
fix-blind-spot-flake

Conversation

@kmoneil

@kmoneil kmoneil commented Aug 25, 2026

Copy link
Copy Markdown
Owner

What flaked

test_no_function_is_wildly_cheaper_to_the_counter_than_to_the_machine held every function to one ceiling of 25x the map reference per charged step. pluck sits at 17 to 22 depending on the machine, because it reads a key directly and walks no tree per item, so it charges almost nothing for real work. It failed twice in one afternoon on macos-latest, once on main, both times on code that had changed nothing.

The cause was the denominator

Measured on both hosted runner platforms, eight repeats each, pluck against map:

Runner 5 rounds 15 rounds
ubuntu-latest 17.18 to 17.40 (spread 0.22) 17.28 to 17.48 (spread 0.20)
macos-latest 14.75 to 26.25 (spread 11.49) 17.53 to 20.82 (spread 3.28)

The macOS reference swings 52.6% across its own minimums at five rounds, against 1.4% on Linux. A reference that happens to measure fast inflates every ratio above it, so five samples is enough on one platform and not on the other, and the ratio inherits all of it. The 26.25 is the CI failure reproduced.

Both tables came from a throwaway probe branch running the measurement on both platforms, which is now deleted.

The fix is in the estimator, not in the number

blind_spots takes fifteen samples rather than the five everything else takes, with the argument written next to BLIND_SPOT_ROUNDS. Taking a minimum is still right and taking more of them is what was missing: more rounds move a minimum down and never up, so this converges rather than drifting. It costs 0.27 s per call at 20,000 items and 2.8 s at 200,000.

This is deliberately the opposite of the move ruled out elsewhere in this file. Nothing takes fewer samples; one thing takes more, where a ratio made five insufficient.

The ceilings are per function now, and the default is tighter than the cap it replaces

Measured on both platforms at fifteen rounds, eight repeats, worst observed:

Function Linux max macOS max
pluck 18.48 21.67
join 7.61 7.91
min 1.84 2.52
max 1.77 2.39
unique_by 1.80 1.87
sum 1.69 0.88
sort_by 1.43 1.62

Default 15x, roughly twice the worst thing it covers, so a function landing at 20x is now caught where it used to pass at 25x. pluck carries its own 40x, roughly twice its worst, because it is a documented property rather than a concession: docs/performance.md already said so in prose, and that prose is updated to the re-measured range.

The class this test exists to catch, the aggregates at 1,500 to 2,300x before calls were charged for what they read, stays two orders of magnitude away from both numbers.

The exemption cannot outlive its reason. test_the_ceilings_are_still_earned fails if a named function drops comfortably under the default, so it gets removed rather than sitting there making the general cap look looser than it is.

Verified by making each guard fail

Break Caught by
a function over its ceiling (default lowered to 5x) the ceiling assertion, naming join at 7.4x (ceiling 5x) and printing the whole table
blind_spots put back on the shared five-round default test_regression_limits_a_noisy_reference_inflated_the_ratio
an exemption that stopped being earned (sort_by given one) test_the_ceilings_are_still_earned

The middle one is the important one: reverting the sampling would leave the ceilings passing on Linux and nothing else would notice.

The failure message now prints the whole table as multiples of the reference, so the next failure diagnoses itself instead of naming one row.

Checks

  • ruff check, ruff format --check, mypy --strict clean
  • Full suite: 2,419 passed, 6 skipped, 63.1 s with --runslow; 2,417 passed, 2 deselected, 41.1 s by default
  • No source file touched; this is scripts/limits.py, tests/test_limits.py and one paragraph of docs/performance.md

test_no_function_is_wildly_cheaper_to_the_counter_than_to_the_machine held
every function to one ceiling of 25x the `map` reference per charged step.
`pluck` sits at 17 to 22 depending on the machine, because it reads a key
directly and walks no tree per item. It failed twice in one afternoon on
macos-latest, once on main, both times on code that had changed nothing.

The instability is in the denominator. Measured on both runner platforms,
eight repeats each, pluck against map:

    ubuntu-latest   rounds=5  17.18 to 17.40 (0.22)   rounds=15  17.28 to 17.48 (0.20)
    macos-latest    rounds=5  14.75 to 26.25 (11.49)  rounds=15  17.53 to 20.82 (3.28)

The macOS reference swings 52.6% across its own minimums at five rounds
against 1.4% on Linux, and a reference that happens to measure fast inflates
every ratio above it. Five samples is enough on one platform and not on the
other; the 26.25 is the failure reproduced.

blind_spots takes fifteen samples now, with the argument next to the constant.
Taking a minimum is still right and taking more of them is what was missing:
more rounds move a minimum down and never up, so this converges. It costs
0.27s per call at 20,000 items.

The ceilings are per function now, and the general one is tighter than the cap
it replaces: 15x by default against a worst observed 7.91x for join and under
2.6x for everything else, so a function landing at 20x is caught where it used
to pass. pluck carries its own 40x with the measurement beside it, and a test
asserts that exemption is still earned.

All three guards verified by making them fail: a function over its ceiling, a
blind_spots put back on the shared five-round default, and an exemption that
stopped being earned.

Claude-Session: https://claude.ai/code/session_01Esnm9mNDpqRWf4QAVHCwHo
@kmoneil
kmoneil merged commit 316c220 into main Aug 25, 2026
13 checks passed
@kmoneil
kmoneil deleted the fix-blind-spot-flake branch August 25, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant