feat(accuracysnes): cover C11.03, and retract the interlace-gate claim (T-04-H) - #302
Conversation
…m (T-04-H) C11.03 -- each M7x * ORG product is masked to a multiple of 64 before the terms accumulate -- is now covered by a Mode 7 scene with M7A and M7B both $0101, deliberately not round numbers. With M7B = $0101 the discarded part is `line MOD 64`, a different amount on every line, so a core that accumulates the full products samples a different texel on roughly a quarter of the columns of most lines. Every other Mode 7 scene uses round matrix values, which hide this completely -- none of them was evidence for the row. Blessed at 0xc032679c9076440a, which all three references produce, stable across repeated runs. Non-vacuity confirmed by removing the mask from fetch_mode7_column: this scene's hash moves. Two existing scenes move under that injection too, so the mask was already witnessed in aggregate -- what this adds is a scene whose stated purpose is the mask. RETRACTION. PR #299 claimed the field gate turned C7.12's three-way emulator split into a two-way one, citing snes9x and Mesen2 producing the identical hash. That was ONE RUN and it does not hold: the identical ROM run twice under Mesen2 gives 0x16f7ab8c7f97b7f8 then 0x266241e43ab85064, the two field parities alternating run to run. RustySNES and snes9x are each stable; Mesen2 is not. The gate is necessary but not sufficient and the missing half is host-side: the cart publishes only on its chosen field, but which RENDERED frame a host associates with the R_SCENE value it read is not pinned, and Mesen2's headless runner does not make that association deterministically. The interlace scene is withdrawn rather than left unblessed, because a scene reporting a different hash each run is noise in the gate output. The gate itself stays -- cart-side half, moves no golden, costs only battery runtime. Coverage is unchanged at 350 of 443: C11.03 replaces C7.12 one-for-one, because the withdrawn scene was being counted as C7.12's scene-cover while still unblessed. What changed is that the row now counted has a golden all three references agree on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (3)
Comment |
Antigravity review (Gemini via Ultra)This pull request updates the Blocking issuesNone found. Suggestions
Nitpicks
Automated first-pass review by |
There was a problem hiding this comment.
🟡 Not ready to approve
CHANGELOG.md currently contains duplicated and internally contradictory entries (retraction text plus the older unretracted claim), which should be consolidated before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Updates AccuracySNES rendered-scene coverage by replacing the withdrawn, field-dependent C7.12 interlace scene with a new deterministic Mode 7 scene covering C11.03, and documents the retraction of the prior “interlace gate made references agree” claim.
Changes:
- Replaced scene
c7-obj-interlace-halves-height (C7.12)withc11-mode7-product-low-bits-masked (C11.03)and added its golden hash. - Updated generated scene catalogs/dispatch to include the new scene.
- Updated planning/coverage docs and changelog text to reflect the scene swap and the interlace-gate retraction.
File summaries
| File | Description |
|---|---|
| tests/roms/AccuracySNES/gen/src/scenes.rs | Swaps the scene definition to C11.03 and defines its Mode 7 setup. |
| tests/roms/AccuracySNES/build/scenes.tsv | Updates the generated scene index mapping to the new scene ID/dossier row. |
| tests/roms/AccuracySNES/asm/scenes.s | Updates generated scene implementation/dispatch table for the new scene. |
| tests/golden/accuracysnes-scenes.tsv | Adds the blessed golden hash for the new C11.03 scene. |
| docs/accuracysnes-plan.md | Updates high-level counts and narrative around the interlace-gate conclusion. |
| docs/accuracysnes-coverage.md | Updates the listed covered rendered-scene dossier row from C7.12 to C11.03. |
| CHANGELOG.md | Adds changelog entries covering the retraction and the new C11.03 scene coverage. |
Review details
- Files reviewed: 7/9 changed files
- Comments generated: 3
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| emulators, the only three-way split any scene has produced.", | ||
| id: "c11-mode7-product-low-bits-masked", | ||
| dossier: "C11.03", | ||
| what: "Mode 7 with `M7A` and `M7B` both `$0101` — deliberately NOT round numbers. Each `M7x * ORG` product has its low six bits masked off (`AND NOT $3F`) before the terms are accumulated, so the per-line origin is quantised to a multiple of 64 in the 1/256-texel fixed point. With `M7B = $0101` the discarded part is `line MOD 64`, which is a different amount on every line — a core that accumulates the full products samples a different texel on roughly a quarter of the columns of most lines, and the two pictures are nothing alike. Round matrix values hide this completely, which is why every other Mode 7 scene here uses them and none of them is evidence for this row.", |
| - **AccuracySNES: the scene protocol publishes on a known field.** `run_scenes` now sets the scene | ||
| ID only on frames whose `$213F` bit 7 is set, so every sighting the host counts is the same | ||
| *cart-side* field. `SCENE_FRAMES` grew 8 → 12: at half the publication rate the old value put the | ||
| host's fourth sighting on the window's *last* frame, one of the two ends the capture protocol | ||
| exists to avoid. The 53 blessed scenes are unaffected on all three hosts — a still picture hashes | ||
| the same on either field. |
| | Tests | **338** (scoring + golden vectors + region SKIP per image) — *tests, not assertions; see the note below the table* | | ||
| | Assertion coverage | **350 of 443** dossier assertions — **297 on-cart** + **53 rendered scenes**, kept as separate columns (`docs/accuracysnes-coverage.md`) | | ||
| | Rendered scenes | **53**, all cross-validated (`docs/adr/0013`) | | ||
| | Rendered scenes | **54** declared and all cross-validated (`docs/adr/0013`); **53** are the dossier rows they are the only cover for | |
Two things: a row covered, and a claim from PR #299 retracted.
Retraction first
#299 said the field gate had turned
C7.12's three-way emulator split into a two-way one, citing snes9x and Mesen2 producing the identical hash. That was one run, and it does not hold. The identical ROM, run twice under Mesen2:c7-obj-interlace-halves-heightunder Mesen20x16f7ab8c7f97b7f80x266241e43ab85064Exactly the two field-parity outcomes, alternating run to run on one build. RustySNES and snes9x are each stable; Mesen2 is not.
The gate is necessary but not sufficient, and the missing half is host-side. The cart is deterministic — it publishes only on its chosen field. What is not pinned is which rendered frame a host associates with the
R_SCENEvalue it read, and Mesen2's headless runner does not make that association deterministically.So the interlace scene is withdrawn, not left unblessed: a scene reporting a different hash each run is noise in the gate output, and "the references agree" was an artifact of looking once. The gate itself stays — it is the cart-side half, it moves no golden, and it costs only battery runtime — but nothing exploits it until a host can pin the frame it hashes.
C9.03/C9.06stay unwritten for the same reason.The lesson is
E8.01's, twice in one session: a result that depends on a phase nobody controls looks stable until you run it twice.C11.03— eachM7x * ORGproduct is masked before accumulationA Mode 7 scene with
M7AandM7Bboth$0101, deliberately not round numbers. WithM7B = $0101the discarded part isline MOD 64— a different amount on every line — so a core that accumulates the full products samples a different texel on roughly a quarter of the columns of most lines. Every other Mode 7 scene here uses round matrix values, which hide this completely; none of them was evidence for the row.Blessed at
0xc032679c9076440a, which all three references produce, stable across repeated runs.Non-vacuity confirmed by injection: removing the mask from
fetch_mode7_columnmoves this scene's hash. Worth stating thatc11-mode7-rotate-scaleandc11-mode7-windowalso move under that injection — the mask was already witnessed in aggregate. What this adds is a scene whose stated purpose is the mask, which is what makes the coverage claim mean something rather than being a coincidence of two scenes about other things.Coverage is unchanged, and that is correct
Still 350 of 443.
C11.03replacesC7.12one-for-one, because the withdrawn scene was being counted asC7.12's scene-cover while it was still unblessed. What changed is that the row now counted has a golden all three references agree on.Verification
cargo fmt --check,cargo clippy --workspace --exclude rustysnes-android --all-targets -- -D warnings— clean.cargo test -p rustysnes-test-harness --test accuracysnes --test accuracysnes_scenes --features test-roms— 58 passed, 0 failed.REF_PROJ=$PWD/ref-proj bash scripts/accuracysnes/crossval.sh—snes9x: 54 scene(s) match, 0 unblessed, 0 mismatched,Mesen2: 54 scene(s) match, 0 unblessed, 0 mismatched,cross-validation: 2 reference(s) agree with the cart.🤖 Generated with Claude Code