diff --git a/docs/adr/0005-automatic-hybrid-media-routing.md b/docs/adr/0005-automatic-hybrid-media-routing.md index 3ccb530..8fbf840 100644 --- a/docs/adr/0005-automatic-hybrid-media-routing.md +++ b/docs/adr/0005-automatic-hybrid-media-routing.md @@ -1,8 +1,8 @@ # ADR-0005: Automatic Hybrid Media Routing -- Status: accepted and deployed; native-edge convergence is opt-in per share +- Status: accepted; route model deployed; default-on policy pending release - Date: 2026-08-20 -- Last updated: 2026-08-27 +- Last updated: 2026-08-28 ## Context @@ -268,9 +268,10 @@ does not promise a static mathematical global optimum. Two pre-share gates constrain this same controller. Peer-only policy removes every SFU tuple and bootstrap path before reservation, so exhaustion keeps the -existing explicit failure. The initial topology-convergence rollout is opt-in; -when disabled, native evidence never creates quality work. Both gates are bound -to share generation and cannot change while sharing. +existing explicit failure. Topology convergence is enabled by default and may +be disabled before sharing; when disabled, native evidence never creates +quality work. Both gates are bound to share generation and cannot change while +sharing. ## Consequences diff --git a/docs/product/routing-transport.md b/docs/product/routing-transport.md index 2acf1aa..8460ba6 100644 --- a/docs/product/routing-transport.md +++ b/docs/product/routing-transport.md @@ -29,8 +29,9 @@ share generation: - peer-only mode excludes SFU publication, subscription, bootstrap, and quality candidates, while retaining the same bounded Peer graph and clear exhausted failure; and -- native-edge topology convergence is initially opt-in. When disabled, quality - evidence stays diagnostic and availability routing is unchanged. +- native-edge topology convergence is enabled by default. The Host may disable + it before sharing; when disabled, quality evidence stays diagnostic and + availability routing is unchanged. These are route-policy gates, not new routing algorithms. Changing either policy requires stopping the current share and starting another generation. diff --git a/docs/project-memory.md b/docs/project-memory.md index 454c71b..9ebd2e6 100644 --- a/docs/project-memory.md +++ b/docs/project-memory.md @@ -38,11 +38,11 @@ implementation and routine UI detail. one serial child operation. First decoded frame commits availability work; accepted quality work adds native edge proof before commit in that operation. - WebRTC and LiveKit own congestion control, media adaptation, reconnect, and SFU - layers. Current source uses persistent native edge state for opt-in local P2P - convergence. SFU quality work is limited to multi-root Host fanout relief and - each Viewer must prove its own candidate non-regression before commit. No - weighted score, all-pairs probe, general parent-wide prediction, or periodic - rebalance is accepted. + layers. Current source defaults persistent native-edge local P2P convergence + on, with a pre-share Host opt-out. SFU quality work is limited to multi-root + Host fanout relief and each Viewer must prove its own candidate non-regression + before commit. No weighted score, all-pairs probe, general parent-wide + prediction, or periodic rebalance is accepted. - Browser video uses `motion`; each share chooses H.264 with VP8 fallback through an actual sender probe unless the Host explicitly selects VP8 or H264. Screen audio uses 64/128/192 kbps ceilings with 128 default. diff --git a/docs/status.md b/docs/status.md index 8ca05a9..b334e0e 100644 --- a/docs/status.md +++ b/docs/status.md @@ -64,7 +64,8 @@ This is the current execution index. Git history owns completed timelines; Viewer sees first-frame readiness plus three fresh windows that strictly improve delivered resolution or rounded FPS without regressing either. Peer candidates stay first; bounded SFU is only the suffix for whole-Host-root - degradation and retains native publication proof. The gate defaults off. + degradation and retains native publication proof. The gate defaults on in + source and remains a locked pre-share opt-out. - Screener has no custom SFU layer list, quality score, layer selector, all-pairs probe, parent-wide prediction or periodic rebalancing. P2P and SFU still recover their current route before actual failure enters reassignment. @@ -86,8 +87,9 @@ subscribers back to P2P, and retired the Host SFU publication. screening did not reproduce a Host-page drop; accepted Viewer lifecycle work prevents frozen JavaScript wall time from becoming an immediate route failure but is not capture keepalive. -- Current-path quality can drive opt-in local convergence in source and - production. Weighted/global optimization remains parked. +- Current-path quality can drive local convergence in source and production. + Source defaults it on; production remains default-off until a later release. + Weighted/global optimization remains parked. - Repository simplification does not change or deploy product behavior beyond deleting proven dead private surfaces. - Native/executable senders, shared encode, distribution packages, broad UI diff --git a/src/shared/protocol.ts b/src/shared/protocol.ts index 982f00a..b361bf4 100644 --- a/src/shared/protocol.ts +++ b/src/shared/protocol.ts @@ -223,7 +223,7 @@ export const routePolicySchema = z export type RoutePolicy = z.infer; export const DEFAULT_ROUTE_POLICY = { peerOnly: false, - topologyOptimization: false, + topologyOptimization: true, } as const satisfies RoutePolicy; export const relayDownstreamEdgesSchema = z diff --git a/tests/protocol.test.ts b/tests/protocol.test.ts index 1958186..bfa5872 100644 --- a/tests/protocol.test.ts +++ b/tests/protocol.test.ts @@ -273,6 +273,10 @@ describe("client signaling protocol", () => { }); it("accepts a bounded authentication message", () => { + expect(DEFAULT_ROUTE_POLICY).toEqual({ + peerOnly: false, + topologyOptimization: true, + }); expect( decodeClientMessage( JSON.stringify({ @@ -313,6 +317,10 @@ describe("client signaling protocol", () => { role: "host", shareGeneration: "share_generation_12345678", qualitySettings: qualitySettingsWithAudio, + routePolicy: { + peerOnly: false, + topologyOptimization: true, + }, }); expect( clientMessageSchema.safeParse({