From 32c4f270e5a700ccf9eaf477d080634a647f4da3 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Tue, 10 Nov 2026 01:13:00 -0800 Subject: [PATCH 1/3] chore(quest): claim quest/m0/nightly/windows.md Quest-Claim: 95e06d4825e3eaeb From 8f0fee87e5c522b332c8b2e134974316442e9814 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Tue, 10 Nov 2026 02:41:09 -0800 Subject: [PATCH 2/3] fix(moq-video): Backend::encode_all compiles only where a backend test calls it Windows' render-only test build has no backend that calls it, so build.warnings = deny failed platform.yml's Rust tests. Co-Authored-By: Claude Opus 5.5 --- quest/m0/nightly/README.md | 1 - quest/m0/nightly/windows.md | 31 -------------------------- rs/moq-video/src/encode/backend/mod.rs | 10 ++++++++- 3 files changed, 9 insertions(+), 33 deletions(-) delete mode 100644 quest/m0/nightly/windows.md diff --git a/quest/m0/nightly/README.md b/quest/m0/nightly/README.md index 3a6969c0cff..7e6ba134836 100644 --- a/quest/m0/nightly/README.md +++ b/quest/m0/nightly/README.md @@ -52,4 +52,3 @@ near the paired threshold (re-check if one repeats), a one-off - [Nightly's macOS platform job passes](/quest/m0/nightly/macos.md) - `moq-audio`'s tests compile on macOS again and the websocket version test's timeout is fixed if it recurs - [Nightly's WebSocket fallback benchmark connects again](/quest/m0/nightly/qmux-bench-handshake.md) - `just js qmux-bench` stops timing out on its handshake, a regression since 2026-11-07, so the Audio quality job fails only on audio results -- [Nightly's Windows platform job passes](/quest/m0/nightly/windows.md) - `moq-vaapi` is gated to Linux and Windows-only unused items are fixed, so `platform.yml`'s Windows job builds and tests cleanly diff --git a/quest/m0/nightly/windows.md b/quest/m0/nightly/windows.md deleted file mode 100644 index 4661fd79d9c..00000000000 --- a/quest/m0/nightly/windows.md +++ /dev/null @@ -1,31 +0,0 @@ -# [S] Nightly's Windows platform job passes - -## Goal - -The `Windows` job of `platform.yml` passes on `main`, both as Nightly's -`platform / Windows` and on `workflow_dispatch` runs and release PRs. Every -Windows-only warning or Linux-only crate it trips on is fixed at its cause, -not silenced for the job. - -## Plan - -Planned 2026-11-09 (maintainer, from -[moq-dev/moq#8251](https://github.com/moq-dev/moq/pull/8251)'s follow-ups, -/quest-unblock). Known causes: - -- `moq-vaapi` is not gated to Linux under `--all`, so the Windows build tries - to compile it. -- `moq-relay`'s memory integration test leaves items unused on Windows, - which `build.warnings = deny` turns into errors. -- The 2026-11-09 dispatch on `quest/m2/video-codec-receive` - ([run](https://github.com/moq-dev/moq/actions/runs/42635646987)) failed - `just rs test -p moq-video --no-default-features --features render` on a - `dead_code` warning at `rs/moq-video/src/encode/backend/mod.rs:84`. Check - whether `main` has it too. - -Reproduce each on a `workflow_dispatch` of `platform.yml` for this branch -before and after the fix. Gate platform-specific crates and items with `cfg` -where they are defined, so a later Windows-only warning shows up as one new -error rather than a pile. - -Public API: none. Wire: none. diff --git a/rs/moq-video/src/encode/backend/mod.rs b/rs/moq-video/src/encode/backend/mod.rs index f5ab121bed8..b14de0839db 100644 --- a/rs/moq-video/src/encode/backend/mod.rs +++ b/rs/moq-video/src/encode/backend/mod.rs @@ -80,7 +80,15 @@ pub(crate) trait Backend { fn flush(&mut self) -> Result<(), Error>; /// Submit one frame and collect everything it readied. - #[cfg(test)] + #[cfg(all( + test, + any( + feature = "openh264", + apple, + all(target_os = "android", feature = "mediacodec"), + all(target_os = "linux", feature = "vaapi"), + ) + ))] fn encode_all(&mut self, frame: &Frame, cut: bool) -> Result, Error> { self.encode(frame, cut)?; self.receive_all() From 22b2ba4ed52ab66e32f771a4fd887be47b3ecb10 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Tue, 10 Nov 2026 08:54:20 -0800 Subject: [PATCH 3/3] Restore quest files the stale base merge dropped --- quest/README.md | 9 ++++ quest/m0/README.md | 13 ++++++ quest/m0/ci/README.md | 8 ++++ quest/m0/nightly/README.md | 4 ++ quest/m1/README.md | 22 +++++++++ quest/m1/audio-jitter-target/README.md | 11 +++++ quest/m1/explicit-state/README.md | 4 ++ quest/m1/stream-credit/README.md | 4 ++ quest/m2/README.md | 13 ++++++ quest/m2/api-shape/README.md | 4 ++ quest/m2/cluster-routing/README.md | 5 ++ quest/m2/cluster-routing/routes/README.md | 8 ++++ quest/m2/probe/README.md | 4 ++ quest/m2/subscribe-ranges/README.md | 6 +++ quest/m2/time-addressing/README.md | 11 +++++ quest/m2/unbounded-groups/README.md | 6 +++ quest/m3/c/README.md | 2 + quest/m3/intra-refresh/README.md | 9 ++++ quest/m3/mesh/README.md | 9 ++++ quest/m3/obs-moq-video/README.md | 7 +++ quest/m3/obs-studio/README.md | 4 ++ quest/m3/one-port/README.md | 5 ++ quest/m3/qos/README.md | 6 +++ quest/m3/quic-realtime/README.md | 4 ++ quest/m3/release/README.md | 23 ++++++++++ quest/m3/stats/README.md | 9 ++++ quest/m3/stream/README.md | 6 +++ quest/m3/vendor-sync/README.md | 11 +++++ quest/m3/video-quality/README.md | 8 ++++ quest/m3/webrtc/README.md | 11 +++++ quest/m3/wire-stats/README.md | 7 +++ quest/m4/kio-channel-contention/README.md | 5 ++ quest/m4/p2p/README.md | 9 ++++ quest/m4/perf/README.md | 12 +++++ quest/m4/stream-transports/README.md | 7 +++ quest/m5/README.md | 56 +++++++++++++++++++++++ quest/m5/e2ee/README.md | 19 ++++++++ quest/m5/net-wrap/README.md | 9 ++++ 38 files changed, 370 insertions(+) diff --git a/quest/README.md b/quest/README.md index 19f5ad3323b..44d4a25ff1e 100644 --- a/quest/README.md +++ b/quest/README.md @@ -51,3 +51,12 @@ that fails intermittently in CI, Nightly, or the merge queue becomes a child of m0's [test flakes](/quest/m0/test-flakes-2/README.md) epic. Skills that plan follow-ups plan a reported flake there without asking whether or where; the planning PR's review is the check. + +## Required + +- [m0: immediate priorities](/quest/m0/README.md) - urgent work of any kind, and maintenance of the current release +- [m1: additive work](/quest/m1/README.md) - this cycle's improvements and fixes that need no breaking release; each ships with the next cut or as a backported patch +- [m2: the next breaking release](/quest/m2/README.md) - every change that would need a breaking release if it landed after the cut, plus the cut gate; the cut waits on m2 alone +- [m3: later work, higher priority](/quest/m3/README.md) - byte streams and mesh libraries first, release execution, what a named consumer needs, and bug fixes in shipped code +- [m4: later work, lower priority](/quest/m4/README.md) - tests, tooling, benchmarks, optimizations, and features nobody waits on yet +- [m5: deferred](/quest/m5/README.md) - gated on the outside world (hardware, a partner, a consumer, a provider's offer, or an upstream release), or speculative with no named consumer diff --git a/quest/m0/README.md b/quest/m0/README.md index abcc4ad29c9..4a7f0aecf61 100644 --- a/quest/m0/README.md +++ b/quest/m0/README.md @@ -23,3 +23,16 @@ Routing: Wildcard landed in #4403, so a service claims the prefix it could serve instead of enumerating broadcasts. Serving the relay's ingested-only view (`origin::Consumer::local()`) to localhost workers belongs to moq.pro's edge, which embeds moq-relay; it moved there on 2026-09-28. + +## Required + +- [The C bindings accept MoqInstance again](/quest/m0/check-c-moqinstance.md) - `check c` passes on main once the C generator stops refusing `MoqInstance`'s exported `Debug` +- [Nightly passes on main](/quest/m0/nightly/README.md) - the scheduled Nightly passes end to end, so red means a new break +- [Interop and Video pass on main](/quest/m0/interop-green/README.md) - the scheduled Interop and Video workflows pass, so red means a new break +- [@moq/clock's Instant has no throwing Duration arithmetic, mirroring kio](/quest/m0/peer-arithmetic.md) - JS `Instant` drops `add`/`sub` for checked and saturating forms, so each call site states what overflow means, as kio's do +- [Publish the release line's drain() wrappers](/quest/m0/ffi-shutdown-backport.md) - Dart `moq` 0.1.1 reaches pub.dev from `release` +- [CI cost and latency](/quest/m0/ci/README.md) - cloud CI runs only in GitHub's merge queue, one tested entry at a time, expensive checks run nightly and gate `release`, caches move to R2, and runners are chosen last +- [More tests under load](/quest/m0/test-flakes-2/README.md) - load-only and queue failures, one quest per flake, fixed at the cause, since each one drops a queued PR +- [just check passes on macOS](/quest/m0/macos-check.md) - the version test, the doc re-export link test, and the carla bridge docs pass on a macOS host +- [Agent build output can't fill the desktop's disk](/quest/m0/agent-disk-budget.md) - finished agent checkouts reclaim their mbx targets automatically, so parallel agent builds stop filling the root disk +- [MoQ builds against rind 0.4 and its corrected adapters](/quest/m0/rind-adapters.md) - the calls rind 0.4 and its adapter patch releases change, adapted the day they publish diff --git a/quest/m0/ci/README.md b/quest/m0/ci/README.md index bab2beb5828..ced41a58993 100644 --- a/quest/m0/ci/README.md +++ b/quest/m0/ci/README.md @@ -173,3 +173,11 @@ feature was considered and not planned: the churn outweighs the build saving. Measure each change against a current baseline and record the result in its PR. The historical samples locate candidates; they are not controlled benchmarks. + +## Required + +- [Read-only pull-request CI](/quest/m0/ci/read-only-secrets.md) - write secrets and publisher identities reach only protected branches and tags, never a pushed branch +- [Verify the R2 Rust cache](/quest/m0/ci/mbx-r2-verify.md) - confirm the hosted Nightly jobs reuse the previous Nightly, then measure restore time and expiry +- [Release tags push to nix.moq.dev, and Cachix stops taking writes](/quest/m0/ci/cachix-retire.md) - backport `release-nix.yml` and its Just module to `release`, drop `cachix.yml`, prove a tag substitutes from nix.moq.dev, then revoke the Cachix token (the cache stays for old tags) +- [Measure the Linux cache effect of native media exclusions](/quest/m0/ci/hakari-followups.md) - scheduled Linux jobs measure cache reuse after unrelated tests stop compiling PipeWire and libclang +- [Only the release cut edits MIGRATE.md](/quest/m0/ci/migrate-guard.md) - `just check` fails any other PR that edits one, so breaking PRs stop conflicting on it in the queue diff --git a/quest/m0/nightly/README.md b/quest/m0/nightly/README.md index 6da7bd3e02a..a7b30bfa623 100644 --- a/quest/m0/nightly/README.md +++ b/quest/m0/nightly/README.md @@ -47,3 +47,7 @@ more children for the causes nothing owned. Dropped: one-night bench moves near the paired threshold (re-check if one repeats), a one-off `remote error: 52` in the browser bench smoke, and failures main or [moq-dev/moq#8290](https://github.com/moq-dev/moq/pull/8290) already fixes. + +## Required + +- [Nightly's macOS platform job passes](/quest/m0/nightly/macos.md) - `moq-audio`'s tests compile on macOS again and the websocket version test's timeout is fixed if it recurs diff --git a/quest/m1/README.md b/quest/m1/README.md index 15bdd7466a0..f578c647594 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -29,6 +29,28 @@ breaking epics and quests stay in m1 for now and are listed in m2's stream-credit. The [re-cut follow-up](/quest/m2/recut-held.md) moves what remains of them once their claims merge. +## Required + +- [Drop set](/quest/m1/drop-set.md) - each cursor's disposition record is billed to the cache pool, as the track's drop runs are, so fragmenting drops costs what the pool holds; eviction folds final runs or ends the cursor with `TooFarBehind` +- [Routing guide](/quest/m1/routing-guide.md) - concepts and practical outbound federation setup +- [A reader on a failed copy continues on the held re-offer](/quest/m1/copy-recover.md) - a live reader keeps a group whose copy fails by continuing on the same track's re-offer at the same frame +- [Group errors are cached by kind](/quest/m1/group-error-cache.md) - permanent group errors bind every reader, retryable ones are kept only for a bounded time, and a live SUBSCRIBE_DROP or FETCH answered `Old` no longer caches it for good +- [The overcommitted receive-window cells run again](/quest/m1/receive-windows-evicted.md) - `benchmark_receive_windows` measures its 256-stream and 4 MiB-frame cells again, reporting delivered frames and evictions instead of stalling +- [Stream credit by priority](/quest/m1/stream-credit/README.md) - every stream opens through one priority entry point, and a higher-priority group takes over or resets a lower one when credit runs out +- [Audio jitter target](/quest/m1/audio-jitter-target/README.md) - the playout target is default in both languages; audio that slows down and catches up around it in every player, graded in that direction, and a native trace replay remain +- [Buffered playback subscribes in ascending order](/quest/m1/buffered-ascending.md) - a buffered `` asks for the oldest group first, so a voice reply's opening arrives first, and audio's head hold shrinks to the floor +- [Lifecycles are explicit state](/quest/m1/explicit-state/README.md) - every lifecycle the 2026-11-07 audit found implicit is one enum or union, fixing the bugs in the 11 lifecycles it redesigns, with review and agent rules against new ones +- [Track drop runs are forgotten below the floor](/quest/m1/drop-runs-prune.md) - a track's dropped-group record stays proportional to its window in Rust and JS +- [A padded TS export sheds when its sink falls behind](/quest/m1/ts-padded-shed.md) - a `--mux-rate` export skips stale slots with a flagged PCR jump instead of back-filling them or blaming the source +- [A resumed QUIC client gives up on its own idle timer](/quest/m1/quic-resume-idle.md) - a client stopped past its idle timeout closes within about one timeout of resuming, without waiting on a stateless reset +- [A reused moq-transport alias delivers a group that beats its SUBSCRIBE_OK](/quest/m1/ietf-alias-reuse.md) - a new SUBSCRIBE clears its track's alias tombstone, so moqxr's alias-0 catalog refetch no longer hangs +- [Unused crates, scripts, and files are deleted](/quest/m1/unused-code.md) - moq-room, the moq-native tombstone, demo/throttle, sh/dart/publish.sh, demo/web's Solid deps, and unpublished packages' release notes go +- [The recurring audits are fewer and carry plans, not results](/quest/m1/audit-merge.md) - m3's 13 audits become about five, each a Goal plus a short check-first list +- [The CARLA bridge builds outside the root workspace](/quest/m1/carla-workspace.md) - workspace builds stop compiling the demo bridge +- [.github/ffi.md holds rules, not evidence](/quest/m1/ffi-doc-trim.md) - the FFI release doc drops one-off measurements for links to their PRs +- [Draft publishing keeps the upload and drops changelog rewriting](/quest/m1/drafts-publish-trim.md) - `sh/drafts/publish.sh` and its test shrink to the datatracker upload +- [rs/AGENTS.md's time-test rule matches the tree](/quest/m1/test-time-rule.md) - the rule names `#[kio::test]`, which about 4,900 tests use, and is stated once + ## Related - [A busy js/net serve yields](https://github.com/moq-dev/moq/pull/5289) - js/net's serve loop leaves the browser its event loop under a fast publisher, if it does not already diff --git a/quest/m1/audio-jitter-target/README.md b/quest/m1/audio-jitter-target/README.md index 8544b31d542..939e8b295e1 100644 --- a/quest/m1/audio-jitter-target/README.md +++ b/quest/m1/audio-jitter-target/README.md @@ -87,6 +87,17 @@ the native decode path too, asserting the same target series the browser's `playout.test.ts` does. The audio quality harness's `pulse` rows already grade native playback against its budgets. +## Required + +- [Grading](/quest/m1/audio-jitter-target/grading.md) - the audio harness grades steady-state lag, dropped audio, and recovery from a stall, with no gate fixed at zero underruns or zero lag +- [Stretch model](/quest/m1/audio-jitter-target/stretch.md) - every player slows down when its buffer runs low and speeds up once it refills, by one rule and one set of vectors, buffered mode included +- [The `stretch` setting](/quest/m1/audio-jitter-target/stretch-setting.md) - a player sets how far audio may trail before it skips, and zero turns the stretch off +- [Calibrate](/quest/m1/audio-jitter-target/calibrate.md) - every browser and native ceiling re-measured from seven Nightlies with the model +- [Capped budgets](/quest/m1/audio-jitter-target/capped-budgets.md) - the AAC browser budgets are re-measured from nightlies after the TS importer groups each PES +- [Native A/V lag](/quest/m1/audio-jitter-target/native-av-lag.md) - `moq play --metrics` reports how far audio trails its presentation clock, so native rows grade `av_lag_ms` +- [Chromium Opus stalled share](/quest/m1/audio-jitter-target/opus-stalled-share.md) - the Chromium Opus browser rows' stalled-share ceiling is measured with the stretch, and passes +- [Native backpressure](/quest/m1/audio-jitter-target/native-backpressure.md) - native playback decodes audio only when the ring has room, holding the rest of the target encoded as the browser does + ## Closes - [#2812](https://github.com/moq-dev/moq/issues/2812) - the iOS stutter report the same estimator fixes diff --git a/quest/m1/explicit-state/README.md b/quest/m1/explicit-state/README.md index c92250086c4..c6882297806 100644 --- a/quest/m1/explicit-state/README.md +++ b/quest/m1/explicit-state/README.md @@ -67,6 +67,10 @@ everything" branch). It belongs to [Delete the old start bookkeeping](/quest/m2/subscribe-ranges/start-bookkeeping.md), which collapses that state and waits on [Drop set](/quest/m1/drop-set.md). +## Required + +- [moq-net phase data](/quest/m1/explicit-state/net-phases.md) - moq-net's session and subscription state machines keep each phase's data in its variant + ## Related - [Delete the old start bookkeeping](/quest/m2/subscribe-ranges/start-bookkeeping.md) - owns the lite `TrackRun` start state and its forgotten-drops bug diff --git a/quest/m1/stream-credit/README.md b/quest/m1/stream-credit/README.md index f0fbc1d3bb3..3f4b7c29445 100644 --- a/quest/m1/stream-credit/README.md +++ b/quest/m1/stream-credit/README.md @@ -46,3 +46,7 @@ which JS cannot raise; Chrome stalled at 103, Firefox at 100): This epic owns the end-to-end test: a browser reader and a Rust relay over WebTransport, 300 live tracks of mixed priority, the highest-priority ones receiving every group, and nothing hanging. + +## Required + +- [Takeover](/quest/m1/stream-credit/takeover.md) - on lite-07 a higher-priority group takes over an acknowledged stream, and a group that lost its stream resumes diff --git a/quest/m2/README.md b/quest/m2/README.md index caea8e88308..763c3a74b6e 100644 --- a/quest/m2/README.md +++ b/quest/m2/README.md @@ -192,6 +192,19 @@ quests that require them. ## Required - [Drop set](/quest/m1/drop-set.md) - each cursor's disposition record is billed to the cache pool, as the track's drop runs are, so fragmenting drops costs what the pool holds; eviction folds final runs or ends the cursor with `TooFarBehind` (held in m1 by an open claim) +- [Subscribe ranges](/quest/m2/subscribe-ranges/README.md) - a lite-07 SUBSCRIBE asks for past and live ranges with absolute or relative ends, in either order, and replaces FETCH for multi-group reads (single-group FETCH stays); merged ranges never starve a subscriber; relays fill misses by range, including over moq-transport +- [Address groups by timestamp](/quest/m2/time-addressing/README.md) - group start timestamps replace sequence numbers in the moq-net API and lite-07 wire, while old subscribers, old publishers, and published JS clients keep working +- [Cluster routing](/quest/m2/cluster-routing/README.md) - prove shared routing contracts, implement per-origin routes, and connect outbound local clusters +- [Promote the routes epic out of cluster routing](/quest/m2/promote-cluster-routes.md) - no epic holds another, once the open PRs under it land +- [A group a subscriber gives up on is always reported](/quest/m2/group-drops.md) - the wire names every abandoned group and the drop signal is public, so readers count losses instead of stalling - [Stream credit by priority](/quest/m1/stream-credit/README.md) - every stream opens through one priority entry point, and a higher-priority group takes over or resets a lower one when credit runs out (held in m1 by an open claim) - [Prove cache-aware routing](/quest/m2/cache-routing-proof.md) - warm routes and the eligibility rule hold in route-layer sweeps, and the warm message's wire placement is chosen before the lite-07 cut - [Route latency](/quest/m2/route-latency.md) - the maintainer decides whether a lite-07 ROUTE carries an informational latency sum, and it lands before the cut if so +- [Finalize moq-lite-07](/quest/m2/lite07-finalize.md) - when the maintainer cuts it, lite-07 negotiates as `moq-lite-07` and the next release ships it +- [Unbounded groups](/quest/m2/unbounded-groups/README.md) - groups and frames lose their size caps; a group keeps a 32 MB tail, and readers behind it replay through paced flights or refresh +- [Small API fixes before the cut](/quest/m2/api-shape/README.md) - one path and one spelling per item, names by role, and no dead or wrong-role public surface across net, transport, media, native, apps, JS, and bindings +- [Finishing a media producer returns a Finished handle](/quest/m2/finished-handle.md) - `finish(self)` consumes the media crates' producers, as it does moq-net's, so appending after finish doesn't compile +- [Probe](/quest/m2/probe/README.md) - a session probes up to the bitrate it wants to send or receive, so a stopped simulcast rendition resumes and a viewer up-switches; browser padding is parked in m3 (held in m2 by open claims; moves to m3) +- [Finish the milestone re-cut](/quest/m2/recut-held.md) - claim-held epics move to the milestone their kind and priority give them once their claims merge +- [moq-transport is a compatibility layer again](/quest/m2/ietf-scope/README.md) - our extensions, JS FETCH serving, and track listing leave moq-transport; live media and joining FETCH stay +- [MoQ Boy is a demo, not a published package](/quest/m2/boy-unpublish.md) - `moq-boy` and `@moq/boy` stop publishing, and `@moq/signals/solid` goes with them diff --git a/quest/m2/api-shape/README.md b/quest/m2/api-shape/README.md index 969834492f3..b754f23006d 100644 --- a/quest/m2/api-shape/README.md +++ b/quest/m2/api-shape/README.md @@ -72,3 +72,7 @@ search misses or which are not items: `just rs macos-test` enables, and its WASI arm (`udp/wasi.rs`), which no target builds. Update [cmsg length on send](/quest/m3/cmsg-len-send.md), which names the feature. + +## Required + +- [A peer's closed session reads as Closed in the bindings](/quest/m2/api-shape/session-closed.md) - a remote SESSION_CLOSED maps to `MoqError::Closed`, as a local close does diff --git a/quest/m2/cluster-routing/README.md b/quest/m2/cluster-routing/README.md index d6e3fb3bd68..bcccbbd027f 100644 --- a/quest/m2/cluster-routing/README.md +++ b/quest/m2/cluster-routing/README.md @@ -129,6 +129,11 @@ Each implementation updates the docs it makes stale. The separate [routing guide](/quest/m1/routing-guide.md) explains the combined design and setup after the capabilities land. +## Required + +- [Outbound federation](/quest/m2/cluster-routing/federation.md) - an outbound-only local relay exchanges authorized broadcasts with the CDN and survives partition/healing +- [Routes and announces](/quest/m2/cluster-routing/routes/README.md) - implement the proven route layer with Rust/JS parity and tiered-cluster acceptance + ## Related - [P2P](/quest/m4/p2p/README.md) - application-selected peer sessions feed the shared routing model diff --git a/quest/m2/cluster-routing/routes/README.md b/quest/m2/cluster-routing/routes/README.md index 100d1197c9a..2b9262cd8a6 100644 --- a/quest/m2/cluster-routing/routes/README.md +++ b/quest/m2/cluster-routing/routes/README.md @@ -537,6 +537,14 @@ benchmarks. subscriptions through the radio mesh and the split refuses, and after a partition each island reaches the other through its uplink. +## Required + +- [js/net route layer](/quest/m2/cluster-routing/routes/js.md) - `js/net` encodes, decodes, and resolves the route layer +- [Route layer acceptance](/quest/m2/cluster-routing/routes/acceptance.md) - forwarding fixtures ported and the model deleted, incident fixtures, end-to-end checks, and benchmarks +- [Firefox tabs prove their route key](/quest/m2/cluster-routing/routes/browser-proof.md) - a current Firefox tab opens a lite-07 session with a route-key proof the relay verifies, once neqo's exporter follows the draft +- [Playwright bundles Chromium's spec exporter](/quest/m2/cluster-routing/routes/playwright-pin.md) - the toolchain's Playwright bundles Chromium 158+, so the route key lane proves the Chromium tab +- [The route node behaves the same whoever creates it](/quest/m2/cluster-routing/routes/node-creation-order.md) - creating an origin's lite-07 route node from SETUP instead of the route layer changes nothing observable + ## Related - [Route wakes](/quest/m4/route-wakes.md) - index work follows the settled source-selection model diff --git a/quest/m2/probe/README.md b/quest/m2/probe/README.md index e4d84843236..535612b10f0 100644 --- a/quest/m2/probe/README.md +++ b/quest/m2/probe/README.md @@ -97,6 +97,10 @@ This README's own work, once the children land: `doc/lib` pages rather than adding a page, unless the material outgrows them. Children keep their own API docs and drafts current inline. +## Required + +- [Browser send estimate](/quest/m2/probe/browser-send-estimate.md) - browser publishers adapt to `getStats()`'s send estimate once Chrome and Safari report one + ## Related - [Realtime uplink congestion control](/quest/m3/quic-realtime/README.md) - a delay-based alternative to BBR3 on native uplinks; it must implement native probing to ship (decided 2026-10-25) diff --git a/quest/m2/subscribe-ranges/README.md b/quest/m2/subscribe-ranges/README.md index 63e756422e2..337688b3b8c 100644 --- a/quest/m2/subscribe-ranges/README.md +++ b/quest/m2/subscribe-ranges/README.md @@ -100,6 +100,12 @@ This line owns the end-to-end test: a relay with a sparse cache answers a wide past range plus live in both orders, over lite-07 and moq-transport, with every sequence delivered or dropped. +## Required + +- [JS head fills and time lookups](/quest/m2/subscribe-ranges/js-fills.md) - JS readers fill a cached group's missing head before handing it out, and look a time start up through `Fill.time` +- [Lite-07 FETCH is single-group only](/quest/m2/subscribe-ranges/lite07-fetch.md) - lite-07 FETCH reads one group or a slice of one, and SUBSCRIBE ranges of whole groups, in Rust, JS, and the draft, with JS multi-group fills moving onto the subscription +- [Delete the old start bookkeeping](/quest/m2/subscribe-ranges/start-bookkeeping.md) - what each lite cursor is owed and dropped lives in the model, and `TrackRun` only translates it per version + ## Related - [Rust groups by start](/quest/m2/time-addressing/model.md) - the cut reworks `Absolute(group)` ends and sequence-range drops onto times diff --git a/quest/m2/time-addressing/README.md b/quest/m2/time-addressing/README.md index 266177c7e0e..a3bc0b72e75 100644 --- a/quest/m2/time-addressing/README.md +++ b/quest/m2/time-addressing/README.md @@ -8,3 +8,14 @@ or starts from a time, nothing maps between group numbers and time, and no producer has to remember group numbers. Old subscribers, old publishers, and published JS clients keep working. VOD, FETCH, and archives need no backwards compatibility. + +## Required + +- [Rust groups by start](/quest/m2/time-addressing/model.md) - the moq-net model and API address groups by start, and legacy wires carry the start ticks as the group ID +- [Lite-07 by start](/quest/m2/time-addressing/lite07.md) - lite-07 carries starts, previous-start links, GROUP_END, and time bounds instead of sequence numbers +- [moq-transport IDs verbatim](/quest/m2/time-addressing/ietf.md) - group IDs pass through as keys, Prior Group ID Gap signals drops best-effort, END_OF_GROUP marks a whole group, and our Timestamp property goes +- [@moq/net by start](/quest/m2/time-addressing/js.md) - JS matches Rust's model, wire, and legacy mapping +- [Consumers by start](/quest/m2/time-addressing/consumers.md) - hang drops duration and discontinuity markers, and every consumer that numbered groups uses starts +- [Bindings by start](/quest/m2/time-addressing/bindings.md) - moq-ffi, moq-c, and every binding expose starts, with migration docs +- [E2EE nonce](/quest/m2/time-addressing/e2ee.md) - the nonce binds the start instead of the sequence +- [Guide](/quest/m2/time-addressing/guide.md) - a page explaining seek by time, group ends, restarts, strictly increasing starts, and how legacy peers see group IDs diff --git a/quest/m2/unbounded-groups/README.md b/quest/m2/unbounded-groups/README.md index 19ad9e2c424..db7516ba140 100644 --- a/quest/m2/unbounded-groups/README.md +++ b/quest/m2/unbounded-groups/README.md @@ -177,3 +177,9 @@ owns the rest: a long compressed group through a small cache pool with a plain reader on a legacy wire, which [moq-dev/moq#6993](https://github.com/moq-dev/moq/pull/6993) covered only at the model layer (maintainer, 2026-10-30). + +## Required + +- [Byte holes](/quest/m2/unbounded-groups/byte-holes.md) - segments inside a frame shed like front frames and flights start at `(frame, byte)` on the current lite wip; the frame cap goes +- [JS byte holes](/quest/m2/unbounded-groups/js-byte-holes.md) - `@moq/net` mirrors the byte-offset wire and continues a frame cut off mid-way +- [Compressed frames have no size cap and inflate as a bounded stream](/quest/m2/unbounded-groups/compressed-stream.md) - A compressed frame of any size publishes and is received in Rust and `@moq/net`, like a plain one diff --git a/quest/m3/c/README.md b/quest/m3/c/README.md index 407a8d81512..d9e9e8e0ea1 100644 --- a/quest/m3/c/README.md +++ b/quest/m3/c/README.md @@ -56,3 +56,5 @@ publication; [old-crate retirement](/quest/m3/release/c-retire.md) follows. ## Required - [Switch to rust2's exporter](/quest/m3/ffi-exporter.md) - the C ABI comes from rust2's exporter instead of a UniFFI generator +- [C consumers](/quest/m3/c/consumers.md) - the C interop client and `doc/lib/c` samples move onto the generated API +- [Async failure contract](/quest/m3/c/async-failure-contract.md) - every generated async call returns a task and calls back exactly once, cancelled when its task was freed first diff --git a/quest/m3/intra-refresh/README.md b/quest/m3/intra-refresh/README.md index ca268987a97..c84d21e13ac 100644 --- a/quest/m3/intra-refresh/README.md +++ b/quest/m3/intra-refresh/README.md @@ -46,3 +46,12 @@ make these presentation guarantees true even when sweep lengths change. a true IDR needs none. - H.264 and H.265 only. AV1 and VP9 have no standard gradual refresh signal. WebCodecs has no intra-refresh option, so js/publish is consumer-only. + +## Required + +- [Dual decoder](/quest/m3/intra-refresh/dual-decoder.md) - js/watch's two decoders open on an H.264 recovery point in Firefox and Safari, as they now do in Chromium +- [Plan: recovery boundaries](/quest/m3/intra-refresh/recovery-boundary.md) - settle how a catalog `warmup` duration stays safe for a later, longer sweep +- [Consumer warmup](/quest/m3/intra-refresh/consumer-warmup.md) - the transcoder decodes the groups covering `warmup` as history before each group, except at a true IDR +- [H.264 import](/quest/m3/intra-refresh/h264-import.md) - the splitter keeps `recovery_frame_cnt` and import publishes `warmup` from it +- [H.265 import](/quest/m3/intra-refresh/h265-import.md) - the splitter reads the recovery-point SEI so an HEVC intra-refresh stream forms groups and publishes `warmup` +- [Export sync flags](/quest/m3/intra-refresh/export-sync-flags.md) - fmp4, MKV, and HLS stop advertising a refresh group start as a sync sample diff --git a/quest/m3/mesh/README.md b/quest/m3/mesh/README.md index 3203a95e21a..581c4a612fa 100644 --- a/quest/m3/mesh/README.md +++ b/quest/m3/mesh/README.md @@ -105,6 +105,15 @@ the third, and survives a relay restart. - [Outbound federation](/quest/m2/cluster-routing/federation.md) - a local relay dials its relays and prefers LAN peers - [Byte streams](/quest/m3/stream/README.md) - lossless TCP-level streams over MoQ +- [Endpoint API](/quest/m3/mesh/endpoint.md) - an iroh-shaped `Endpoint` that connects to an endpoint ID and service and accepts byte streams +- [Mesh relay node](/quest/m3/mesh/node.md) - a relay node enrolls into a mesh, dials its relays, and admits only enrolled LAN peers +- [Mesh enrollment is bounded and revocation takes effect](/quest/m3/mesh/device-bounds.md) - a reusable key enrolls at most its own use budget and a revoked device loses access within a bounded time +- [Certificate credentials](/quest/m3/mesh/cert-credentials.md) - a certificate chain and a proof signature stand in for a JWT, checked against a trust store the application swaps live +- [Address hints](/quest/m3/mesh/addr.md) - nodes publish their addresses on mesh tracks and dial each other directly where mDNS cannot find them +- [Sparse overlay](/quest/m3/mesh/overlay.md) - each node keeps about log N deterministic direct links, forwards for the rest, and falls back to relays across a partition +- [JS mesh enrollment client](/quest/m3/mesh/js-enroll.md) - `@moq/auth` enrolls and refreshes from JS like `moq_auth::mesh::Client` +- [Status track](/quest/m3/mesh/status.md) - a signed `.status` track per node with its links and per-link RTTs +- [Mesh library guide](/quest/m3/mesh/guide.md) - the doc.moq.dev page for the libraries, the contract, and porting from iroh ## Related diff --git a/quest/m3/obs-moq-video/README.md b/quest/m3/obs-moq-video/README.md index f3e64f00b06..d9ebfec9b2e 100644 --- a/quest/m3/obs-moq-video/README.md +++ b/quest/m3/obs-moq-video/README.md @@ -18,6 +18,13 @@ The quests separate portable decoding, audio, and publishing so each can land an Decided in the 2026-09-30 audit: the Windows and Linux GPU decode paths and the macOS and Windows GPU encoder inputs moved to m2 (listed under Related), because each needs physical-hardware proof, and Linux GPU input is already m2/m3. +## Required + +- [Video source replacement](/quest/m3/obs-moq-video/source.md) - remove the FFmpeg video decode and attempt macOS GPU delivery immediately, with a working CPU fallback on other platforms +- [Linux bundle](/quest/m3/obs-moq-video/linux-bundle.md) - attach a portable Linux x86_64 tarball to every obs-moq release once FFmpeg is gone +- [Video publishing](/quest/m3/obs-moq-video/adapter.md) - back an internal OBS video encoder with moq-video and expose the combined opt-in mode +- [VP8/VP9 in OBS](/quest/m3/obs-moq-video/vpx-obs.md) - play VP8 and VP9 through moq-video's libvpx backend on every OBS platform + ## Related - [Video hardware validation](/quest/m5/video-hardware.md) - physical hardware evidence is required for each claimed GPU path diff --git a/quest/m3/obs-studio/README.md b/quest/m3/obs-studio/README.md index 2d503ee65f6..ed00b59b446 100644 --- a/quest/m3/obs-studio/README.md +++ b/quest/m3/obs-studio/README.md @@ -26,6 +26,10 @@ Open, for when the port starts: - What stays in the plugin: the MoQ Source and the dock may remain a plugin even once the output is native. +## Required + +- [obs-studio maintainers agree](/quest/m3/obs-studio/maintainers.md) - condition: agreement in principle to a native MoQ output and service + ## Related - [First C++ package release](/quest/m3/release/cpp-release.md) - the published C++ package the port would build on diff --git a/quest/m3/one-port/README.md b/quest/m3/one-port/README.md index e229b202850..2dcd558d210 100644 --- a/quest/m3/one-port/README.md +++ b/quest/m3/one-port/README.md @@ -93,6 +93,11 @@ dropped and counted. Decided 2026-10-13: the responder binds its own port ([relay STUN](/doc/bin/relay/config.md#stun)), so the shared port never answers public Binding requests. +## Required + +- [WebRTC on the shared socket](/quest/m3/one-port/rtc-feed.md) - `moq-webrtc` serves WHIP and WHEP media from the WebRTC hook and pins ICE tuples +- [SRT on the shared socket](/quest/m3/one-port/srt-demux.md) - moq-srt drives `srt-protocol` on demuxed packets and the flow table pins its 4-tuples + ## Related - [One port on the io_uring workers](/quest/m3/uring-demux.md) - the io_uring workers host the UDP demux diff --git a/quest/m3/qos/README.md b/quest/m3/qos/README.md index 87688438394..950e89feae1 100644 --- a/quest/m3/qos/README.md +++ b/quest/m3/qos/README.md @@ -55,6 +55,12 @@ crate. Client stats left the line (2026-09-29) when media stats moved out of moq-stats onto hang tracks, which are additive on `main`. +## Required + +- [Viewer lag histogram](/quest/m3/qos/lag-histogram.md) - the egress `lag` + histogram and `dropped` counters land on the stats totals and prefix + tracks + ## Related - [Media stats](/quest/m3/stats/README.md) - publishers and viewers report diff --git a/quest/m3/quic-realtime/README.md b/quest/m3/quic-realtime/README.md index cfbc3a12669..4ff3836d349 100644 --- a/quest/m3/quic-realtime/README.md +++ b/quest/m3/quic-realtime/README.md @@ -176,6 +176,10 @@ the upstream encoder, so a GStreamer pipeline at a fixed bitrate still queues when capacity drops; [its own quest](/quest/m3/quic-realtime/moqsink-feedback.md) owns that feedback. +## Required + +- [moqsink encoder feedback](/quest/m3/quic-realtime/moqsink-feedback.md) - GStreamer publishers retune their encoder to the target rate + ## Related - [QUIC on the sim](/quest/m4/quic-sim.md) - deterministic successor to the moq-shaper harness once it lands diff --git a/quest/m3/release/README.md b/quest/m3/release/README.md index a3066dd3e3e..0accc575b42 100644 --- a/quest/m3/release/README.md +++ b/quest/m3/release/README.md @@ -24,3 +24,26 @@ wire, archive-format, and legacy limits. Downstream staging, mixed-version upgrade/rollback, canaries, and broad rollout follow publication and require their own operator authorization. Do not mark production stability proven merely because upstream artifacts published. + +## Required + +- [Migration audit](/quest/m3/release/migrate-audit.md) - the cut writes a MIGRATE.md entry for every break, stating the net published-to-final change +- [API shape review](/quest/m3/release/api-review.md) - every new or changed public API reviewed for a better shape before the cut +- [Feature review](/quest/m3/release/feature-review.md) - every major work line since the last release judged end to end before the cut +- [Cargo feature review](/quest/m3/release/feature-flags.md) - defaults stay lean and every remaining feature is scoped to the crate that owns it, before the cut +- [Claim new npm names](/quest/m3/release/npm-first-publish.md) - a maintainer claims `@moq/clock`, `libav`, and `video` on npm with trusted publishing, before the cut publishes them +- [Cut and publish](/quest/m3/release/cut.md) - independently executable after m2; release-triggered publication +- [Published assets](/quest/m3/release/assets-release.md) - npm carries hostable worklets +- [C++ publication](/quest/m3/release/cpp-release.md) - archives and matching OBS plugin publish and install +- [Generated C publication](/quest/m3/release/c-publish.md) - released archives run the C samples and interop client +- [Dart publication](/quest/m3/release/dart-publish.md) - the wrapper and native artifacts install from the registry +- [Final libmoq stub](/quest/m3/release/libmoq-final-release.md) - publish the migration notice before removing its source +- [Retire libmoq](/quest/m3/release/libmoq-retire.md) - cleanup only after that publication +- [Retire hand-written C](/quest/m3/release/c-retire.md) - delete the hand-written crate once generated C publishes +- [Retire the web-transport JS qmux](/quest/m3/release/qmux-js-retire.md) - once `@moq/qmux` publishes from `js/qmux`, deprecate `@moq/web-socket-stream` and stop the second publisher +- [Retire the web-transport Rust qmux](/quest/m3/release/qmux-rs-retire.md) - once `qmux` publishes from `rs/qmux`, moq-dev/web-transport stops publishing the crate +- [moq.sh deployment](/quest/m3/release/moq-sh-deploy.md) - verify its release-triggered publication +- [Runner client bump](/quest/m3/release/runner-client-bump.md) - the upstream interop runner's Rust client moves to the published moq-tokio, so it stops stamping every object +- [Smoke clients use request and follow](/quest/m3/release/smoke-bindings-rename.md) - condition: a binding release ships the renames; then the native smoke clients move to them +- [Relay loader adoption](/quest/m3/release/relay-loader-adoption.md) - once their pins carry it, embedding consumers load relay config through `Config::merge` and refuse obsolete spellings +- [moq.dev's hosted demos run on sockets](/quest/m3/release/demo-sockets-deploy.md) - after the cut, a maintainer deploys lite-07 and the socket grants so the hosted boy and CARLA demos connect diff --git a/quest/m3/stats/README.md b/quest/m3/stats/README.md index 74b24e0491b..fc5d2f14893 100644 --- a/quest/m3/stats/README.md +++ b/quest/m3/stats/README.md @@ -118,6 +118,15 @@ generic, so they join this line as [client health](/doc/concept/stats.md#health) and [preflight](/quest/m3/stats/preflight.md). moq.pro keeps the per-project connection view and the dashboard flow. +## Required + +- [Rust reporters](/quest/m3/stats/rust.md) - the player and gateways + publish stats and feedback, as the CLI remuxes and capture do +- [Preflight](/quest/m3/stats/preflight.md) - a bounded test run over a + broadcast reports which media layer is broken and why +- [Client health in use](/quest/m3/stats/health-consumers.md) - a per-connection media counter, consumers of the grade, and re-measured limits +- [The media test checks browser feedback](/quest/m3/stats/feedback-media-test.md) - a browser publishes feedback and Rust reads it back with `moq export echo` + ## Related - [QoS](/quest/m3/qos/README.md) - the relay's delivery counters; the diff --git a/quest/m3/stream/README.md b/quest/m3/stream/README.md index 82ee813ba3d..9ad4c08ef53 100644 --- a/quest/m3/stream/README.md +++ b/quest/m3/stream/README.md @@ -56,3 +56,9 @@ This epic owns the end-to-end proof: an unmodified TCP client and server (SSH and an HTTP bulk transfer) talk through a two-relay chain with loss injected on one hop, with no corruption, FIN and reset propagated, and memory bounded by the window. + +## Required + +- [Rust byte streams](/quest/m3/stream/rust.md) - a duplex `AsyncRead`/`AsyncWrite` stream, a listener and a dialer, and `moq` CLI forwarding +- [JS byte streams](/quest/m3/stream/js.md) - the same surface in `@moq/net` +- [Stream benchmark](/quest/m3/stream/bench.md) - throughput and latency against raw TCP through a relay chain, with and without loss diff --git a/quest/m3/vendor-sync/README.md b/quest/m3/vendor-sync/README.md index 0a3a0f187b4..2c958955bb1 100644 --- a/quest/m3/vendor-sync/README.md +++ b/quest/m3/vendor-sync/README.md @@ -68,6 +68,17 @@ which builds pinned upstream libav.js, ffmpeg, and opus releases unmodified. Public API: none expected; a ported fix that changes one says so. Wire: QUIC behavior follows quinn's fixes. +## Required + +- [moq-quic has every quinn fix it needs](/quest/m3/vendor-sync/quinn.md) - moq-quic, moq-sock's `udp`, moq-tokio's driver, and moq-congestion's Cubic and BBR3 carry quinn's fixes +- [The WebRTC ports have every upstream fix they need](/quest/m3/vendor-sync/webrtc.md) - moq-congestion's GoogCC and moq-audio's NetEq time stretch follow WebRTC's fixes +- [moq-congestion's SCReAMv2 follows its draft and reference](/quest/m3/vendor-sync/scream.md) - draft revisions and Ericsson's reference fixes are ported or ruled out +- [moq-rtmp's rml has every upstream fix it needs](/quest/m3/vendor-sync/rml.md) - rust-media-libs fixes to rml_rtmp and rml_amf0 are ported or ruled out +- [moq-v4l has every libv4l-rs fix it needs](/quest/m3/vendor-sync/v4l.md) - libv4l-rs fixes are ported or ruled out +- [moq-nvenc has every upstream fix it needs](/quest/m3/vendor-sync/nvenc.md) - nvidia-video-codec-sdk fixes and NVIDIA SDK releases are ported or ruled out +- [moq-vaapi has every ChromeOS fix it needs](/quest/m3/vendor-sync/vaapi.md) - cros-libva and cros-codecs fixes are ported or ruled out +- [UniFFI generator forks are current](/quest/m3/vendor-sync/uniffi.md) - the four `kixelated/uniffi-*` forks carry the upstream fixes moq's bindings need + ## Related - [Dependency audit](/quest/m3/audit-deps.md) - covers crates cargo-deny can see diff --git a/quest/m3/video-quality/README.md b/quest/m3/video-quality/README.md index e1f1b819bc9..ff4f00bad74 100644 --- a/quest/m3/video-quality/README.md +++ b/quest/m3/video-quality/README.md @@ -67,3 +67,11 @@ Decided in planning (2026-10-28): - The moq-boy clip is generated, not stored. The emulator is deterministic, so the harness renders it from a public homebrew ROM on `rom.moq.dev` plus scripted input (✅ "Generate it" over "Store captures"). + +## Required + +- [Harness](/quest/m3/video-quality/harness.md) - `just test video-quality` scores OpenH264 rows with per-frame VMAF and boundary pops against floors, nightly +- [On-demand pops](/quest/m3/video-quality/on-demand.md) - cold starts, resubscribes, and fetch-encoded groups spliced with live ones stay under the pop ceiling +- [moq-boy quality](/quest/m3/video-quality/moq-boy.md) - moq-boy's encode is measured on generated clips and fixed +- [GPU runners](/quest/m3/video-quality/gpu-runners.md) - `nixos2` and the desktop host self-hosted runners for the nightly job +- [Hardware rows](/quest/m3/video-quality/hardware.md) - NVENC and VA-API rows from three GPU hosts gate the nightly and compare side by side diff --git a/quest/m3/webrtc/README.md b/quest/m3/webrtc/README.md index d1e87be2c15..19a1d9dfb3c 100644 --- a/quest/m3/webrtc/README.md +++ b/quest/m3/webrtc/README.md @@ -18,6 +18,17 @@ Decided 2026-10-30 with the maintainer (planning interview), after the str0m wor - **Upstream fixes:** after vendoring, nobody merges upstream automatically. Record the vendored upstream versions in the crate docs; the release-cut audit checks the upstream changelogs for security fixes (malformed SRTP/RTCP input, for example) and ports them. - Docs a change makes stale (crate names, `doc/lib/rs`, `doc/setup/upgrade.md`, other quests naming a crate or module) change in the PR that makes them stale. +## Required + +- [A typed DTLS handshake timeout error](/quest/m3/webrtc/dtls-timeout.md) - callers match a DTLS handshake timeout by variant, and session end treats it like an ICE timeout +- [Several bandwidth lines per media section](/quest/m3/webrtc/sdp-bandwidth.md) - answers carry both `b=TIAS` and `b=AS` without splicing +- [DTLS waits for ICE](/quest/m3/webrtc/dtls-after-ice.md) - DTLS flights start once ICE nominates a pair, so a late ICE path can't exhaust them +- [The stack takes kio clock time](/quest/m3/webrtc/clock.md) - the vendored code takes `kio::clock::Instant`, so sim tests drive it directly +- [WHIP/WHEP builds carry no SCTP](/quest/m3/webrtc/sctp-feature.md) - SCTP compiles only with the `p2p` feature +- [The vendored stack keeps only what browsers negotiate](/quest/m3/webrtc/browser-only.md) - PSK suites, `ccm`, and anything else no browser uses are gone +- [The vendored stack exposes only what moq-webrtc calls](/quest/m3/webrtc/dead-api.md) - dead upstream API is deleted once clock settles the time seams +- [A failed client socket ends a WebRTC session with an error](/quest/m3/webrtc/socket-error.md) - a client or `p2p` session whose socket fails ends with its I/O error, not `Ok` or `Closed` + ## Related - [moq-webrtc paces WHEP viewers](/quest/m3/rtc-pacing.md) - adds the NACK hook and the shared pacer on the vendored stack diff --git a/quest/m3/wire-stats/README.md b/quest/m3/wire-stats/README.md index 8f4b9ba0ab4..038b0c4c03f 100644 --- a/quest/m3/wire-stats/README.md +++ b/quest/m3/wire-stats/README.md @@ -70,3 +70,10 @@ receive-side limitations. - **One source registry for sessions and embedders.** An embedder registers a gateway connection's wire source on a `stats::Session` from its stats handle's `session(label)`, the same path the relay's own sessions use. + +## Required + +- [qmux byte counters](/quest/m3/wire-stats/qmux.md) - a WebSocket session + reports its TCP bytes +- [moq-srt wire source](/quest/m3/wire-stats/srt.md) - an SRT connection + reports its wire bytes diff --git a/quest/m4/kio-channel-contention/README.md b/quest/m4/kio-channel-contention/README.md index a84456f1bc5..d217e192ee3 100644 --- a/quest/m4/kio-channel-contention/README.md +++ b/quest/m4/kio-channel-contention/README.md @@ -467,3 +467,8 @@ Decided (maintainer, 2026-11-01, cluster spike): control-plane cost. Weighing the two is for the planning to settle. - Rejected: calling relay-per-thread a no-win and leaving sharding to the replica spike alone, and restoring the no-sharding rule now. + +## Required + +- [Plan relay-per-thread on a worker mesh that never re-announces](/quest/m4/kio-channel-contention/relay-per-thread.md) - measure no-re-announce, weigh it against per-track replicas, and decide whether log adoption waits on it +- [Log adoption](/quest/m4/kio-channel-contention/log-adoption.md) - the rest of moq-net's log-shaped state moves onto the log where it measures as a win diff --git a/quest/m4/p2p/README.md b/quest/m4/p2p/README.md index b9e54bb33b3..367f179bc19 100644 --- a/quest/m4/p2p/README.md +++ b/quest/m4/p2p/README.md @@ -163,6 +163,15 @@ Before `@moq/p2p` is first published, add its entrypoints to the API Extractor declaration checks, which analyze only published packages since [moq-dev/moq#6794](https://github.com/moq-dev/moq/pull/6794). +## Required + +- [Signaling and policy](/quest/m4/p2p/signal.md) - opted-in peers find each other under the prefix, the application picks who to dial, and per-peer `iceServers` decide whether STUN is used +- [Native pairs over ICE and QUIC](/quest/m4/p2p/native-quic.md) - two native peers connect through ICE, then `moq-quic` over the nominated path with fingerprints pinned from the offer +- [moq-cli joins](/quest/m4/p2p/cli.md) - `--p2p` publishes a roster entry, dials native peers over ICE and QUIC, and serves browsers as a transit hop +- [Peer route policy](/quest/m4/p2p/cost-scopes.md) - application priorities and total cost choose eligible routes, with epoch-aware handover +- [Watch opts in](/quest/m4/p2p/watch.md) - one attribute turns it on in the demo and the watcher migrates to the best eligible route +- [Harness](/quest/m4/p2p/harness.md) - the Playwright harness and the numbers behind every mapping decision + ## Related - [E2EE](/quest/m5/e2ee/README.md) - what a peer would need if the token scope stopped being the trust boundary diff --git a/quest/m4/perf/README.md b/quest/m4/perf/README.md index f089a7a53d6..a39664c04c0 100644 --- a/quest/m4/perf/README.md +++ b/quest/m4/perf/README.md @@ -83,3 +83,15 @@ revisions on the same host and worker count, and profiles with - [kio channel contention](/quest/m4/kio-channel-contention/README.md) - workers spend less time blocked on kio channel-state mutexes (up to 215% of worker CPU on chat at 16 tokio workers), via a version counter, per-thread spikes, and an append-only log - [Stream transports](/quest/m4/stream-transports/README.md) - qmux drives its own WebSocket and TCP sockets in one task, measured end to end, then serves them from the io_uring workers +- [Relay allocations](/quest/m4/perf/relay-allocs.md) - fewer allocations per delivered frame, starting with per-stream session clones +- [QUIC lock contention](/quest/m4/perf/quic-lock-contention.md) - a measured verdict on the tokio driver's connection-wide mutex and per-packet endpoint-to-connection hop, with levers built only on evidence +- [Ingest batch](/quest/m4/perf/ingest-batch.md) - relay ingest pays one lock, wake, and clock read per burst of whole frames instead of per frame +- [kio waiter costs](/quest/m4/perf/kio-waiter-costs.md) - long-lived waiters stop being rebuilt every poll, IETF fetch keeps one close watch per stream, and a short `kio::log` costs less +- [Shard by default](/quest/m4/perf/shard-default.md) - a saturating shard sweep decides whether an unset `runtime.workers` runs one worker per core on Linux +- [Mesh session cost](/quest/m4/perf/mesh-session-cost.md) - moq-net's per-session announce, route sync, and scope work drops, swept over sessions and announces +- [Cluster route memory](/quest/m4/perf/cluster-route-memory.md) - a full-mesh cluster's ~3.7 KB per route per broadcast shrinks, and the in-memory hop is profiled +- [Lock profiles find why switch records stop alternating](/quest/m4/perf/profile-lock-switches.md) - refusals stay strict and get a root cause, and lost records are sized and counted +- [Small hot-path waste](/quest/m4/perf/hot-path-waste.md) - one track-name copy per lite subscription, no full-history `#drift` walk, and one header buffer per JS object +- [Track-state reads skip when nothing changed](/quest/m4/perf/cursor-version-skip.md) - `Cursor::sync`, `probe` and `GroupExpiry` skip unchanged reads, then group reads move onto a Watch +- [An idle TS export with a delay costs what one without does](/quest/m4/perf/ts-idle-jitter.md) - the jitter scan and memcmp stop leading the idle poll +- [Fanout takes the route lock less](/quest/m4/perf/route-lock.md) - fewer than 41 route-lock acquisitions per fanout round diff --git a/quest/m4/stream-transports/README.md b/quest/m4/stream-transports/README.md index 0d11bb92fc3..0de481c542e 100644 --- a/quest/m4/stream-transports/README.md +++ b/quest/m4/stream-transports/README.md @@ -143,6 +143,13 @@ Decided 2026-10-31 (maintainer), in about 15 minutes against a base at 3 rounds; the transport argument narrows a run when that matters. +## Required + +- [Ring TCP ablation](/quest/m4/stream-transports/ablation.md) - measured ring TCP against tokio TCP under the qmux workload picks the mechanisms the port uses +- [Ring TCP](/quest/m4/stream-transports/ring.md) - moq-uring serves TCP, and hyper (therefore axum) runs on it +- [Relay listeners on the workers](/quest/m4/stream-transports/relay.md) - the relay's WebSocket, qmux TCP, and HTTP listeners run on the io_uring workers +- [Codec](/quest/m4/stream-transports/codec.md) - qmux frames WebSocket itself and tungstenite leaves the tree, if the bench says it pays + ## Related - [WebSocket rate caps](/quest/m3/rate-websocket.md) - its IO wrapper sits under the protocol, on the socket the driver now owns diff --git a/quest/m5/README.md b/quest/m5/README.md index 39cc0a6f982..a2a5f6056d5 100644 --- a/quest/m5/README.md +++ b/quest/m5/README.md @@ -33,3 +33,59 @@ in this repository and in moq.pro's plans, which kept the io_uring tuning quests (fleet relays on io_uring workers), broadcast fairness, and the transcode and NVENC quests (production transcoding). Re-plan one when a consumer asks. + +## Required + +- [Mesh over ICE](/quest/m5/mesh-ice.md) - mesh nodes on different networks connect directly through the P2P line's ICE pairs, once a mesh user needs it +- [Video validation hardware is on hand](/quest/m5/video-hardware-access.md) - the machines the validation runs on, including a Raspberry Pi 4/5 for embedded presenting +- [Fair share across broadcasts on cluster links](/quest/m5/broadcast-fairness.md) - broadcasts share a cluster link fairly, so one tenant's priority never starves another's, once a tenant identity exists +- [Video hardware validation](/quest/m5/video-hardware.md) - run the encode, capture, and zero-copy paths that were never run on real machines, including PipeWire on KDE, the camera portal, and a Pi +- [An Ada NVIDIA GPU is available](/quest/m5/ada-gpu.md) - the hardware AV1 NVENC is verified on +- [NVENC AV1](/quest/m5/nvenc-av1.md) - AV1 encode through NVENC, once an Ada-generation GPU is available +- [NVDEC and NVENC share CUDA arrays](/quest/m5/nvenc-cuda-arrays.md) - SDK 13.1 application-owned CUDA arrays drop the per-frame device copy, on driver 610+ +- [Embedded video](/quest/m5/video-embedded.md) - verify a Pi 4/5 presents through the existing Vulkan and CPU paths, adding EGL import only if that fails +- [A physical-NIC peer for the zero-copy sweep](/quest/m5/zero-copy-peer.md) - the rig the zero-copy sweep runs on +- [#3201: moq-uring: use SENDMSG_ZC for large UDP GSO trains](/quest/m5/3201-moq-uring-use-sendmsg-zc-for-large-udp-gso-trains.md) - complete the prerequisite issue first +- [#3204](/quest/m5/3204-moq-uring-register-tx-pool-buffers-for-zero-copy-sends.md) - moq-uring: register TX-pool buffers for zero-copy sends +- [Cluster dials on the ring](/quest/m5/uring-cluster-dial.md) - measure whether an io_uring relay's outbound cluster links belong on its workers +- [#3202](/quest/m5/3202-moq-uring-use-fixed-file-slots-for-worker-udp-sockets.md) - moq-uring: fixed-file slots for worker UDP sockets, if its own benchmark measures a win +- [Byte streams in moq-ffi](/quest/m5/ffi-stream.md) - Swift and Kotlin dial and accept byte streams, for moq.pro's T3 Code mobile client +- [E2EE in moq-ffi](/quest/m5/ffi-e2ee.md) - Swift and Kotlin publish and consume protected broadcasts, for the same client +- [The moq.pro mesh runs lite-07](/quest/m5/lite07-mesh.md) - the deployment that makes the exemption dead code +- [Drop the hidden cluster exemption](/quest/m5/hidden-exemption.md) - relays stop forcing hidden broadcasts on cluster peers once every peer opts in on the wire +- [Robot teleoperation conventions](/quest/m5/teleop-robot.md) - documented track shapes for video down and control up, implemented by the MAVLink gateway, once a robotics consumer appears +- [Operator arbitration](/quest/m5/teleop-arbitration.md) - one operator holds control at a time +- [MAVLink bridge](/quest/m5/teleop-mavlink.md) - a `moq-mavlink` gateway + replacing the VPN plus two unmanaged UDP flows, with QGroundControl and + friends unchanged +- [SITL proof and browser ground station](/quest/m5/teleop-proof.md) - ArduPilot + SITL and a synthetic camera flown from a browser ground station, reproducible + in five minutes +- [Interop runner withdraws before disconnecting](/quest/m5/interop-runner-approval.md) - condition: a released moq-tokio and @moq/net carry close() withdrawals; then the runner's moq.dev clients switch to close() +- [Safari ships the WebKit 319818 fix](/quest/m5/webkit-319818.md) - the Safari release the gate admits +- [Safari WebTransport](/quest/m5/safari-webtransport.md) - WebKit browsers return to WebTransport once WebKit 319818 ships fixed +- [moq-video in the browser](/quest/m5/video-web.md) - getUserMedia, getDisplayMedia, WebCodecs, and VideoFrame import into wgpu, for moq-dev/studio's web studio +- [moq-audio in the browser](/quest/m5/audio-web.md) - AudioWorklet capture and playback and WebCodecs Opus and AAC, for the web studio's audio +- [Mesh keys](/quest/m5/mesh-keys.md) - parked: encrypted and HMAC-authenticated mesh broadcasts through a wrapped `.keys` track +- [rust2-ts reaches moq-net's model](/quest/m5/rs2ts-model-ready.md) - rust2's translator is ready to translate the model +- [Keep moq-net's model in rust2-ts's subset](/quest/m5/rs2ts-model-subset.md) - safe twins for the model's internal `unsafe`, `dyn Expiry` as an enum, once rust2-ts reaches the model +- [Wait for a stable bun lint](/quest/m5/bun-lint-release.md) - condition: `bun lint` ships in a stable Bun that nixpkgs carries +- [A transcode ladder probes an unseen source shape without stalling its other rungs](/quest/m5/transcode-parallel-open.md) - a source changing to an unseen size opens the new encoders without stalling the ladder's other rungs +- [Relay ACME on instant-acme](/quest/m5/relay-acme.md) - moq-relay's ACME returns on instant-acme and rind, once a user needs it +- [Native compression flush](/quest/m5/native-compression-flush.md) - report the per-frame nonfinal flush requirement in existing browser discussions +- [Native synchronous codecs](/quest/m5/native-compression-sync.md) - report the stateful small-frame synchronous API requirement +- [Native browser codecs](/quest/m5/native-compression-adopt.md) - adopt native operations when timing, frame and resource contracts hold +- [Vendor-free CARLA bridge](/quest/m5/carla-bridge.md) - the CARLA demo's GPU bridge lets moq-video pick the encoder, and its stand-in test runs on AMD as well as NVIDIA +- [Wrapper traits over moq-net](/quest/m5/net-wrap/README.md) - moq-net exports producer and consumer traits, and every writer and reader above it takes them, so a wrapper such as e2ee passes through unchanged +- [E2EE](/quest/m5/e2ee/README.md) - TypeScript and Rust peers interoperate over encrypted broadcasts no relay can decrypt +- [Publishers learn their cap](/quest/m5/rate-grant.md) - the AUTH grant carries the caps and publishers clamp their encoder to them +- [WASM-to-JS evaluation](/quest/m5/rs2ts-wasm2js.md) - try the Rust implementation as JS-only browser output and compare source-translator alternatives if needed +- [JS-only @moq/net](/quest/m5/rs2ts-js.md) - adopt the selected Rust-to-JS route after browser parity and measured tradeoffs are accepted +- [#3199](/quest/m5/3199-moq-uring-remove-sq-indirection-and-per-enter-ring-fd.md) - moq-uring: remove SQ indirection and per-enter ring fd lookup, if a profile shows the win +- [#3200](/quest/m5/3200-moq-uring-batch-completion-wakeups-with-min-timeout.md) - moq-uring: batch completion wakeups with MIN_TIMEOUT +- [Browser media report](/quest/m5/rs2ts-browser-report.md) - compare Rust-backed and handwritten @moq/net through full media workloads, supplementing the pre-adoption comparisons +- [Link quality](/quest/m5/link-quality.md) - a radio link's cost follows its measured quality without flapping routes +- [io_uring thread check](/quest/m5/uring-transport-machines.md) - the relay fanout bench measures `moq_uring::transport::Local`'s per-call thread check after the transport is boxed, removing it only if it shows +- [NVENC buffer pool](/quest/m5/nvenc-pool.md) - NVENC reuses input and output buffers instead of allocating per frame, if a benchmark shows it wins +- [QUIC I/O boundary](/quest/m5/quic-io-boundary.md) - moq-uring receives from the buffer ring and transmits into caller-owned buffers with no copy, once a profile says where +- [A failed archive time lookup fails the subscription](/quest/m5/archive-time-followups.md) - when an `archive::Consumer` cannot answer a `Time(pts)` lookup because a store GET fails or an object does not decode, the subscription fails with a typed error naming the lookup failure instead of silently falling back to the cache diff --git a/quest/m5/e2ee/README.md b/quest/m5/e2ee/README.md index 8c0a0cfc7ed..48cd60aae98 100644 --- a/quest/m5/e2ee/README.md +++ b/quest/m5/e2ee/README.md @@ -73,6 +73,25 @@ Before `@moq/crypto` is first published, add its entrypoints to the API Extractor declaration checks, which analyze only published packages since [moq-dev/moq#6794](https://github.com/moq-dev/moq/pull/6794). +## Required + +- [JS undeclared track names](/quest/m5/e2ee/js-undeclared-names.md) - + `@moq/net` exposes a broadcast request handler and `@moq/crypto` serves + undeclared names through it +- [Rust protected publisher seams](/quest/m5/e2ee/rust-publish.md) - Rust + publishers emit encrypted catalogs and no plaintext semantic catalog in + E2EE mode, through the moq-net traits +- [Encrypted consumer shape](/quest/m5/e2ee/consumer.md) - one consumer shape, the producer's mirror, shared by browser and CLI (moq-ffi is out of scope for this epic) +- [Encrypted browser components](/quest/m5/e2ee/browser.md) - browser publish + and watch components handle encrypted audio and video without leaking + credentials into browser-owned surfaces +- [Encrypted native CLI](/quest/m5/e2ee/cli.md) - the native CLI publishes and + plays encrypted media without exposing credentials through process metadata + or logs +- [Cross-language encrypted proof](/quest/m5/e2ee/interop.md) - browser + TypeScript and native Rust exchange encrypted media both ways, with relays + forwarding and metering blind + ## Closes - [#3023](https://github.com/moq-dev/moq/issues/3023) - close this issue when the quest finishes diff --git a/quest/m5/net-wrap/README.md b/quest/m5/net-wrap/README.md index 63d0557208f..4b53f33338c 100644 --- a/quest/m5/net-wrap/README.md +++ b/quest/m5/net-wrap/README.md @@ -69,6 +69,15 @@ Open: the trait names. Bring options with a recommendation in the [moq-net traits](/quest/m5/net-wrap/traits.md) PR; the methods are fixed above. +## Required + +- [moq-net traits](/quest/m5/net-wrap/traits.md) - moq-net exports producer and consumer traits at every level, implemented by its own types +- [moq-crypto's e2ee implements the traits](/quest/m5/net-wrap/e2ee.md) - the e2ee broadcast, track, and group wrappers implement the traits, proving them before the adopters land +- [moq-json, moq-stats, and hang take the traits](/quest/m5/net-wrap/json.md) - json snapshots, streams, windows, the stats producer, and hang's tracks write and read through the traits +- [moq-mux takes the traits](/quest/m5/net-wrap/mux.md) - importers, catalog, container, timeline, json tracks, `Source`, TS export, and the moq-video and moq-audio encoders are generic over the traits +- [CLI paths take the traits](/quest/m5/net-wrap/cli.md) - the CLI's publish and play paths hand moq-mux any broadcast that implements them +- [JS mirror](/quest/m5/net-wrap/js.md) - `@moq/net` exports the same interfaces, taken by `@moq/hang`, `@moq/publish`, and `@moq/watch`, and implemented by `@moq/crypto` + ## Related - [E2EE](/quest/m5/e2ee/README.md) - the first wrapper, which publishes and consumes through these traits