Skip to content

fix(ledger): retire "lit pixels" as evidence of rendering (R-18) - #178

Merged
doublegate merged 3 commits into
mainfrom
fix/r18-correlated-capture
Jul 29, 2026
Merged

fix(ledger): retire "lit pixels" as evidence of rendering (R-18)#178
doublegate merged 3 commits into
mainfrom
fix/r18-correlated-capture

Conversation

@doublegate

Copy link
Copy Markdown
Owner

No title produces a picture, and I had been implying otherwise

Asked whether a working Super Mario 64 screenshot could be saved, I captured the
scanned-out frames and — for the first time — looked at them.

Title Non-black pixels Distinct colours What it actually is
Star Wars: Rogue Squadron 68,527 / 75,840 (90%) 4,790 noise
Jet Force Gemini 69,479 / 75,840 (92%) 6,203 noise
Super Mario 64 27 18 black
Ocarina of Time 0 1 black

The lit-pixel count reports non-black scanned-out pixels, and uninitialised
RDRAM is non-black. 90% lit with thousands of distinct colours sounds like a
picture; converted to PNG and viewed, both are RDRAM garbage with no rendered
content whatever. Neither title even runs microcode, which should have been the
tell.

This is the retired > 1_000_000 failure, repeated in the same session

R-18's original root cause hid behind retired >= 1_000_000 — a threshold a
NOP-sledding machine cleared just as easily as a booted game. I diagnosed that,
wrote it up as a lesson, and then spent the rest of the session quoting another
metric with exactly the same defect.

Twice the number looked like progress and was measuring nothing.

Change

  • Video evidence now means one of two things only: a byte-comparison against
    a committed golden frame, or someone actually viewing the output.
  • The capstone still prints the count, relabelled "non-black pixels (NOT proof
    of rendering)"
    with the reason inline, so it stays a diagnostic and cannot be
    misread as a pass condition.
  • Ledger R-18 and the CHANGELOG record the retirement, including that earlier
    revisions of that row implied rendering.

Where this leaves video

screenshots/ stays empty. The most informative case is Ocarina of Time: it
executes 733 RSP instructions and submits 17,900 RDP commands, yet scans out
an entirely black frame (0 lit, 1 colour). So the microcode and the DPC seam work
while the RDP → VI presentation path does not — that is now the concrete next
target, and it is much better localised than "reach a title frame".

Also in this branch

Three R-18 hypotheses tested and refuted, recorded so they are not re-chased:
KSEG0 under 64-bit addressing; "these titles sit in the exception vector" (a
correlated capture shows ExcCode=0, EPC=00x8000_0000 is simply the
CIC-6103/6106 entry point); and R-18's original "the VI vblank interrupt never
fires" (F-Zero X receives 1,228 VI interrupts and 3,304 IP2 assertions, comparable
to a working SM64).

Gates

cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings,
cargo test --workspace, RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps, pre-commit run markdownlint --all-files — each run separately, exit
status checked.

Oracle: no emulation behaviour changes (docs + one test-output relabel), so
n64-systemtest is unchanged at 90 suite-wide, Phase 1 Failed: 0, per
docs/STATUS.md.

🤖 Generated with Claude Code

Asked whether a working Super Mario 64 screenshot could be saved, I captured the
scanned-out frames and, for the first time, LOOKED at them. Two titles I had been
citing as rendering are producing pure noise.

The lit-pixel count reports non-black scanned-out pixels, and uninitialised RDRAM
is non-black. Rogue Squadron scores 68,527 of 75,840 (90%) with 4,790 distinct
colours; Jet Force Gemini 69,479 (92%) with 6,203. Converted to PNG and viewed,
both are RDRAM garbage with no rendered content whatever - and neither title even
runs microcode, which should have been the tell.

This is the retired > 1_000_000 failure again, and I repeated it in the same
session I diagnosed it: a metric a broken machine satisfies exactly as easily as
a working one, quoted for weeks because nobody opened the image. Twice now the
number looked like progress and was measuring nothing.

Video evidence now means one of exactly two things: a byte-comparison against a
committed golden frame, or someone actually viewing the output. The capstone
still prints the count, relabelled "non-black pixels (NOT proof of rendering)"
with the reason inline, so it stays a diagnostic and cannot be misread as a pass.

Actual state: no title produces a picture. Super Mario 64 scans out 27 lit pixels
of 75,840 - effectively black. Ocarina of Time executes 733 RSP instructions and
submits 17,900 RDP commands yet scans out an entirely black frame (0 lit, 1
colour), so the RDP-to-VI presentation path is the next thing to close.
screenshots/ stays empty.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@doublegate, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 02fad749-2126-40f8-9bc2-209bb1addba8

📥 Commits

Reviewing files that changed from the base of the PR and between d1591fe and 2db4855.

📒 Files selected for processing (1)
  • crates/rustyn64-test-harness/tests/commercial_boot.rs
📝 Walkthrough

