Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions quest/m0/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ The historical samples locate candidates; they are not controlled benchmarks.
- [The queue host keeps the queue's disk](/quest/m0/ci/queue-host-disk.md) - agent sessions can't starve the queue runner of disk, and a crashed runner restarts
- [The next test-CPU cuts](/quest/m0/ci/test-cost-followups.md) - the slow-test leftovers from #6987, cut at their source
- [Biome checks every file it can parse](/quest/m0/ci/biome-whole-repo.md) - Biome runs over the whole repository and main is clean under it
- [mbx launches Cargo with any argument length](/quest/m0/ci/mbx-arg-max.md) - no "Argument list too long" in `sh/rs/select.test.py`'s recipe test
21 changes: 21 additions & 0 deletions quest/m0/ci/mbx-arg-max.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# [S] mbx launches Cargo with any argument length

## Goal

mbx launches Cargo however long its argument list or environment is, and
`RecipeTest.test_unexecuted_bench_is_not_compiled` (`sh/rs/select.test.py`)
passes in `just ci`.

## Plan

Planned 2026-11-01 (maintainer, follow-up planning). A `just ci` run during
[moq-dev/moq#7567](https://github.com/moq-dev/moq/pull/7567) failed in that
test, because mbx couldn't launch Cargo: "Argument list too long" (`E2BIG`).

- First find which part goes over the limit: the argv, or the environment
the test passes (`os.environ` plus its overrides).
- Then fix it at the cause, for example by passing long lists through a file
or by trimming what mbx forwards, rather than skipping the test.
- If the limit is hit inside mbx itself rather than in this repository's
wrapper, the fix belongs upstream, and this quest pins the release that
carries it.
1 change: 1 addition & 0 deletions quest/m0/test-flakes-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ Public API: none. Wire: none.
- [IETF22 fallback](/quest/m0/test-flakes-2/ietf22-fallback.md) - an IETF22 browser viewer follows a fallback within the media lane's bound, keeping its session and its audio
- [moq-relay's auth-trust test survives load](/quest/m0/test-flakes-2/relay-auth-trust.md) - it stops timing out on a busy host
- [Draft-22 interop with a native publisher](/quest/m0/test-flakes-2/draft22-interop.md) - no "invalid fetch range" or audio gap with a Rust or C++ publisher
- [The relay fits a Windows stack under every feature set](/quest/m0/test-flakes-2/relay-stack-all-features.md) - the 1 MiB stack test passes under `--all-features` too
24 changes: 24 additions & 0 deletions quest/m0/test-flakes-2/relay-stack-all-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# [S] The relay fits a Windows stack under every feature set

## Goal

`stack::debug_relay_load_and_run_fit_windows_stack`
(`rs/moq-relay/tests/integration/stack.rs`) passes under
`cargo nextest --all-features` as well as in `just ci`. The relay's
`Relay::load` and `Relay::run` futures fit a 1 MiB thread stack under every
feature set the test builds with.

## Plan

Planned 2026-11-01 (maintainer, follow-up planning). Seen while iterating
[moq-dev/moq#7211](https://github.com/moq-dev/moq/pull/7211): on main
(da0a9e1d8a) the test overflows its stack under `--all-features`, and passes
with the gate's feature set.

- Find which feature makes the future grow past the stack, for example by
bisecting features and checking future sizes with `-Zprint-type-sizes` or
`std::mem::size_of_val`.
- Shrink it at its source, for example by boxing a large state or moving a
large local out of the async body.
- Don't raise the stack size, and don't narrow the test's features to hide
the overflow: the test exists because Windows' main thread really has 1 MiB.
7 changes: 7 additions & 0 deletions quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ Added 2026-10-27 (maintainer, from an external security audit): relay and
wire boundary fixes, importer streaming, moq-c handle wrap, browser input
checks, and CI tool pins, under one epic; its credential leaks went to m0.

Added 2026-11-01 (maintainer, follow-up planning): byte-stream ladders, so
the binding API for `lower` breaks before the cut, `moq export` ending
with its broadcast, and a relay answering a SUBSCRIBE on a fetched copy.

Added 2026-10-27 (maintainer, from an external release-to-main audit): the
bindings' silent `max_delay` default change and the upgrade notes that
contradict the code. Its other findings already had owners or contradicted
Expand Down Expand Up @@ -141,7 +145,10 @@ per-frame CPU growth since #5926.
- [moq-c at parity](/quest/m1/c/README.md) - the hand-written `moq-c` ships at the cut with every m1 binding feature moq-ffi gains
- [Exact timestamps in every binding](/quest/m1/binding-timestamps.md) - bindings carry `{value, scale}` timestamps instead of lossy microseconds
- [Bindings see a moq-transport run end as an end](/quest/m1/ffi-ietf-run-end.md) - an IETF publisher ending its run reaches moq-ffi consumers as an end, not `Internal`
- [Byte-stream renditions form a ladder](/quest/m1/stream-ladder.md) - moq-ffi stream producers link as `lower` and disable unfundable rungs like frame producers
- [A broadcast stamps everything from one clock](/quest/m1/broadcast-clock.md) - catalog, MSF, and HLS record groups are stamped from the broadcast's clock, never the ambient one
- [moq export ends when the broadcast ends](/quest/m1/export-broadcast-end.md) - the export finishes on its own, proven without a give-up timeout
- [A relay answers a SUBSCRIBE on a copy it kept after a fetch](/quest/m1/relay-fetched-copy-subscribe.md) - the downstream SUBSCRIBE_OK waits for the upstream edge instead of hanging
- [A job's exact route continues its claim's readers](/quest/m1/announce-takeover.md) - a job's route inherits its claim's identity, replacing the ANNOUNCE_TAKEOVER predecessor design
- [Subscribe ranges](/quest/m1/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; merged ranges never starve a subscriber; relays fill misses by range, including over moq-transport
- [Drop set](/quest/m1/drop-set.md) - each cursor judges missing groups against its own budget, so a narrow reader drops promptly and a widening re-offers groups already reported dropped on lite-07
Expand Down
30 changes: 30 additions & 0 deletions quest/m1/export-broadcast-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# [S] moq export ends when the broadcast ends

## Goal

`moq export` finishes on its own once the broadcast it reads ends. A test
proves this without a give-up timeout.

## Plan

Planned 2026-11-01 (maintainer, follow-up planning). Found while iterating
[moq-dev/moq#6987](https://github.com/moq-dev/moq/pull/6987):

- In all 20 drains of its export timing tests, the export never reported the
end of the broadcast after the video and audio tracks finished. An older
version of the test helper ended fine, so something on main changed this.
- Main's copy of the helper gives up after advancing the clock 10 ms, which
hides the problem.
- It may only be the export waiting on the catalog track, which those tests
never close.

First find out which it is.

- **If it's a real bug,** an export that never ends after a finished
broadcast, fix it.
- **If the export correctly waits for the catalog,** make the tests finish
their catalog. Document in `doc/bin/cli.md` (or wherever `moq export` is
documented) that export ends when the catalog does.

Either way, the timing tests then read to the export's real end, and the
10 ms give-up is removed.
29 changes: 29 additions & 0 deletions quest/m1/relay-fetched-copy-subscribe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# [S] A relay answers a SUBSCRIBE on a copy it kept after a fetch

## Goal

A moq-transport subscriber gets SUBSCRIBE_OK for a history SUBSCRIBE sent
through a relay that holds a copy kept after a FETCH. The OK names the live
edge from the upstream's SUBSCRIBE_OK, never from the relay's cache or an
edge the upstream reported earlier. An integration test covers it.

## Plan

Planned 2026-11-01 (maintainer, follow-up of
[moq-dev/moq#7545](https://github.com/moq-dev/moq/pull/7545)).

Repro, from #7545's review: the relay fetches group 2 of an unfinished track.
A fresh draft-22 session then subscribes `with_range(1..2)` through it, and
gets no SUBSCRIBE_OK within 5 s. It hangs the same way on main
(`3ae67897`), where the relay does subscribe upstream, so this bug predates
#7545.

- The maintainer decided on 2026-11-01, on #7545, that the OK waits until the
live edge is known, and is never taken from the cache. So the fix is not to
answer from the stale reported edge.
- Find why the upstream's SUBSCRIBE_OK doesn't reach the downstream OK on a
fetched copy, and fix that.
- Test it in `rs/moq-net/tests/integration/fetch_only.rs` on drafts 18 and 22,
direct and through a relay.

Public API: none. Wire: none.
35 changes: 35 additions & 0 deletions quest/m1/stream-ladder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# [M] Byte-stream renditions form a ladder

## Goal

A simulcast ladder of moq-ffi byte-stream producers
(`MoqMediaTrackStreamProducer`, which imports fMP4, MKV, TS, or FLV bytes)
works like a ladder of frame producers (`MoqMediaTrackProducer`):

- A stream producer can be passed as another rendition's `lower`, and sits
one priority below it.
- It disables itself when the bandwidth grant can't fund it, and resumes at
the next keyframe, as
[moq-dev/moq#7029](https://github.com/moq-dev/moq/pull/7029) does for
frame rungs.

Every binding exposes this.

## Plan

Planned 2026-11-01 (maintainer, follow-up planning; m1 so the binding API
breaks before the cut). Raised by CodeRabbit on #7029
([r4436515610](https://github.com/moq-dev/moq/pull/7029#discussion_r4436515610)).

- The stream producer records its priority and exports `set_enabled`.
- `lower` (`MoqVideoInit.lower`, `MoqVideoProducerOptions.lower`) accepts
either producer kind. That changes a public UniFFI field type in every
binding (Python, Swift, Kotlin, Go, Dart).
- Pick the type that keeps one field, for example a small enum or a shared
rendition handle.
- Record the choice, and the migration in each `MIGRATE.md`.
- The C ABI follows when the C ABI parity work for #7029 does.
- Test a two-rung stream ladder in `rs/moq-ffi/src/test.rs`: the lower rung
is funded first, and the upper rung disables and resumes at a keyframe.

Public API: breaking in every binding (`lower`'s type). Wire: none.
8 changes: 8 additions & 0 deletions quest/m1/unbounded-groups/fastest-reader.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ Decided 2026-10-28 (maintainer, after an audit of the plan):
(`CloseKind::Evicted`), which could reset the very byte stream pacing keeps
lossless. Bring the mechanism to the maintainer before coding, and align it
with the [receive pool](/quest/m2/receive-pool.md).
- Folded in 2026-11-01 (maintainer, follow-up of
[moq-dev/moq#7328](https://github.com/moq-dev/moq/pull/7328)): the same cap
covers streams parked waiting for TRACK_INFO. Group data that a SUBSCRIBE
sent alongside TRACK, or a FETCH, leaves unread until TRACK_INFO arrives
must not use up the connection receive window, or TRACK_INFO itself can't
arrive. TRACK_INFO and other control messages always get connection
credit, in Rust and JS. Test it: enough parked groups to fill the
connection window, with TRACK_INFO still arriving and the groups then read.

Prior art splits the same way (2026-10-28 survey): Varnish streaming, ATS
read-while-writer, and WHATWG `tee()` fan out at the writer's pace and buffer
Expand Down