8.8 KiB
8.8 KiB
Project Memory
Last updated: 2026-08-26
Current Product Truth
- Screener is private, low-latency game screen sharing for one Host and up to
20authenticated Viewers, not a public broadcast service. - Web Host, Viewer, and Browser relay are the current delivery surface. Native capture, shared encoding, and distributable server/local packages remain later work.
- Rooms are bounded process memory: random free
1000..9999code, default 24-hour dormant lease, active sharing never expires, exact Host token resume, Viewer activity does not renew, and process restart loses every room and credential. A Host may request its last locally remembered active code when creating a new room; the server uses it only while free and always creates a new room incarnation. There is no database or migration path. - Every room has one 128-bit/22-character Viewer grant bound to that exact room
incarnation and independent
open | privatecode entry. Private without a password is invitation-only; adding a password also permits matching code entry. Reclamation, restart, rotate, or revoke ends the grant. Missing codes returnROOM_NOT_FOUNDwithout a password prompt. - Host creation preferences and raw ownership token stay local to the Host browser. Server authority stores only current-process digests/verifiers and never uses IP, UA, device, or browser fingerprint as identity.
Media And Routing
- Media stays automatic and distributed. Ordinary peer ICE is STUN-only and direct/peer UDP is preferred. The only application fallback is the dedicated LiveKit SFU over UDP; Screener configures no TURN, ICE/TCP, media TCP, or TLS-relayed media.
- Browser LiveKit publisher/subscriber PCs use no external ICE server and retain LiveKit-signaled UDP candidates. Deployment STUN remains available to ordinary peers and LiveKit server-side public-IP discovery.
- Every non-server endpoint uses one server-authoritative steady outbound copy
cap: default
2, configurable only as1,2, or3. A peer child or the Host publication consumes one slot; upstream receive is free; SFU subscriber egress uses separate server admission. - One room controller owns one committed acyclic source-reachable graph, one event-driven reconciliation loop, and at most one room-serial child operation. The operation owns one deterministic candidate list/cursor, one current candidate and reservations, one fact version, and one total deadline.
- Candidate filtering enforces current authority, reachability, acyclicity, capacity, transition slots, and server admission. Eligible P2P parents are ordered by resulting depth, remaining capacity, a stable child-parent hash, join order, and peer identity.
- A candidate commits only after the exact child decodes its first new video frame. Exact direct transport-connected progress may retain the candidate through the total deadline but cannot commit. Failure releases resources, broadcasts a strictly newer rollback revision, advances the cursor without resetting the deadline, and preserves unaffected healthy branches. SFU-backed Viewers keep working media while finite direct candidates converge in background round-robin. A relay with bad ingress reparents itself while retaining its subtree.
- Healthy decoded routes remain sticky. There is no periodic rebalancing, quality score, all-pairs probing, parent blacklist, NAT classification, port prediction, or independent depth cap. Quality evidence cannot prove an unconnected parent would be better.
- P2P and SFU first use their framework reconnect behavior. P2P recovery tries the same parent, and SFU recovery rebuilds the same publication/subscription. Manual media reconnect also stays on the current exact route. Only actual recovery exhaustion, hard failure, non-paused decoded-frame stall, parent departure, or capacity invalidation enters route reassignment.
- Active-path WebRTC/LiveKit sampling owns one exact-route decoded-progress deadline. Route/connection change or new progress resets it; authoritative pause suppresses it. Page resume rebaselines frozen wall-clock time before another no-progress sample can fail a route.
Media Quality
- Production candidate
5551177runs one sender-scoped actual-sender preflight with a deterministic moving probe track sized to the current share target, so captured-content motion cannot decide encoder capability. Proved senders prefer H.264 with native VP8 fallback, while failed/inconclusive senders remain VP8-only. Codec UI/state/wire, persistent codec cache, parallel codec media, backup publication, and active-edge codec switching remain absent. Display video usescontentHint = "motion"and display audio usescontentHint = "music". Canonicalmainhas accepted this contract but its application tree remains fixed VP8 until production acceptance and integration. - Windows Chrome 151 uses software VP8 and exposes no Web control for selecting NVENC, AMF, QSV, a GPU, or an MFT. Edge, non-Windows paths, and real-game CPU contention remain evidence-specific.
- Recommended profiles remain exactly
720p30,1080p30, and1080p60, with1080p30default.480pis only an advanced854x480resolution choice; advanced FPS and bitrate remain independent. - WebRTC owns direct/peer media adaptation. The Host reapplies the selected video profile after answer negotiation; no periodic application controller exists.
- The production SFU publisher uses the Host's H.264/VP8 decision and selected ceiling but no backup codec or custom simulcast layers. Pinned LiveKit defaults own representations, Dynacast owns aggregate demand, and server send-side BWE owns subscriber forwarding. AdaptiveStream stays disabled because any Viewer may relay its received track.
- Screen audio requests capture by default and offers live 64/128/192 kbps sender ceilings with 128 default. Peer answers request Opus stereo with a 192 kbps receive maximum. SFU publication uses stereo, DTX off, and RED off; disabling RED accepts reduced burst-loss resilience in exchange for bounded publisher traffic.
- Configured resolution, FPS, bitrate, preference, codec, and audio ceiling are requests or ceilings. Sender readback and RTCStats are the observable truth.
Presentation And Lifecycle
- Viewer presentation is revision/generation-fenced and keeps the stage stable
until a current-generation composited frame. A new current frame clears stale
media
connecting/reconnectingpresentation; old callbacks cannot prove a new route. - Viewer local play/pause, volume, mute, and fullscreen are owned by native video controls on one persistent media element. Host preview is a muted, control-free view of the capture stream; only explicit Host actions pause or stop sharing.
- Viewer hidden/freeze/pagehide suppress application decoded-stall authority; visible/resume/pageshow rebaseline and rearm current-frame proof. SFU pagehide does not make LiveKit actively disconnect, while SDK freeze behavior, playback, background audio, page reclamation, and relay survival remain physical gates.
- Hiding or unfocusing the Host page pauses only the local preview element. Browser/OS capture and background behavior remain platform capabilities; no fake keepalive, silent media, Wake Lock, or timer loop is a product mechanism.
Current Source And Production
- Production and canonical source use strict
screener-v12, but the pending application candidate adds the internal H.264/VP8 decision while production remains on its prior fixed-VP8 artifact. Exact identities are indexed by status. - Production uses random memory rooms, 20-Viewer admission, endpoint cap
2, fixed 9,000-publication ingress and9000 * 20subscription egress admission, STUN UDP 3478, LiveKit media UDP 7882, and Web TCP 80/443. Node 8787 and LiveKit 7880 remain private. - Exact artifact and service state are owned by deployment and indexed by status. Physical evidence boundaries are owned by verification status.
Current Priority
- Validate and integrate production candidate
5551177, then simplify the local preferred-room record while retaining the server lease. - Complete the mobile Viewer lifecycle matrix and representative real-network route/media acceptance.
Quality-driven parent selection, Native sender work, distribution packages, whole-product UI/bilingual polish, and repository-wide simplification remain later decisions in the TODO ledger.
Working Rules
- Generic authority and scope follow the repo-tracked
stop-that-shitskill. - Canonical
mainand the current truth owners override old branches, worktrees, handoff text, and chat summaries. - Preserve unique or dirty candidates until integration and reference/reparse audits prove cleanup is safe.