Walkthrough

R-18 documentation and commercial-boot diagnostics now distinguish non-black pixel counts from rendering evidence, prioritising microcode loading and RDP command submission while recording the remaining proof gap.

Changes

R-18 evidence clarification

Layer / File(s) Summary
Update R-18 diagnosis and evidence
docs/accuracy-ledger.md, CHANGELOG.md
R-18 records now replace non-black pixel counts with microcode loading and RDP command submission as verifiable indicators, and define golden-frame comparison or actual viewing as rendering proof.
Align boot diagnostic wording
crates/rustyn64-test-harness/tests/commercial_boot.rs
The boot diagnostic labels the metric as non-black pixels and states that it is informational rather than a rendering pass condition.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • doublegate/RustyN64#173: Updates the same commercial boot verification flow and R-18 evidence records after the IPL3 boot fix.
  • doublegate/RustyN64#177: Also revises the R-18 documentation to clarify that “lit pixels” do not prove rendering.
🚥 Pre-merge checks | ✅ 10
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed The title matches Conventional Commits and clearly summarises the ledger change.
Description check ✅ Passed The description is directly about retiring lit-pixel counts as rendering evidence and updating the ledger and changelog.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Oracle Number Is Stated ✅ Passed Docs/tooling-only; the description says n64-systemtest is unchanged at 90 suite-wide / Phase 1 Failed: 0, matching docs/STATUS.md.
Docs-As-Spec Sync ✅ Passed PASS: only CHANGELOG.md and a test-harness label changed; no chip-crate or docs/<subsystem>.md files were touched, and the PR body says emulation behaviour is unchanged.
Changelog Entry For User-Visible Changes ✅ Passed Correct: CHANGELOG.md has an Unreleased Fixed entry for ledger R-18, matching the user-visible fix.
Measured, Never Tuned ✅ Passed No new hardware constant or timing value was introduced; the added numerics are R-18 measurement evidence already recorded in docs/accuracy-ledger.md.
Unsafe Stays Out Of The Chip Crates ✅ Passed PASS: the diff only edits docs/test output; chip crates and rustyn64-core still have #![forbid(unsafe_code)], and no unsafe code appears outside rustyn64-frontend.

Comment @coderabbitai help to get the list of available commands.

Review follow-up. "### Corrected" was a one-off heading in a file that otherwise
uses Added/Fixed/Changed 161 times between them; it is now "### Fixed".

The five-line comment inside the eprintln! restated the ledger's R-18 entry
verbatim, which is both clutter and a second copy to drift. Cut to one line
naming the rule and pointing at R-18, where the evidence and the measurements
belong.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@doublegate

Copy link
Copy Markdown
Owner Author

Antigravity — the five-line comment duplicates the ledger. ADOPTED. It restated R-18's entry verbatim inside an eprintln!, which is clutter and a second copy to drift out of sync. Cut to one line naming the rule and pointing at R-18, where the evidence and measurements belong.

Nitpick — ### Corrected is a non-standard heading. ADOPTED. Checked against the file rather than the spec: it uses Added/Fixed/Changed 161 times between them, and Corrected appeared exactly once — mine. Now ### Fixed.

Both are the same small failure on my part: writing as if this entry were special enough to need its own vocabulary and its own copy of the evidence. It is not; the ledger row is the spec and the CHANGELOG has a convention.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/rustyn64-test-harness/tests/commercial_boot.rs`:
- Around line 166-169: Rename the diagnostic metric field and all references
from `lit` to `non_black_pixels`, including `BootResult.lit`, its initialization
and propagation, and the formatted output in the commercial boot harness.
Preserve the existing value and ensure it remains diagnostic-only rather than a
rendering-pass condition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1494e06c-8129-4282-9f0b-e3a460bf2562

📥 Commits

Reviewing files that changed from the base of the PR and between 21947ff and d1591fe.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • crates/rustyn64-test-harness/tests/commercial_boot.rs
  • docs/accuracy-ledger.md

Comment thread crates/rustyn64-test-harness/tests/commercial_boot.rs Outdated
The message said "NOT proof of rendering" while the value still flowed through a
field called lit, so the name kept asserting what the label denied - and a name
is what a future assertion reaches for. Renamed at the field, the local, and the
module docs, with the reason on the field rather than only in the ledger.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Antigravity review (Gemini via Ultra)

This PR updates documentation, changelogs, and integration test diagnostics to rename the "lit pixels" metric to "non-black pixels" and document that non-black scanout is uninitialized RDRAM noise rather than proof of rendering.

Blocking issues

None found.

Suggestions

  • commercial_boot.rs: (w * h) as usize risks 32-bit multiplication overflow before casting to usize; use (w as usize) * (h as usize) instead.

Nitpicks

  • Inconsistent number formatting between CHANGELOG.md (68,527) and docs/accuracy-ledger.md (68 527).

Automated first-pass review by agy on a self-hosted runner -- not a human review.

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