ROLLBACK LOBBY SCOREBOARD - PLAYTEST 13
======================================

Scope
-----
The approved Lobby Scoreboard design replaces only the connection-results modal.
New authoring lives under patches/rollback-scoreboard. Three first-party units
are substituted externally after accepted Playtest 12: runtime_ui.cpp,
direct_session.cpp (diagnostic header/context only), rollback_check.cpp.
No guest, renderer, simulation, save, mod, dependency or checked-out generated
recomp source is changed. The five-second countdown, canonical checkpoint clock,
party retirement, invite handling and original restored lobby remain composed.

Recovery snapshot: D:/DiddykongWorkFolder/rollback-scoreboard-20261024/baseline

Diagnostics and report sharing
------------------------------
The existing authenticated diagnostic envelope gets an independent v2 marker.
This is NOT a change to game input or gameplay wire framing. Existing 30 Hz
racer probes, 20 Hz spectator/repair probes, two-second negotiation, six-second
sample and two-second drain remain. An older diagnostic is explicitly unsupported
rather than treated as a bad connection. Normal runtime clocks are untouched.

Context now includes the entire authenticated participant roster and each role,
in addition to the actual host/peer transport identities. Party members use their
stable authenticated IDs. Non-party Room payloads do not carry all authentication
IDs, so reports use generation-bound port tokens; no controller is assigned by
the diagnostic. Names come only from the current validated roster, not report
text. Metadata or role changes invalidate the report. Automatic-delay heartbeat
adjustments retain existing behavior; the report explicitly shows the effective
delay at test start. No suggested delay is written into settings.

The host freezes at most twelve rows. Every compatible client receives every
row, including unsupported participants and the local host. Rows fit the existing
96-byte diagnostic payload, delivered on authenticated Control with bounded
round-robin pacing (at most twelve packets per service pulse), 500 ms retry cycles
and a three-second overall delivery limit. There is no retained synthetic game
backlog. Existing per-route readiness/backpressure checks remain authoritative.

Each received row must match diagnostic version, policy, nonce/test, roster
generation, count, member identity, role, host identity and tested settings.
Counts and timing values are bounded. Duplicates must be byte-identical. Every
row's global metadata must agree, with unique member IDs and complete roster
coverage before publication. A client never displays a partial report as final.
Only the authenticated host can deliver rows. The complete report is receipted;
receipts are rate limited. Session reset and cancellation erase partial state.

Scoring policy v1
-----------------
Arrival timing 35%, successful probe replies 35%, timing consistency 20%, median
round-trip delay 10%. Score is rounded and clamped to 1..10; zero internally
means unrated, displayed as --. At least 90 racer/60 spectator main replies are
required; non-party repair lanes also need 60 replies. Global scheduling/queue
pressure or significant local blocked sends withhold grades, not assign blame.

Racer headroom uses the existing conservative arrival allowance:
  (delay + max(prediction_window - 2, 0)) * 1000/30 - (max(p95,repair_p95)+8ms)
It is a host-star round-trip estimate, not measured one-way delay. Spectator
arrival grading instead uses playback timing bands, never racer delay/window.

Timing subgrade by racer margin in frames: >=3:10, >=2:9, >=1:8, >=0:7,
>=-1:5, >=-2:3, otherwise 1. Playback p95 bands (ms): <=80:10, <=120:9,
<=180:8, <=250:7, <=350:5, <=500:3, otherwise 1.
Reply deficit bands (%): <=0.5:10, <=1:9, <=2:8, <=5:6, <=10:4, otherwise 2.
Mean adjacent RTT variation bands (ms): <=4:10, <=8:9, <=16:8, <=25:6,
<=40:4, <=60:2, otherwise 1. Median RTT bands (ms): <=40:10, <=80:9,
<=120:8, <=180:7, <=250:5, <=400:3, otherwise 1.
Missing replies >2% cap at 7, >5% at 5, >10% at 3. Racer p95 >250 ms caps
at 7, >400 ms at 5; negative conservative margin caps at 4. Increasing input
delay cannot remove reliability, variation or latency weaknesses. Missing probes
are not presented as measured gameplay packet loss. Wire-precision normalization
ensures host/client assessment agrees at rounding boundaries.

The overall race score is the minimum remote-racer grade. Any unrated racer
makes it incomplete. Spectators are excluded. The host shows that aggregate,
not a self-ping. With no remote racers, no racing score is invented. Host upload
capacity, gameplay FPS, replay cost and checkpoint bandwidth are not benchmarked.
This versioned policy is heuristic and needs user field calibration; it is not
a promise of desync-free play or hardware performance.

UI and verification
-------------------
Dedicated rounded modal, fixed header/footer, exactly one scrolling body, full
width native navigation rows, explicit focus rings, expandable details, tested
settings, policy explanation and existing automatic-delay advice. B/Escape first
closes detail and restores focus to its row, then closes the popup. Re-run is
host-only and disabled while busy. Width-responsive row text wraps rather than
truncating; footer stacks on narrow surfaces. Other dialogs are unchanged.

Static audits recompose outputs byte-for-byte, follow source replacement graphs
to final compiler bindings, run retained source-contract audits, compare the
accepted Playtest 12 departure/checkpoint identities, and compare every baseline
authored file. Linked markers and package architecture/allowlists/hashes are
checked. Policy endpoints/monotonic example are compile-time assertions. No
game, mod, test executable or AppImage is run. User gameplay/network/controller
acceptance remains pending. No Git commit/push, publication or updater signing.
