Port the enemy footprint decision-boundary probe to Rust (#227) - #353
Merged
Conversation
Port-first entry 2. `test/enemyBaseField.spec.ts` carries two claims, not one, and only the first has a Rust counterpart. `worstAbs`/`worstRel` grade the field's values, and `fixtures.rs` already reproduces those at both seeds in three magnitude buckets. The second claim is `footprintDisagreements`: port and game never fall on opposite sides of a cut at 0.05 through `min(v, ENEMY_PLACEMENT_CAP)`. Nothing in Rust graded that. The gap is real rather than theoretical, because the two checks cannot see each other. An aggregate tolerance passes a residual that still moves a position across the cut, and a cut is what the overlay does with this field. The nearest Rust check, `the_enemy_fixture_is_mostly_basement_...`, compares positive counts, so two positions could swap sides and the count would not move. Planted rather than predicted: | plant | result | | --- | --- | | bias the port by 0.011 | `a value sits 8.04e-4 from the cut` | | bias the port by 0.03 | `port and game fall on opposite sides` - 3 at seed 123456 | The second is the one that matters: 0.03 is 33x below the deleted spec's own `ABS_TOL` of 1.0, so the aggregate arms would have passed it. Two guards beside the probe, because a zero on its own can be luck. The count of positions inside the cut is frozen per seed - 39 of 1032 at seed 123456, 37 at seed 777771 - so a port returning a constant cannot satisfy it. And the nearest value to the cut is required to stay above 1e-3, so the f32 read cannot be what decides a side. This unblocks deleting `test/enemyBaseField.spec.ts`, which imports `src/noise/enemies/enemyBaseField.ts` and therefore cannot outlive the #227 deletion. The spec stays until then; the coverage is now in both places. Claude-Session: https://claude.ai/code/session_01UVcbv1pAhPUoCC6aBwZUtg Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port-first entry 2.
test/enemyBaseField.spec.tscarries two claims, not one,and only the first has a Rust counterpart.
worstAbs/worstRelgrade thefield's values, and
fixtures.rsalready reproduces those at both seeds inthree magnitude buckets. The second claim is
footprintDisagreements: port andgame never fall on opposite sides of a cut at 0.05 through
min(v, ENEMY_PLACEMENT_CAP). Nothing in Rust graded that.The gap is real rather than theoretical, because the two checks cannot see each
other. An aggregate tolerance passes a residual that still moves a position
across the cut, and a cut is what the overlay does with this field. The nearest
Rust check,
the_enemy_fixture_is_mostly_basement_..., compares positivecounts, so two positions could swap sides and the count would not move.
Planted rather than predicted:
a value sits 8.04e-4 from the cutport and game fall on opposite sides- 3 at seed 123456The second is the one that matters: 0.03 is 33x below the deleted spec's own
ABS_TOLof 1.0, so the aggregate arms would have passed it.Two guards beside the probe, because a zero on its own can be luck. The count
of positions inside the cut is frozen per seed - 39 of 1032 at seed 123456, 37
at seed 777771 - so a port returning a constant cannot satisfy it. And the
nearest value to the cut is required to stay above 1e-3, so the f32 read cannot
be what decides a side.
This unblocks deleting
test/enemyBaseField.spec.ts, which importssrc/noise/enemies/enemyBaseField.tsand therefore cannot outlive the #227deletion. The spec stays until then; the coverage is now in both places.
Claude-Session: https://claude.ai/code/session_01UVcbv1pAhPUoCC6aBwZUtg
Co-authored-by: Claude Opus 5 (1M context) noreply@anthropic.com