diff --git a/docs/adr/0005-automatic-hybrid-media-routing.md b/docs/adr/0005-automatic-hybrid-media-routing.md index 4ea42e7..ddb979d 100644 --- a/docs/adr/0005-automatic-hybrid-media-routing.md +++ b/docs/adr/0005-automatic-hybrid-media-routing.md @@ -283,6 +283,23 @@ second mutable graph. the counterfactual quality of another parent, so Screener creates no weighted route score, alternative-parent probe, hysteresis loop, or periodic quality-driven reparenting. +- Quality selection begins with one evidence-only shadow phase inside this same + controller. A Viewer reports standard rendered-frame, freeze and pause deltas + only while its exact current route is connected, the page is visible and not + suspended, the Host is not paused, the native video is playing, and a current + composited frame has already been proved. A strictly monotonic presentation + epoch fences every eligibility change; its first stats sample establishes a + baseline and is not evidence. The server then revalidates the authenticated + Viewer session, exact committed upstream and connection before the controller + keeps one bounded current-epoch aggregate per child. Missing stats remain + unknown, recovered freeze/pause duration may exceed one report window, and a + stale aggregate disappears from the on-demand Host diagnostic snapshot. + Shadow observation never changes facts, capacity, graph, revision, candidate + order, SFU admission or reconciliation. Active trials remain unaccepted until + annotated production evidence establishes a usable trigger and disruption + boundary; any accepted trial must reuse this controller's single child + operation, reservations, first-frame commit and rollback rather than create a + second optimizer. - Web clients derive active decoded progress from their existing periodic WebRTC/LiveKit stats sampling. One route-keyed last-progress deadline reports the exact edge once; it resets on route/connection change or decoded progress diff --git a/docs/research/realtime-quality-adaptation.md b/docs/research/realtime-quality-adaptation.md index 2fbefde..819e947 100644 --- a/docs/research/realtime-quality-adaptation.md +++ b/docs/research/realtime-quality-adaptation.md @@ -374,27 +374,44 @@ quality ceiling as a delivered floor requires a separate product SLO. Relay ingress degradation reparents that relay while retaining its subtree; one child's degradation moves only that child. -Research recommends shadow evaluation before active migration, followed by an -existing-SFU-only canary if the measured trigger has acceptable false-positive -rate. An active episode would keep the existing first-frame commit rule, allow -one low-priority trial and at most one restore, and yield immediately to join, -hard recovery, departure, capacity, pause, or SFU drain work. This post-commit -probation measures the actual presented path without holding two long-running -media routes whose competing bandwidth and non-rendered candidate metrics would -distort comparison. It necessarily permits a temporarily worse candidate and a -second transition on restore; that behavior, the freeze SLO, inconclusive result, -and permission to create or prioritize SFU resources remain product decisions. +The accepted first stage is shadow evaluation only. Viewer evidence adds the +standard cumulative-renderer deltas `framesRendered`, `freezeCount`, +`totalFreezesDuration`, `pauseCount` and `totalPausesDuration`. W3C already +defines a freeze relative to the last 30 rendered frames, so this phase invents +no FPS, bitrate, loss or latency threshold. A recovered freeze or pause updates +its duration only after a later frame is rendered, so a valid delta may exceed +the adjacent report window and must not be clipped. A missing member is unknown; +only windows containing all five rendered metrics enter the aggregate. -The current quality-evidence wire is not yet eligible for that shadow authority. -WebRTC defines freeze and pause from rendered frames, while the current payload -has decoded progress but no rendered-frame or standard pause evidence. It also -caps one recovered `freezeDuration` delta to one report window even though the -cumulative counter can legitimately jump by several windows after rendering -resumes. Presentation eligibility must bind visibility, page lifecycle, local -playback/autoplay, Host pause, current frame proof, and an identity epoch; the -first sample after any epoch change establishes a baseline only. +Presentation eligibility binds visible/not-suspended page state, non-paused +Host authority, native video play state, current composited-frame proof and the +exact connected route. Every eligibility change advances a strictly monotonic +presentation epoch. The first completed stats sample in an epoch is only a +baseline; an async sample may be emitted only if the epoch is still current. +Rate limiting remains per Viewer connection across epoch changes. -The minimal active state machine remains `observe -> qualified -> queued -> +After the signaling layer revalidates the authenticated Viewer, current upstream, +connection and room revision, the existing room controller independently checks +its exact committed edge. It retains no samples or event ring, only one safe- +integer aggregate for the latest accepted epoch of each current child: +eligible windows/duration, recovered-freeze windows/count/duration, pause +count/duration, and the last accepted time used by the existing five-second +freshness rule. The Host-only on-demand route snapshot exposes that closed +aggregate under the child's temporary ordinal; it exposes no epoch, session, +connection, raw metric or timeline. Observation does not touch controller facts +or trigger route work. + +Active migration follows only after annotated production samples establish an +acceptable false-positive and disruption boundary. An active episode would keep +the existing first-frame commit rule, allow one low-priority trial and at most +one restore, and yield immediately to join, hard recovery, departure, capacity, +pause, or SFU drain work. Post-commit probation measures the actual presented +path without holding two long-running media routes whose competing bandwidth +and non-rendered candidate metrics would distort comparison. The trigger, +probation, cooldown, inconclusive result and permission to create or prioritize +SFU resources remain the next product decision. + +The possible active state machine remains `observe -> qualified -> queued -> trial prepare -> first-frame commit -> probation -> keep | restore once -> cooldown`. It uses the existing reservation and room-serial child operation, permits no bounded-gap quality trial, and yields to availability work. Relay diff --git a/docs/status.md b/docs/status.md index 09a5923..ea3a993 100644 --- a/docs/status.md +++ b/docs/status.md @@ -62,8 +62,11 @@ This is the current execution index. Git history owns completed timelines; ## Current Milestone -1. Finish the Android Chrome and iOS Safari Viewer lifecycle matrix. -2. Finish representative public-network direct, peer-relay, SFU, recovery, +1. Implement presentation-authoritative rendered freeze/pause evidence and the + controller-owned shadow aggregate; collect production samples without active + route changes. +2. Finish the Android Chrome and iOS Safari Viewer lifecycle matrix. +3. Finish representative public-network direct, peer-relay, SFU, recovery, Pause/Resume, screen-audio, real-game A/V, and all-UDP-blocked acceptance without adding another transport or quality controller. diff --git a/docs/todo.md b/docs/todo.md index af0bdce..6dcdc26 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -7,12 +7,19 @@ later topic is not implementation authority by itself. ## Now -1. **Mobile Viewer lifecycle.** Run Android Chrome and iOS Safari matrices for +1. **Quality-route evidence and shadow calibration.** Make current Viewer + quality evidence presentation-authoritative with standard rendered freeze and + pause deltas, exact presentation epochs and baseline fencing. Keep one bounded + current-epoch aggregate per exact child in the existing room controller and + expose it only through the Host acceptance snapshot. It must not alter facts, + capacity, routes or SFU usage. Collect annotated production samples before + accepting an active trigger, probation, restore or cooldown policy. +2. **Mobile Viewer lifecycle.** Run Android Chrome and iOS Safari matrices for autoplay gesture, foreground/background audio, foreground video recovery, lock/page reclamation, rotation, Wi-Fi/cellular migration, and assigned-relay survival or controller recovery. Web does not promise background video or relay execution after OS suspension. -2. **Finish real-network route and media acceptance.** Exercise direct peer, +3. **Finish real-network route and media acceptance.** Exercise direct peer, Browser relay, SFU, relay-ingress recovery with subtree retention, disconnect/capacity drain, Pause/Resume, source replacement, screen-audio continuity, and real-game A/V sync across representative IPv4/IPv6, @@ -57,7 +64,7 @@ later topic is not implementation authority by itself. | Item | Decision | | --- | --- | | Repository and distribution license | Decide before public release or package distribution. GPL/AGPL implementations remain research-only until then. | -| Quality-driven route exploration | The intended model includes exact-child active reparenting, relay ingress reparent with subtree retention, relay egress abdication/drain, and Host egress convergence onto one SFU publication while SFU-fed Viewers may still relay. Research must first unify their evidence, reservations, probation/restore and recovery under the existing single graph/operation; no active quality route change is authorized yet. | +| Active quality-route action | Shadow evidence is authorized, but active changes are not. Production samples must first settle the trigger, probation, one-restore and cooldown boundaries. Any accepted exact-child reparent, relay abdication/drain or Host convergence onto one SFU publication must reuse the existing single graph/operation and preserve SFU-fed Viewer relay; no second optimizer or periodic rebalancer is allowed. | ## Evidence Boundaries