LOBBY RESTORATION - PATCH PIPELINE LAYER

Approved scope
Restore the preserved original lobby composition and add the current spectator
features within it. Do not replace the party runtime, wire protocol, guest,
renderer or rollback algorithm. Retain Store Vehicles and Rollback-only policy.

Composition
ReleaseOverlay.cmake composes after store-vehicles and stages exactly two final
translation units plus the final online UI include into the external build tree.
It adds a bounded native presentation adapter to DKRNetplayCore. Adjacent header
paths are rebased; compiler/RT64 header selection stays with the retained build.
No checked-out submodule, RecompiledFuncs or RecompiledPatches source is edited.

Restored shell
The party-only early return is removed. DrawOnlinePage again draws its original
header/ROM field, tabs, main column, profile/guide column, shared notices,
countdowns, keyboards and confirmations. DrawOlLobby retains the original panel,
cream code plate, avatars, cards, lights, Ready/Start bar and footer.

Party projection
One bounded sanitized snapshot copies roster/control leases, readiness, verified
save-seed availability and heartbeat measurements under the party mutex. The
four visible racer cards are derived from the current lease owners, not from
stale original peer slots. Spectators retain no local_slot (255). A host who is
watching is still identified as the host without assuming ownership of P1.
Pending joins use their requested role: four racer ports, eight spectator
places, twelve total participants, spectators only while a race is running.

Actions
Existing ready/start/role/swap/camera/stop APIs remain authoritative. Player
dialogs capture room, member and roster generation; swap actions also recheck
the current outgoing lease owner before queuing the existing party request.
The camera chooser maps visible rows to actual ports, including sparse ports.
Room replacement/disconnect closes this layer's modal confirmations.

Removal
The restored host removal action queues a bounded request keyed by stable member,
room and generation. DirectSession's owner thread revalidates host/room/member/
generation/no handover, sends the existing authenticated Leave, flushes before
releasing the peer route, removes that exact member and clears their requests.
Removing an active racer uses the existing safe stop/return path; removing a
spectator does not stop the race. No controller lease is edited by the UI.
The existing lobby-lock operation is permitted while a party race is running;
its original host gate, pending-route cleanup and implementation are retained.

Connection panel
The legacy four-player preflight path is not used for party lobbies. Existing
authenticated heartbeat RTT rings are sampled over seven seconds with no new
packets or wire format. Results report reply count, median, p95 and range only.
Roster changes or a UI-polling interruption cancel the sample. Other clients'
measurements are not invented on a non-host client. No performance grade or
gameplay packet-loss claim is derived from these probes.

Validation boundary
audit.py verifies exact staged transforms and source receipts, original unchanged
component regions, final linked feature markers, all retained audit contracts,
and the earlier authored-source baseline. package.py uses the existing runtime
allowlist, architecture/version checks, ZIP CRC and AppImage SquashFS inspection.
No game, test executable, mod or AppImage is launched. The owner performs all
gameplay, controller, visual and real-network acceptance testing.

Build outputs
Windows x64 ZIP and Linux x86_64 AppImage, 1.0.9-spectator-playtest.6.
Fresh output directories preserve earlier playtests. No publication, automatic
update signing, commit/push, website deployment or user-data mutation is included.
