chore: merge main into feat/quality-evidence-alignment
This commit is contained in:
commit
9014474ca6
4 files changed
+131
-8
No files matched your search
@@ -53,6 +53,47 @@
|
||||
- 在 `status.md`、调研或 ADR 中记录昂贵验证对应的 commit、环境、结果和适用边界,PR 可以引用该记录,使后续工作能判断证据是否仍有效,而不是机械重跑。
|
||||
- 发布、安全边界、数据库迁移和部署切换仍按其风险执行必要的最终门禁;“批量验证”不是跳过会被当前变更影响的检查。
|
||||
|
||||
## 阶段验收后的有界架构收敛
|
||||
|
||||
这是一项明确延期的收官任务。只有当前主要功能基本完成、相关主线变更合并且阶段验收完成后才可启动;它不阻断或抢占当前的质量证据、自动路由 exact-room canary、native sender 或部署工作。启动时从届时最新 `main` 建立一个短期 `refactor/` 或 `chore/` 分支。当前只记录审查契约,不实施重构。
|
||||
|
||||
2026-08-19 的一次只读盘点估算约有 14,153 行产品源码和 31,094 行第一方文本,并标出以下高集中度 owner:
|
||||
|
||||
- `src/server/hybrid-media-router.ts`:约 1,605 行;
|
||||
- `src/client/pages/HostPage.tsx`:约 1,455 行;
|
||||
- `src/server/signaling.ts`:约 1,057 行;
|
||||
- `scripts/peer-assisted-benchmark.ts`:约 2,049 行。
|
||||
|
||||
这些总量、分类口径和“产品源码可能净减少 7%-14%”都只是当日待重测的审查假设,不是删除指标、承诺区间或 LOC KPI。文件长度也不单独证明职责错误。正式审查必须先重新读取 `AGENTS.md`、当前 memory/status、需求、相关研究及 [ADR-0004](adr/0004-peer-assisted-media-experiment.md)/[ADR-0005](adr/0005-automatic-hybrid-media-routing.md),重新统计届时 `main`,明确计数口径,并按消费者和测试把代码分为:
|
||||
|
||||
1. 当前生产路径必需;
|
||||
2. 自动 `direct P2P -> peer-assisted -> optional SFU` 目标必需;
|
||||
3. 有明确下一阶段消费者和退出条件的实验能力;
|
||||
4. 已被替代、重复、无消费者或仅服务一次性定位的代码。
|
||||
|
||||
任何实现开始前,先输出基于证据的候选清单、行为与迁移风险,以及按 owner 说明依据的预计净减少范围;范围可以低于 7%、为零,或证明当前不值得改。评审该输出后再决定是否实施,不能用预设比例反推删除。
|
||||
|
||||
审查优先减少状态 owner、重复路径和认知负担:先删除已证明无消费者的代码,再合并重复逻辑,只在已有独立职责和消费者时提取窄模块。重点检查:
|
||||
|
||||
- `SignalingServer` 是否能只保留认证、WebSocket 分发与薄协调职责;
|
||||
- `HybridMediaRouter` 的拓扑计划、SFU grant/lifecycle、intent drain 和广播是否形成可独立验证的自然边界;
|
||||
- `HostPage`/`ViewerPage` 的纯媒体编排与展示状态能否适度分离,而不建立新的前端架构层;
|
||||
- benchmark 的一次性探针和重复 CDP 逻辑能否收缩,同时保留可重复验收与结果可比性;
|
||||
- 测试 setup/fixtures 能否合并,同时完整保留竞态、鉴权和 host edge 上限覆盖。
|
||||
|
||||
不要为了缩短文件机械拆分,也不要引入通用框架、工厂、事件总线或更多状态机。Peer/SFU 代码不能因默认关闭就视为多余:若 canary 和 ADR 门槛支持该路线,则保留并整理;若路线被实测否决或明确替代,则删除失败路径,不长期保留无消费者的负担。
|
||||
|
||||
任何候选改动都必须保持以下行为不变:
|
||||
|
||||
- 用户无感的自动 `direct P2P -> peer-assisted -> optional SFU` 梯级;
|
||||
- 每条 P2P 边独立执行 ICE,并可使用短期凭据回退到鉴权 TURN;
|
||||
- host 下游活跃媒体边不超过两个;
|
||||
- 普通桌面或移动浏览器 Viewer 无需安装应用;
|
||||
- break-before-make、安全授权、重连、回滚和陈旧消息隔离语义;
|
||||
- 功能默认关闭,并保留 exact-room allowlist 灰度边界。
|
||||
|
||||
实现期间只运行覆盖当前改动的窄测;完整候选形成后统一运行一次 full check。除非媒体行为或证据采集逻辑改变,不重跑昂贵浏览器/网络矩阵。实现 PR 必须原位同步 status、project memory 和相关 ADR,删除失效描述,不新增过程流水账文档。
|
||||
|
||||
## 在线调研规则
|
||||
|
||||
非平凡的设计、实现和 bug 修复先读仓库,再查当前的一手资料。优先级为规范/官方文档、官方源码与维护者说明、原始论文,然后才是高质量社区复现与运行经验。安全、网络协议、浏览器能力、依赖版本和云服务行为属于易变化信息,必须按当前日期重新验证。
|
||||
|
||||
@@ -18,15 +18,17 @@ Last updated: 2026-08-19
|
||||
|
||||
- Keep desktop Chrome/Edge and the responsive Web viewer as the baseline. Validate Android Chrome and iOS Safari as leaves.
|
||||
- Use direct host P2P for one or two viewers. Keep ADR-0004 off for broad production traffic: two mobile leaves can consume both host roots. Use the exact-room allowlist only on an isolated canary until its resource, quality, recovery, TURN, and browser/mobile gates pass.
|
||||
- Standard browser relays resend remote `MediaStreamTrack` values and therefore decode and re-encode at every hop. Browser WebRTC does not guarantee one shared encoder across peer connections; measure this cost rather than hiding it.
|
||||
- Keep the browser experiment bounded. Evaluate native RTP relay, encoded-object striping, SVC, or FEC only in separate measured spikes.
|
||||
- Browser relays resend remote `MediaStreamTrack` values and re-encode at each hop; WebRTC does not guarantee a shared encoder across peer connections, so measure the cost.
|
||||
- Keep browser experiments bounded; spike native RTP relay, encoded-object striping, SVC, and FEC separately.
|
||||
- Plan a separate native-sender ADR for TeamSpeak-style shared encoding regardless of the browser relay result. One compatible encoded output may feed at most two standard WebRTC packetizers to reduce host encode work, but each edge still consumes upload bandwidth. This work is not part of the current Draft and cannot rescue another failed browser-relay gate.
|
||||
- Keep user-operated or central single-node SFU capacity optional. When configured, `main`'s #17 route controller may select it only as the final fallback; its fanout egress belongs to its operator and does not justify Redis or multi-node infrastructure. Closed PR #12's explicit whole-room SFU mode is superseded, not a current option.
|
||||
- Keep automatic routing default-off behind ADR-0005: discrete failures drive peer recovery and optional SFU fallback, host media uses break-before-make under two active edges, and a binary relay capability keeps mobile/iPad clients as leaves. Merged PR #20's token-free prewarm passes the local sub-second gate; public transport and load gates remain.
|
||||
- Local reparenting is a later candidate: start with unassigned relay admission rescue; do not block current work.
|
||||
- Prefer direct UDP, then TURN/UDP, with TURN/TCP as the required non-UDP fallback. Optional TURN/TLS uses TCP 5349 by default; TCP 443 needs a dedicated address or validated L4/SNI routing.
|
||||
- Treat video settings as ceilings. Production defaults clarity-first with bounded manual controls, but reported degradation is unclassified. Before ADR-0007 implementation, correlate same-tick capture settings and outbound deltas/identity, then add only the minimal authenticated viewer report needed for per-path `HIGH`/`FALLBACK`. Do not use UA for quality or build a composite score. Keep browser audio request/presence-only.
|
||||
- Do not add custom scene detection or dynamic-FPS control until WebRTC statistics and host resource measurements prove a material gap. Keep browser codec order until target hardware proves a more efficient common codec.
|
||||
- Keep room policy deployment-driven. Public and password-only deployments use random temporary rooms. A site password plus SQLite path enables sequential persistent rooms; stopping sharing leaves the room and viewer link available.
|
||||
- Keep room policy deployment-driven. Public/password-only deployments use random temporary rooms. A site password plus SQLite path enables sequential persistent rooms; stopping leaves the room and viewer link available.
|
||||
- Deferred architecture audit: `docs/maintenance.md`.
|
||||
|
||||
## Current Implementation
|
||||
|
||||
|
||||
@@ -164,6 +164,73 @@ central fallback and keep it only if, at equal quality and egress, latency or
|
||||
server CPU improves at least 20% over the SFU reference and draft-version churn
|
||||
is isolated behind a small adapter.
|
||||
|
||||
## Candidate 6: Bounded Capability-Aware Local Reparenting
|
||||
|
||||
This is a later topology candidate, not part of ADR-0004 or the current
|
||||
implementation milestone. Narada and Overcast demonstrate measurement-driven
|
||||
overlay improvement, but neither supplies a maintained WebRTC RTP/RTCP routing
|
||||
library. BitTorrent/WebTorrent and P2P Media Loader use chunk-pull swarms and
|
||||
playout buffers, while SplitStream requires striped multi-tree media.
|
||||
Their exploration and hysteresis ideas are useful, but none is a drop-in route
|
||||
controller for sub-second screen sharing. A mature SFU is the directly reusable
|
||||
low-latency alternative, with central egress rather than audience forwarding.
|
||||
|
||||
With host degree two and the current browser-relay degree one, two balanced
|
||||
chains already minimize maximum depth at `ceil(N/2)`. A tree for `N` viewers
|
||||
still has `N` media edges, approximately `N*B` useful upload in aggregate, and
|
||||
approximately `2B` host upload once both roots are used. Local reparenting does
|
||||
not reduce either bandwidth quantity. Reordering an already balanced healthy
|
||||
tree also cannot reduce depth; a move needs a discrete admission, path, TURN,
|
||||
relay-resource, recovery, or future native-capacity benefit.
|
||||
|
||||
The initial spike is limited to admission rescue. If a relay-capable viewer is
|
||||
unassigned because two zero-capacity roots, especially mobile leaves, occupy
|
||||
both host slots, insert that viewer above one deterministic childless root:
|
||||
|
||||
```text
|
||||
host -> new relay -> existing leaf
|
||||
host -> other root
|
||||
```
|
||||
|
||||
This admits the waiting viewer while keeping host fanout two and browser relay
|
||||
fanout one. It must pass the existing depth, codec, authorization, and recovery
|
||||
gates; otherwise the controller proceeds to the optional SFU or visible wait.
|
||||
|
||||
Eligibility is discrete: an active authenticated session, explicit relay
|
||||
capacity, compatible representation, a free downstream slot, acyclicity, and
|
||||
depth/edge budgets; a candidate already in the tree must also have healthy
|
||||
inbound media. For admission rescue, choose the eligible childless root by
|
||||
server join order; do not probe or rank alternate paths. Broader experiments
|
||||
may react to a hard media failure, a reviewed threshold-crossing event from
|
||||
correlated path evidence, or a proven native capacity change, but never a
|
||||
continuous optimizer. Do not use a weighted score, UA/device model, IP
|
||||
geography, or one party's unverified report. Keep healthy assignments sticky,
|
||||
move only one affected subtree, use separate enter and recovery thresholds plus
|
||||
a cooldown, and disable proactive moves for the share after repeated rollback.
|
||||
|
||||
Use make-before-break only when the new parent has a free downstream media slot
|
||||
and every affected endpoint remains within its limit: host at most two, current
|
||||
browser relay one, and any future native relay at most two. Admission rescue
|
||||
starts with both host slots occupied, so it is break-before-make: retire the
|
||||
chosen host-to-leaf media edge before activating host-to-new-relay media. A
|
||||
control-only `RTCPeerConnection` may prewarm ICE but cannot prove media uplink:
|
||||
WebRTC exposes `availableOutgoingBitrate` only after congestion-controlled RTP
|
||||
has used that candidate pair. Zero interruption, active standby media, and a
|
||||
hard endpoint edge limit cannot all be guaranteed at once.
|
||||
|
||||
Proceed only after the current evidence-alignment and peer canary gates pass.
|
||||
Every sampled instant must retain host/relay fanout limits; unaffected branches
|
||||
must not freeze; make-before-break must decode at every affected receiver on the
|
||||
new path before retiring the old edge, while break-before-make must do so within
|
||||
one second p95 after the break and before declaring the move successful. Stable
|
||||
reference runs must not migrate; each move must record one discrete benefit,
|
||||
avoid reversal during cooldown, and restore the prior deterministic route on
|
||||
rollback. Reject this candidate if it needs all-pairs probing, a continuous
|
||||
optimizer, temporary fanout above budget, self-reported geography or device
|
||||
quality, or cannot beat the unchanged route. Start and stop the initial spike
|
||||
at admission rescue. Later measured work owns quality-driven moves and
|
||||
healthy TURN-to-direct optimization.
|
||||
|
||||
## Automatic Route Controller Boundary
|
||||
|
||||
The product order is:
|
||||
@@ -198,6 +265,19 @@ Sources checked on 2026-08-19:
|
||||
- [SplitStream](https://www.microsoft.com/en-us/research/publication/splitstream-high-bandwidth-multicast-in-a-cooperative-environment/)
|
||||
and [Network Coding for Large Scale Content Distribution](https://www.microsoft.com/en-us/research/publication/network-coding-for-large-scale-content-distribution/)
|
||||
- research evidence, not reusable source licenses.
|
||||
- [Narada](https://www.cs.cmu.edu/~srini/papers/papers/2002-Chu-jsac/2002-Chu-jsac.pdf),
|
||||
[Overcast](https://pdos.csail.mit.edu/~jj/jannotti.com/papers/overcast-osdi00/),
|
||||
[NICE](https://conferences.sigcomm.org/sigcomm/2002/papers/appmulti.pdf), and
|
||||
[CoolStreaming/DONet](https://www.cs.sfu.ca/~jcliu/Papers/47_01.pdf) -
|
||||
original application-layer multicast and live-streaming research.
|
||||
- [BitTorrent BEP 3](https://www.bittorrent.org/beps/bep_0003.html),
|
||||
[WebTorrent](https://github.com/webtorrent/webtorrent), and
|
||||
[P2P Media Loader](https://github.com/Novage/p2p-media-loader) - mature
|
||||
chunk/segment swarms, not an RTP route implementation.
|
||||
- [WebRTC statistics](https://www.w3.org/TR/webrtc-stats/),
|
||||
[ICE, RFC 8445](https://www.rfc-editor.org/rfc/rfc8445.html), and
|
||||
[LiveKit SFU](https://docs.livekit.io/reference/internals/livekit-sfu/) -
|
||||
observable path boundaries and the centralized low-latency alternative.
|
||||
- [MOQT draft](https://datatracker.ietf.org/doc/draft-ietf-moq-transport/) and
|
||||
[moq-dev/moq](https://github.com/moq-dev/moq) - core MIT/Apache-2.0; its OBS
|
||||
plugin is separately GPL-2.0-or-later and remains study-only.
|
||||
|
||||
+5
-5
@@ -67,11 +67,11 @@ no-RTX remains research-only.
|
||||
|
||||
## Blockers And Decisions
|
||||
|
||||
Production enablement of peer assistance and automatic routing is No-Go until
|
||||
ADR-0004/0005 gates pass. Without LiveKit, two mobile leaves can occupy both
|
||||
host roots and leave later viewers without media; use only an exact-room
|
||||
allowlisted isolated canary.
|
||||
Native shared encode and multi-tree striping remain separate experiments.
|
||||
Peer assistance and automatic routing remain No-Go until ADR-0004/0005 pass.
|
||||
Without LiveKit, two mobile leaves can fill both host roots; use an isolated
|
||||
exact-room canary only.
|
||||
Native shared encode and striping remain separate experiments.
|
||||
Deferred architecture audit: `docs/maintenance.md`.
|
||||
|
||||
- Whole-system versus selected-game audio for the first release.
|
||||
- Initial deployment region and network cohort.
|
||||
|
||||
Reference in new issue
Block a user