What
test/spotCandidates.spec.ts cannot see a candidate-generation reordering, in
almost every region.
The game fixture (test/fixtures/spot-candidates.game.json, 11 cases) is
sorted by (x, y), and its own note says so: "Sorted (x,y); generation order
is not recorded here". The spec sorts the port's output the same way before
comparing, so any permutation of the generated stream compares equal.
One test does grade order - the candidate_index_to_Vx_Vy stream from
docs/noise/spot-candidate-stream.seed123456.json - but it covers exactly
one key: seed0 = 123456, seed1 = 0, region (0, 0), regionSize 2**32.
Measured
Planted mutations against a scratchpad copy of spotCandidatePoints, 2026-08-18:
| planted mutation |
game fixture (sorted) |
stream (indexed) |
| none |
11/11 |
20/20 |
| reverse generation order |
11/11 - blind |
0/20 caught |
| rotate by one |
11/11 - blind |
0/20 caught |
| swap first two candidates |
11/11 - blind |
18/20 caught |
| swap the x and y draw |
0/11 caught |
0/20 caught |
And the hole the single-key stream test leaves, measured directly: a reversal
applied to every region except (0, 0) passes the game fixture 11/11, the
stream test 20/20, the clamp test and the bit-0 test. The whole spec is blind
to it.
Why it matters
Order is not cosmetic here. spotSelection consumes candidates in generation
order: the skip set is applied by index (skipSpan / skipOffset), and
randomPenalty is a batch op seeded from the first accepted spot and
streamed last-to-first, so a permutation changes every spot's quantity. See
docs/noise/spot-noise-NOTES.md and docs/noise/random-penalty-NOTES.md.
No defect is known to exist behind this gap. It is a missing guard, not a bug
report.
What would close it
Capture an ordered stream for a second key - ideally one with a non-zero region
and a non-zero seed1 - and grade it by index like the existing stream test.
test/oracle/ already has the machinery; docs/noise/spot-candidate-stream.seed123456.json
is the shape to copy.
Do NOT convert this spec under #256
Separate but related, and worth recording here because the two look alike: the
stream assertion compares raw u32 draws (up to 4,178,305,507), where f32's
spacing is 256. Scoring it with Math.fround(got) === expected returns 1/40
on values that are 40/40 strictly equal. The fround would be the
corruption, not the measurement. spotCandidates is integer end to end and a
Rust port must carry it as u32/u64 wrapping arithmetic - its pre-mod seed
sum reaches 3.4e13, and evaluating that in f32 disagrees on 4 of the 29 keys the
spec exercises.
Found while scoring the phase-1 primitives for #220.
What
test/spotCandidates.spec.tscannot see a candidate-generation reordering, inalmost every region.
The game fixture (
test/fixtures/spot-candidates.game.json, 11 cases) issorted by (x, y), and its own note says so: "Sorted (x,y); generation order
is not recorded here". The spec sorts the port's output the same way before
comparing, so any permutation of the generated stream compares equal.
One test does grade order - the
candidate_index_to_Vx_Vystream fromdocs/noise/spot-candidate-stream.seed123456.json- but it covers exactlyone key:
seed0 = 123456, seed1 = 0, region (0, 0), regionSize 2**32.Measured
Planted mutations against a scratchpad copy of
spotCandidatePoints, 2026-08-18:And the hole the single-key stream test leaves, measured directly: a reversal
applied to every region except (0, 0) passes the game fixture 11/11, the
stream test 20/20, the clamp test and the bit-0 test. The whole spec is blind
to it.
Why it matters
Order is not cosmetic here.
spotSelectionconsumes candidates in generationorder: the skip set is applied by index (
skipSpan/skipOffset), andrandomPenaltyis a batch op seeded from the first accepted spot andstreamed last-to-first, so a permutation changes every spot's quantity. See
docs/noise/spot-noise-NOTES.mdanddocs/noise/random-penalty-NOTES.md.No defect is known to exist behind this gap. It is a missing guard, not a bug
report.
What would close it
Capture an ordered stream for a second key - ideally one with a non-zero region
and a non-zero
seed1- and grade it by index like the existing stream test.test/oracle/already has the machinery;docs/noise/spot-candidate-stream.seed123456.jsonis the shape to copy.
Do NOT convert this spec under #256
Separate but related, and worth recording here because the two look alike: the
stream assertion compares raw u32 draws (up to 4,178,305,507), where f32's
spacing is 256. Scoring it with
Math.fround(got) === expectedreturns 1/40on values that are 40/40 strictly equal. The
froundwould be thecorruption, not the measurement.
spotCandidatesis integer end to end and aRust port must carry it as
u32/u64wrapping arithmetic - its pre-mod seedsum reaches 3.4e13, and evaluating that in f32 disagrees on 4 of the 29 keys the
spec exercises.
Found while scoring the phase-1 primitives for #220.