docs: align recovery authority truth (#280)
This commit is contained in:
1 parent
06c154a080
commit
c0c5b1e661
8 files changed
+68
-46
No files matched your search
+2
-2
@@ -18,7 +18,7 @@
|
||||
- [Native H.264 hardware decision](./research/native-h264-hardware-decision.md): bounded WebCodecs no-go, proved Media Foundation/NVIDIA hardware encode, the default-fmtp `42c01f` stop, and the retained interop boundary.
|
||||
- [Native H.264 opt-in path](./research/native-h264-opt-in-path.md): explicit H.264 sender mode, exact Pion profile registration, and one bounded Host/Viewer loopback with hardware caveats.
|
||||
- [Realtime quality adaptation](./research/realtime-quality-adaptation.md): Browser codec and `motion` evidence, manual quality ceilings, path-quality authority, and LiveKit-owned SFU representation adaptation.
|
||||
- [Cross-restart room recovery](./research/cross-restart-room-recovery.md): pending lineage, authority-epoch, invitation-replay, and bounded media-rebuild evidence without reopening durable room storage.
|
||||
- [Cross-restart room recovery](./research/cross-restart-room-recovery.md): room-authority lineage, optional SQLite stable mode, invitation continuity, and process-fresh media rebuild evidence.
|
||||
- [Browser background capture diagnostics](./research/browser-background-capture.md): browser lifecycle evidence, a privacy-bounded capture/send/receive experiment, interpretation gates, and non-goal keepalive mechanisms.
|
||||
- [Browser screen-audio quality](./research/browser-screen-audio-quality.md): capture/source compatibility, live sender-ceiling readback, Opus negotiation boundaries, and remaining audible/device evidence.
|
||||
- [Display name and presence boundaries](./research/display-name-presence.md): browser-local storage failure behavior, Unicode normalization, control-character policy, and the Web-only presence capability boundary.
|
||||
@@ -28,7 +28,7 @@
|
||||
- [ADR-0004](./adr/0004-peer-assisted-media-experiment.md): historical standard-WebRTC peer-assisted experiment and reusable evidence.
|
||||
- [ADR-0005](./adr/0005-automatic-hybrid-media-routing.md): accepted P2P-first single-reconcile route model, including deployed Browser SFU ICE-server isolation; remaining real-network validation is tracked in verification status.
|
||||
- [ADR-0006](./adr/0006-fixed-high-native-sender-canary.md): proposed fixed-`HIGH` native canary, current no-go result, and staged revalidation boundary.
|
||||
- [ADR-0007](./adr/0007-path-isolated-representation-quality.md): accepted LiveKit-owned pinned-default VP8 SFU adaptation, pinned evidence, and application-controller/SVC boundaries.
|
||||
- [ADR-0007](./adr/0007-path-isolated-representation-quality.md): accepted LiveKit-owned SFU representation adaptation, pinned evidence, and application-controller/SVC boundaries.
|
||||
- [ADR-0008](./adr/0008-window-scoped-audio-capture.md): browser window-audio hint and the Windows WASAPI process-loopback boundary.
|
||||
|
||||
Documentation and project memory are part of the product source of truth. Update them in the same change that alters the corresponding requirement or architecture.
|
||||
@@ -236,6 +236,9 @@ second mutable graph.
|
||||
removed naturally.
|
||||
- The Host is the only source publisher. There is at most one authoritative Host
|
||||
publication per share generation, and every SFU-fed Viewer subscribes to it.
|
||||
The Host page owns the canonical capture tracks. LiveKit publisher teardown,
|
||||
remote room deletion, and transport recovery may release only their SFU
|
||||
publication and must never stop those capture tracks.
|
||||
Any source-reachable endpoint with effective capacity may be a parent
|
||||
candidate; SFU-fed and peer-fed endpoints use the same provisional-child
|
||||
transaction and each child edge commits independently. Viewer republishing
|
||||
|
||||
+8
-8
@@ -3,7 +3,7 @@
|
||||
Last verified: 2026-08-26.
|
||||
|
||||
This page records production running exact deployed application/runtime revision
|
||||
`3037c0a8f0d16e0df791eb8e64003a7a6660d521`, release `3037c0a`, and the single
|
||||
`8164102af8083d55632cf5de10197b5823b3d140`, release `8164102`, and the single
|
||||
Browser `screener-v12` contract. Product direction and pending work are owned by
|
||||
[project memory](./project-memory.md) and [the TODO ledger](./todo.md).
|
||||
|
||||
@@ -25,16 +25,16 @@ ICE/UDP only. Ordinary peer ICE remains STUN-only and production coturn uses the
|
||||
tracked STUN-only configuration with TCP/TLS disabled. The source and production
|
||||
configure no TURN, ICE/TCP, media TCP, or TLS-relayed media.
|
||||
|
||||
Production runs exact `3037c0a8f0d16e0df791eb8e64003a7a6660d521`, release
|
||||
`3037c0a`, from `/opt/screener/releases/3037c0a`. The immutable runtime tar
|
||||
Production runs exact `8164102af8083d55632cf5de10197b5823b3d140`, release
|
||||
`8164102`, from `/opt/screener/releases/8164102`. The immutable runtime tar
|
||||
SHA-256 is
|
||||
`f84cb7f7acbfbd950ecfdac13da9a0d6e99a4c10eb221c6948ce81b47ce2b5f6`.
|
||||
`1f61395702afaabfda8c178a08c7896af77e1c4750dcc9f29ffaafbd56bba80f`.
|
||||
Its 41-file path/size/hash manifest SHA-256 is
|
||||
`e2fc8115c9cb7d6455027dc2af6f29229834774ed12de334832a8d53d6fc6262`.
|
||||
`55b9779fdaf4fe2ba98d5612b16e398fbf2ad6b9ebcfeeeef6e0ce5c3595ac8d`.
|
||||
Local and public `/healthz` return 200; Screener, LiveKit, coturn, and nginx are
|
||||
active with `NRestarts=0`. The public main Browser asset is
|
||||
`assets/index-Y4pFjW_S.js` with SHA-256
|
||||
`a3df27613dfb10fb45297197afdf2500e2953c2b5330b13e5bb49eafdc3e1447`.
|
||||
`assets/index-CPECbwjN.js` with SHA-256
|
||||
`dfcbed5d4178afbd7f6713f1ae348a70921b936199fa56d87fa05c785564559e`.
|
||||
|
||||
The release deploys the single Browser `screener-v12` wire and one internal,
|
||||
content-independent H.264 sender gate with VP8 fallback across Browser direct,
|
||||
@@ -296,7 +296,7 @@ must fail or wait before a fourth endpoint copy is issued.
|
||||
Supplying the removed `MAX_PEER_RELAY_DOWNSTREAM_EDGES`, even blank, fails
|
||||
startup.
|
||||
|
||||
Production release `3037c0a` runs the deployed server and Browser assets
|
||||
Production release `8164102` runs the deployed server and Browser assets
|
||||
atomically on `screener-v12`; every stale Browser or executable-sender wire fails
|
||||
before room authority. Native senders and helpers are outside this release.
|
||||
|
||||
|
||||
+24
-17
@@ -8,22 +8,23 @@ This is the current execution index. Git history owns completed timelines;
|
||||
## Production
|
||||
|
||||
- `https://share.bonfire.icu` runs exact application/runtime revision
|
||||
`3037c0a8f0d16e0df791eb8e64003a7a6660d521`, release `3037c0a`, wire
|
||||
`screener-v12`, from `/opt/screener/releases/3037c0a`. The immutable runtime
|
||||
`8164102af8083d55632cf5de10197b5823b3d140`, release `8164102`, wire
|
||||
`screener-v12`, from `/opt/screener/releases/8164102`. The immutable runtime
|
||||
tar SHA-256 is
|
||||
`f84cb7f7acbfbd950ecfdac13da9a0d6e99a4c10eb221c6948ce81b47ce2b5f6`;
|
||||
`1f61395702afaabfda8c178a08c7896af77e1c4750dcc9f29ffaafbd56bba80f`;
|
||||
its 41-file manifest SHA-256 is
|
||||
`e2fc8115c9cb7d6455027dc2af6f29229834774ed12de334832a8d53d6fc6262`.
|
||||
- The served Browser entry references `assets/index-Y4pFjW_S.js`; the public
|
||||
`55b9779fdaf4fe2ba98d5612b16e398fbf2ad6b9ebcfeeeef6e0ce5c3595ac8d`.
|
||||
- The served Browser entry references `assets/index-CPECbwjN.js`; the public
|
||||
asset SHA-256 is
|
||||
`a3df27613dfb10fb45297197afdf2500e2953c2b5330b13e5bb49eafdc3e1447`.
|
||||
`dfcbed5d4178afbd7f6713f1ae348a70921b936199fa56d87fa05c785564559e`.
|
||||
Public `/healthz` returns 200. The release postflight found Screener, LiveKit,
|
||||
coturn, and nginx active with zero restarts.
|
||||
- Production enables SQLite room authority at
|
||||
`/var/lib/screener/rooms.sqlite`; live participants, routes and media remain
|
||||
process-only. A controlled restart retained a temporary room's exact Host
|
||||
authority and normal room deletion removed it afterward. Lightweight mode
|
||||
remains available when `ROOM_DATABASE_PATH` is unset.
|
||||
process-only. A controlled restart retained the room authority and Host-owned
|
||||
capture while the Viewer rebuilt media without a page refresh. Lightweight
|
||||
mode remains available when `ROOM_DATABASE_PATH` is unset and reacquires a
|
||||
room rather than persisting the old authority.
|
||||
- Public media listeners remain STUN-only UDP 3478 and LiveKit UDP 7882. Web
|
||||
ingress is TCP 80/443; Node 8787 and LiveKit control/signaling 7880 are
|
||||
private. TURN, ICE/TCP, media TCP, TLS relay, port 5349, and relay ranges are
|
||||
@@ -41,10 +42,11 @@ This is the current execution index. Git history owns completed timelines;
|
||||
|
||||
## Current Source
|
||||
|
||||
- Canonical `main` contains the same application tree deployed from `3037c0a`.
|
||||
- Canonical `main` contains the same application tree deployed from `8164102`.
|
||||
Optional SQLite stable authority, non-expiring local preferred code, atomic
|
||||
room replacement, graceful service-restart presentation and the Host codec
|
||||
selector are implemented; production selects stable storage.
|
||||
room replacement and the Host codec selector are implemented; production
|
||||
selects stable storage. Graceful restart, crash, timeout and network loss use
|
||||
one reconnect state. LiveKit room teardown cannot stop Host-owned capture.
|
||||
- One event-driven controller owns the committed graph and one room-serial child
|
||||
operation. Initial direct acquisition uses a five-second foreground window;
|
||||
exact transport-connected progress may retain that candidate through the
|
||||
@@ -62,11 +64,15 @@ This is the current execution index. Git history owns completed timelines;
|
||||
|
||||
## Current Milestone
|
||||
|
||||
1. Implement presentation-authoritative freeze/pause evidence with decoded
|
||||
1. Close the confirmed authority/recovery P1s: typed KDF gate outcomes, exact
|
||||
route-terminal ownership, assignment-fenced child creation, bounded SFU
|
||||
refresh, exact Viewer authentication outcomes, and reconnect-safe Host
|
||||
quality intent.
|
||||
2. Implement presentation-authoritative freeze/pause evidence with decoded
|
||||
progress 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,
|
||||
3. Finish the Android Chrome and iOS Safari Viewer lifecycle matrix.
|
||||
4. 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.
|
||||
|
||||
@@ -85,5 +91,6 @@ This is the current execution index. Git history owns completed timelines;
|
||||
|
||||
## Current Hold
|
||||
|
||||
No source or deployment P0 is open. Representative real-network and mobile
|
||||
physical evidence remains required before route acceptance is complete.
|
||||
No source or deployment P0 is open. The recovery/authority P1 milestone blocks
|
||||
active quality-route behavior; representative real-network and mobile physical
|
||||
evidence remains required before route acceptance is complete.
|
||||
+15
-4
@@ -7,7 +7,15 @@ later topic is not implementation authority by itself.
|
||||
|
||||
## Now
|
||||
|
||||
1. **Quality-route evidence and shadow calibration.** Make current Viewer
|
||||
1. **Recovery and authority convergence.** Close the confirmed P1 owner gaps
|
||||
before active quality work: return distinct KDF `busy | cancelled | value`
|
||||
outcomes without committing a passwordless room; return the exact exhausted
|
||||
demand identity from the route controller and emit its terminal once; fence
|
||||
every Host child retry to the current assignment; make SFU refresh end in
|
||||
typed config or failure; preserve exact Viewer authentication outcomes; and
|
||||
retain one Host quality intent until the server confirms or rejects it. These
|
||||
are existing owner corrections, not new retry loops or fallback controllers.
|
||||
2. **Quality-route evidence and shadow calibration.** Make current Viewer
|
||||
quality evidence presentation-authoritative with standard freeze/pause
|
||||
deltas, continuing decoded progress, exact presentation epochs and baseline
|
||||
fencing. Keep one bounded
|
||||
@@ -15,12 +23,12 @@ later topic is not implementation authority by itself.
|
||||
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
|
||||
3. **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.
|
||||
3. **Finish real-network route and media acceptance.** Exercise direct peer,
|
||||
4. **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,
|
||||
@@ -58,7 +66,10 @@ later topic is not implementation authority by itself.
|
||||
physical-media checkpoints settle, inventory components, configuration,
|
||||
migrations, timers, compatibility paths, tests, and truth duplication using
|
||||
the [maintenance review](./maintenance.md#机制减负审查). Begin read-only and do
|
||||
not turn it into a broad refactor.
|
||||
not turn it into a broad refactor. The current read-only scan confirmed
|
||||
coarse `mediaAssignment` wire residue, legacy SFU room-name acceptance,
|
||||
and duplicated teardown/test/browser-gate owners as the bounded starting
|
||||
set; it did not authorize unrelated cleanup.
|
||||
|
||||
## Product Decision Needed
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@ may be interpreted. Git and pull requests own routine completed checks.
|
||||
## Current Production Identity
|
||||
|
||||
- Production runs exact application/runtime revision
|
||||
`3037c0a8f0d16e0df791eb8e64003a7a6660d521`, release `3037c0a`, wire
|
||||
`screener-v12`, from `/opt/screener/releases/3037c0a`.
|
||||
`8164102af8083d55632cf5de10197b5823b3d140`, release `8164102`, wire
|
||||
`screener-v12`, from `/opt/screener/releases/8164102`.
|
||||
- Runtime tar SHA-256:
|
||||
`f84cb7f7acbfbd950ecfdac13da9a0d6e99a4c10eb221c6948ce81b47ce2b5f6`.
|
||||
`1f61395702afaabfda8c178a08c7896af77e1c4750dcc9f29ffaafbd56bba80f`.
|
||||
The 41-file manifest SHA-256 is
|
||||
`e2fc8115c9cb7d6455027dc2af6f29229834774ed12de334832a8d53d6fc6262`.
|
||||
- Public Browser asset `assets/index-Y4pFjW_S.js` has SHA-256
|
||||
`a3df27613dfb10fb45297197afdf2500e2953c2b5330b13e5bb49eafdc3e1447`.
|
||||
`55b9779fdaf4fe2ba98d5612b16e398fbf2ad6b9ebcfeeeef6e0ce5c3595ac8d`.
|
||||
- Public Browser asset `assets/index-CPECbwjN.js` has SHA-256
|
||||
`dfcbed5d4178afbd7f6713f1ae348a70921b936199fa56d87fa05c785564559e`.
|
||||
Public `/healthz` returns 200. Release postflight found Screener, LiveKit,
|
||||
coturn, and nginx active with zero restarts.
|
||||
|
||||
@@ -26,8 +26,9 @@ may be interpreted. Git and pull requests own routine completed checks.
|
||||
room-lived Viewer grants, `open | private` code entry, invitation-only private
|
||||
rooms, password entry, grant rotate/revoke, atomic room replacement and
|
||||
`ROOM_NOT_FOUND` have passed source gates. Production stable mode retained an
|
||||
exact Host authority across a controlled restart and then deleted the test
|
||||
room through the normal lifecycle.
|
||||
exact Host authority across a controlled restart. A current-production
|
||||
restart also preserved the Host-owned capture and restored Viewer media
|
||||
without refreshing either page.
|
||||
- Endpoint capacity `1/2/3`, default `2`, one active upstream, acyclicity,
|
||||
source reachability, deterministic parent order, exact candidate identity,
|
||||
transport-connected wake extension, first-decoded-frame commit, strictly newer
|
||||
@@ -59,7 +60,7 @@ may be interpreted. Git and pull requests own routine completed checks.
|
||||
|
||||
## Current Source Evidence
|
||||
|
||||
- Canonical source contains the same application tree deployed from `3037c0a`:
|
||||
- Canonical source contains the same application tree deployed from `8164102`:
|
||||
the adaptive H.264/VP8 sender decision with `contentHint = "motion"` reapplies the
|
||||
selected video profile after answer negotiation, leaves SFU representation
|
||||
construction to pinned LiveKit, keeps Dynacast/send-side BWE, disables
|
||||
|
||||
+5
-5
@@ -2,7 +2,7 @@
|
||||
|
||||
## 2026-08-18 14:45
|
||||
|
||||
状态:production 与 canonical source 使用严格 `screener-v12`,均已实现每分享代次的 H.264 sender gate 与 VP8 fallback;两者都使用 video `contentHint = "motion"` 和 audio `music`。本阶段接受但尚未实现 Host 本地 pre-share `VP8 | 自动 | H264` selector,以及 SQLite stable room authority、无期限 preferred code 和换房控制;这些不新增 codec wire、自定义 SFU layer list或应用媒体质量 controller。SFU 由 pinned LiveKit 默认 representations、Dynacast、server send-side BWE 和 disabled AdaptiveStream 拥有质量适配;screen audio 使用 64/128/192 kbps ceiling、stereo、DTX off 与 RED off。精确执行状态由 `docs/status.md` 持有。
|
||||
状态:production 与 canonical source 使用严格 `screener-v12`,均已实现每分享代次的 H.264 sender gate 与 VP8 fallback、本地 pre-share `VP8 | 自动 | H264` selector、可选 SQLite stable room authority、无期限 preferred code 和换房控制;这些不新增 codec wire、自定义 SFU layer list或应用媒体质量 controller。Video 使用 `contentHint = "motion"`,audio 使用 `music`。SFU 由 pinned LiveKit 默认 representations、Dynacast、server send-side BWE 和 disabled AdaptiveStream 拥有质量适配;screen audio 使用 64/128/192 kbps ceiling、stereo、DTX off 与 RED off。精确执行状态由 `docs/status.md` 持有。
|
||||
|
||||
## 目标与边界
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
本阶段必须形成完整的最小纵向链路:
|
||||
|
||||
- 分享者主动选择屏幕、窗口或标签页,并请求可用音频;
|
||||
- 创建四位随机数字房间;production site access 密码严格控制建房/发布和 code-only 观看,默认 room-scoped capability link 让受邀 Viewer 直接观看,房间控制状态只驻留当前进程内存;
|
||||
- 创建四位随机数字房间;production site access 密码严格控制建房/发布和 code-only 观看,默认 room-scoped capability link 让受邀 Viewer 直接观看;轻量模式把房间权威留在当前进程,可选 SQLite stable 模式只持久化房间权威 aggregate;
|
||||
- 每名观看者拥有独立的 `RTCPeerConnection`;
|
||||
- 当前 production 要求 STUN,普通 peer ICE 只发 STUN servers;source 与 production 的 Browser SFU PC 使用空 ICE-server 列表、保留 LiveKit signaling 的 UDP candidates 并由标准 ICE 选择;
|
||||
- 展示连接状态、direct/relay、RTT、实际码率、帧率和丢包等数据;
|
||||
- 超过部署配置上限的观看者被明确拒绝,不静默超载;
|
||||
- 在代码、测试和真实浏览器验证完成前,不宣称达到延迟或画质目标。
|
||||
|
||||
首个基线不实现账号数据库、通用业务数据库、房间数据库、Redis、语音聊天、Electron、原生捕获、PWA、录制、遥测平台或多地区调度。房间控制状态只驻留当前应用进程;peer-assisted/SFU candidate 只通过 ADR-0004/0005 的现有窄 owner 扩展,不引入第二套路由器或通用优化框架。
|
||||
当前不实现账号数据库、通用业务数据库、Redis、语音聊天、Electron、原生捕获、PWA、录制、遥测平台或多地区调度。可选 SQLite 只保存 ADR-0002 定义的房间权威,不保存参与者、路由或媒体;peer-assisted/SFU candidate 只通过 ADR-0004/0005 的现有窄 owner 扩展,不引入第二套路由器或通用优化框架。
|
||||
|
||||
## 技术栈决策
|
||||
|
||||
@@ -160,7 +160,7 @@ accepted 的唯一 wire 是 `screener-v12`,不做版本协商、旧 parser、
|
||||
| 1080p30 | 1920x1080、30 fps | 5 Mbps/peer |
|
||||
| 1080p60 | 1920x1080、60 fps | 8 Mbps/peer |
|
||||
|
||||
浏览器可返回更低设置,界面以 `track.getSettings()` 显示实际捕获结果。推荐区始终只有表中的三档并默认选择中档 `1080p30`;高级分辨率额外提供 `480p`(854x480)、720p、1080p 与 1440p,FPS 继续独立接受 15 至 60 整数,码率继续独立接受 2 至 12 Mbps,因此不建立第四个推荐档或 `480p` preset ID。视频 track 使用标准 `contentHint = "motion"` 表达游戏动态意图;返回的音频 track 使用 `contentHint = "music"`。默认 `1080p30` 与折叠高级区初始值采用 `degradationPreference = "maintain-resolution"`,1080p60 与 720p30 推荐档采用 `balanced`,并允许显式选择 balanced 或 fluid。“分享高级设置”不提供 codec 选择,并提供离散的 `96 kbps 普通默认 | 128 kbps 音乐 | 192 kbps 保真` 屏幕音频 sender ceiling。音频 ceiling 可在直播中串行更新。这些设置只是 ceiling 和浏览器偏好,不保证实际分辨率、帧率、码率或声道。
|
||||
浏览器可返回更低设置,界面以 `track.getSettings()` 显示实际捕获结果。推荐区始终只有表中的三档并默认选择中档 `1080p30`;高级分辨率额外提供 `480p`(854x480)、720p、1080p 与 1440p,FPS 继续独立接受 15 至 60 整数,码率继续独立接受 2 至 12 Mbps,因此不建立第四个推荐档或 `480p` preset ID。视频 track 使用标准 `contentHint = "motion"` 表达游戏动态意图;返回的音频 track 使用 `contentHint = "music"`。默认 `1080p30` 与折叠高级区初始值采用 `degradationPreference = "balanced"`,并允许显式选择清晰、均衡或流畅。高级设置在未分享时提供 `VP8 | 自动 | H264`,分享期间锁定;屏幕音频提供离散的 `64 kbps 普通 | 128 kbps 音乐默认 | 192 kbps 保真` sender ceiling。音频 ceiling 可在直播中串行更新。这些设置只是 ceiling 和浏览器偏好,不保证实际分辨率、帧率、码率或声道。
|
||||
|
||||
每次 `setParameters()` 都必须从当次 `getParameters()` 派生更新,然后读回 requested/applied `maxBitrate`、`maxFramerate`、`scaleResolutionDownBy` 和 degradation preference。浏览器负责具体降级,实际结果由 stats 观测;拒绝或浏览器改写必须进入可见状态,不能只写 `console.warn`。
|
||||
|
||||
@@ -365,7 +365,7 @@ Token-free SFU standby prewarm 保持可选且不创建 participant、publicatio
|
||||
|
||||
## 当前交付边界
|
||||
|
||||
- Production 与 canonical source 使用严格单一 `screener-v12` wire。每分享代 actual-sender gate 在证据通过时让未来 direct/relay 和 Host 单一 SFU publication 使用 H.264,否则使用 VP8。当前 production 尚无手动 selector;本阶段实现本地 pre-share `VP8 | 自动 | H264` 并保持 quality-state/wire、自定义 SFU layer list、backup publication与健康 edge codec 切换不存在。Browser SFU 使用 pinned LiveKit 默认 representations、Dynacast、server send-side BWE、disabled AdaptiveStream 与 RED off;精确执行状态由 `docs/status.md` 持有。
|
||||
- Production 与 canonical source 使用严格单一 `screener-v12` wire。每分享代 actual-sender gate 在证据通过时让未来 direct/relay 和 Host 单一 SFU publication 使用 H.264,否则使用 VP8。本地 pre-share `VP8 | 自动 | H264` selector 已实现并在分享期间锁定;quality-state/wire、自定义 SFU layer list、backup publication与健康 edge codec 切换不存在。Browser SFU 使用 pinned LiveKit 默认 representations、Dynacast、server send-side BWE、disabled AdaptiveStream 与 RED off;精确执行状态由 `docs/status.md` 持有。
|
||||
- Pause/Resume 由当前 Host session 和 `shareGeneration` 约束。Host 后台性能和 VP8 hardware acceleration 分别按受控根因证据诊断;标准 ICE/SFU 按真实异构网络验收。
|
||||
- 当前发布面只包含 Web Host、Viewer 和 browser relay。Native sender、capture helper、shared-encode executable 与两个分发包仍由各自后续决策和物理证据驱动,不属于当前 Browser release。
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ SFU 的 publication、subscription、server-resource accounting、临时 overlap
|
||||
- 端点发送容量:所有非服务器端点使用同一个服务端权威稳态 outbound media-copy capacity,由唯一部署项 `ENDPOINT_MEDIA_COPY_CAPACITY` 配置,默认 `2` 且只接受 `1`、`2` 或 `3`;不读取旧键或保留第二套 tier。peer child 或 Host 的唯一 SFU publication 各消耗一份,上游接收不消耗该预算。客户端只能声明不高于部署值的可用容量,角色、浏览器、UA、设备类型和页面可见性不产生不同上限。服务端在每次 `authenticated` 权威快照中返回最终 `endpointMediaCopyCapacity`;普通非 peer-assisted 模式也只授权稳定加入顺序中的至多 `C` 个 Host child,超额 Viewer 保持入房等待并在槽位释放后提升,信令不能绕过该集合。Browser Host 与 Viewer 严格校验该值并用它约束稳态 assignment;并行产生媒体的 candidate 必须持有唯一 `TransitionOverlapSlot`,active+pending 物理 copy 只可达到 `min(C + 1, 3)` 并在 commit/abort 后释放。`C=3` 满载时必须先收到 active bounded-gap retirement 再 prepare,绝不产生第四份 copy。SFU subscriber egress 由独立 server admission 记账。当前不兼容房间合同以单一 release 原子升级;缺失/非法 cap、旧 wire 与 executable sender都在取得room/route authority前fail closed。
|
||||
- P2P 优先:每条普通逻辑媒体边先尝试 direct/peer UDP,服务器不得默认中转可直连媒体。更多观看者优先沿满足统一端点容量的无环 peer 图分布;每名 Viewer 同时至多一个 active upstream,失败时只影响需要重选的 child。任何 source-reachable endpoint 在 effective capacity 有空位时都可作为 parent candidate;Peer-fed 与 SFU-fed endpoint 使用同一个 provisional-child transaction,并在 candidate child 解码出第一帧新画面后独立提交该 edge。Host 已满且首次需要 SFU 时,同一 controller 用有限 carrier cursor 建立唯一 publication;carrier 必须能在既有 overlap 上限内完成,不能先切断健康分支。终态归原始等待需求,publication 成功后该需求先取得 SFU 画面,剩余 direct candidate 再在后台收敛;完整事务由 ADR-0005 定义。
|
||||
- NAT 与传输边界:STUN 必须可用,所有 ordinary peer `RTCPeerConnection` 只接收 STUN ICE servers。Browser LiveKit publisher/subscriber PC 必须显式使用空 `iceServers`,保留 LiveKit signaling 交付的授权 SFU UDP candidates,并由标准 ICE 选择 nominated non-relay pair;不得把 ordinary-peer STUN、LiveKit join response 中的 STUN 或默认公共 STUN混入该 PC,也不得把某一种 candidate type 或数量写成成功条件。部署 STUN 仍供 ordinary peers 和 LiveKit server-side 公网地址发现使用。浏览器 ICE connectivity checks 是 direct UDP 可达性的权威;Screener 不合成 remote candidate、不预测端口、不分类 NAT,也不使用 TCP 探测推断 UDP 媒体可达性。所有恢复和候选授权必须绑定 authenticated room/endpoint session、share generation、base/pending route revision 与 candidate connection identity;成功即停止,失败、超时或绑定失效即撤销,direct 阶段耗尽后在同一 operation deadline 内进入 SFU/UDP,全部可用路径耗尽后明确等待或失败。已接受的完整顺序只有保持或尝试 direct/STUN peers,再复用或建立 direct-ingress Host publication/SFU subscription。Screener 不配置 TURN、ICE/TCP、media TCP 或 TLS-relayed media;当前 LiveKit 也保持 UDP-only。未来若真实严格防火墙矩阵证明需要另一种传输,必须把它作为 LiveKit 内部能力重新决策,不能增加第三种应用 route candidate。LiveKit join JWT 仅按协议进入不得记录的 WebSocket request target;HTTPS/WSS 继续独立使用 TLS/TCP。
|
||||
- 质量控制:推荐档位始终只有 720p30(3 Mbps)、1080p30(5 Mbps)、1080p60(8 Mbps)三档,默认选择中档 `1080p30`。高级设置的分辨率选项增加 `480p`(854x480),其 FPS 与码率仍由高级控件独立选择;不增加 `480p` 推荐档、preset ID 或固定的 480p FPS/码率组合。三档与高级设置初始值统一采用中档 `balanced`(均衡),`maintain-resolution`(清晰)、`maintain-framerate`(流畅)保留为显式选择。Browser Host 在每个新分享代次运行一次有界实际 sender 预检,Relay 在该代首次取得 upstream source 且尚无 child 时运行同一预检;H.264 源帧与编码帧进度通过时,未来 direct/relay offer 原生排序 H.264 后接 VP8,Host 的唯一 SFU publication 也使用 H.264;不支持、证据不足、超时或表现不达标时只使用 VP8。界面、质量状态和 wire 不提供 codec 选择,结果不持久化,也不因质量设置、换源或换父重复探测或切换已连接线路。分享期间可直接换视频档位和 64/128/192 kbps 音频 sender ceiling,音频默认选择中档 128 kbps,不重新选择来源或重建健康连接。Peer-assisted relay 与已配置的 SFU 必须接收同一个严格校验的房间级权威设置,覆盖当前和以后建立的 sender;普通 P2P 信令结构保持不变。任何设置都只是浏览器上限和偏好,具体降级由 WebRTC/LiveKit 决定;必须读回实际 sender 参数并通过 stats 观测结果、显示参数拒绝、改写和持续受限原因。Host 资源不足时由 Host 主动选择较低的现有档位。Screener 不设置自定义 SFU layer list、动态 FPS、综合评分或周期性全房间调档。
|
||||
- 质量控制:推荐档位始终只有 720p30(3 Mbps)、1080p30(5 Mbps)、1080p60(8 Mbps)三档,默认选择中档 `1080p30`。高级设置的分辨率选项增加 `480p`(854x480),其 FPS 与码率仍由高级控件独立选择;不增加 `480p` 推荐档、preset ID 或固定的 480p FPS/码率组合。三档与高级设置初始值统一采用中档 `balanced`(均衡),`maintain-resolution`(清晰)、`maintain-framerate`(流畅)保留为显式选择。Browser Host 在未分享时提供本地 `VP8 | 自动 | H264` 选择并在分享期间锁定;自动模式每个新分享代次运行一次有界实际 sender 预检,Relay 在该代首次取得 upstream source 且尚无 child 时运行同一预检。H.264 源帧与编码帧进度通过时,未来 direct/relay offer 原生排序 H.264 后接 VP8,Host 的唯一 SFU publication 也使用 H.264;不支持、证据不足、超时或表现不达标时只使用 VP8。Resolved codec 不进入质量状态或 wire、不持久化,也不因质量设置、换源或换父重复探测或切换已连接线路。分享期间可直接换视频档位和 64/128/192 kbps 音频 sender ceiling,音频默认选择中档 128 kbps,不重新选择来源或重建健康连接。Peer-assisted relay 与已配置的 SFU 必须接收同一个严格校验的房间级权威设置,覆盖当前和以后建立的 sender;普通 P2P 信令结构保持不变。任何设置都只是浏览器上限和偏好,具体降级由 WebRTC/LiveKit 决定;必须读回实际 sender 参数并通过 stats 观测结果、显示参数拒绝、改写和持续受限原因。Host 资源不足时由 Host 主动选择较低的现有档位。Screener 不设置自定义 SFU layer list、动态 FPS、综合评分或周期性全房间调档。
|
||||
- 路径隔离表示:direct/peer 继续使用每条 PeerConnection 独立的 stock WebRTC GCC,不把 Viewer 反馈合成全房目标。Browser Host 的唯一 SFU publication 不设置 `screenShareSimulcastLayers`,由锁定的 LiveKit client 默认行为拥有当前 H.264 或 VP8 source decision 对应的 screen-share representations、source replacement 与 republish;LiveKit Dynacast 和启用 send-side BWE 的 server stream allocator 负责需求聚合与每个 subscriber 的实际下行层。Screener 不实现质量评分、带宽估计、周期调档或应用媒体层 selector。所有当前 Viewer 都可能承担 peer children,因此 subscriber 保持 `adaptiveStream: false`,不得让本地元素尺寸或可见性控制 relay ingress。表示选择不改变拓扑、端点容量或路由失效权威。
|
||||
- 路由失效输入:应用不推断 parent-wide 质量,也不计算综合分数。当前 authenticated child 只在 PeerConnection `failed/closed`,或非权威暂停时现有 periodic stats 在统一 deadline 内没有新 decoded frame 时,使自己的 exact edge 失效并唤醒同一个 reconcile。decoded progress 只保存 route-keyed `lastDecodedAt`,route/connection变化或新帧重置、暂停抑制,同一 edge只报告一次,不增加轮询器。Active SFU route 暂时没有 video track、stats report 为空或 stats 读取失败时,现有采样 cadence 仍把该次作为无 decoded progress 推进 deadline;它不得停表、伪造连接指标或立即判定 edge 失效,只有 route 停用或 teardown 才停止该 cadence。该 operation 把失败的 exact direct parent 在当前 fact version 视为已尝试;foreground direct window结束后用SFU取得可用画面,剩余direct candidate只在画面后方收敛,新的外部事实才允许本轮失败tuple重新进入。Track availability、低码率、低 FPS、模糊、sender/viewer stats 与 SFU layer只用于stock WebRTC/LiveKit恢复和诊断。relay自身ingress失效时,它作为child换父并保留subtree;disconnect或effective downstream capacity降低只让direct/overflow children逐个走同一事务。
|
||||
- 断线恢复:临时网络变化先交给 WebRTC/LiveKit 的 ICE、consent、重连和流状态。Direct edge 可在 exact current parent/child sessions 内采用 framework rebuild 的新 connection ID而不改变topology。应用只在上述exact edge失效后运行一次有界reconcile;任一步成功即停止。候选耗尽时hard-invalid、confirmed-departed或overflow edge被退休并进入明确waiting,healthy bootstrap edge保留。所有异步结果受authenticated session、share generation、base/pending route revision与candidate connection identity约束,未受影响分支保持sticky。权威暂停abort未提交candidate、保留active graph、抑制stall,并在resume后重新reconcile。
|
||||
|
||||
Reference in new issue
Block a user