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/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fidelity: a red Interop hides real regressions.

## Required

- [CI cache release](/quest/m0/ci-cache-release.md) - a stable cache server supports anonymous reads and OIDC writes restricted to the main warmer
- [Self-hosted CI](/quest/m0/self-hosted-ci.md) - same-repo Check and Test run on a self-hosted NixOS runner with a main-written local cache, behind a `CI_RUNNER` kill switch
- [CI host](/quest/m0/ci-host.md) - the maintainer brings up the spare desktop as the `moq-ci` and `moq-gpu` runner host
- [Draft-22 media on 0.17](/quest/m0/release-22/README.md) - a 0.17.x with the LOCATION_FILTER and FIRST_OBJECT fixes and moq-noq 1.3.5, before Seattle, then draft-20+ FETCH
Expand Down
25 changes: 25 additions & 0 deletions quest/m0/ci-cache-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# [XS] A stable cache server enforces the CI write policy

## Goal

Condition: a stable `jdx/mr-boxington-cache` release supports anonymous reads
and server-enforced GitHub OIDC writes restricted to the main cache warmer,
as [Self-hosted CI](/quest/m0/self-hosted-ci.md) requires.

## Plan

Decided in the quest audit: wait for a stable release rather than select an
unreleased pin or weaken the write boundary. The latest stable release,
v0.1.1, allows writes in anonymous mode; [#5218](https://github.com/moq-dev/moq/pull/5218)
therefore keeps workflow routing hosted while preparing the runner module.

Check the upstream releases and their authentication policy. Advance this
condition by identifying a stable release that supports the required split;
record its version and policy evidence when deleting this quest. The
self-hosted CI quest owns packaging it and testing that anonymous and PR-ref
writes fail while the main warmer can write. Keep `CI_RUNNER` unset until
that implementation and its validation are complete.

## Related

- [Self-hosted CI](/quest/m0/self-hosted-ci.md) - packages and proves the cache policy before enabling workflow routing
6 changes: 5 additions & 1 deletion quest/m0/self-hosted-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ group) with `CI_RUNNER` set and unset, and that the module evaluates (`nix eval`
and with a token from a PR ref). End-to-end proof happens in
[CI host](/quest/m0/ci-host.md).

Public API: none. Wire: none.
Public API: the NixOS runner module and its configuration options. Wire: none.

## Required

- [CI cache release](/quest/m0/ci-cache-release.md) - a stable server supports the enforced read/write split; keep routing hosted until its policy is proven

## Related

Expand Down
3 changes: 1 addition & 2 deletions quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ disabled rung strands WHEP, HLS, and moq-mux export viewers.
- [Controlled time](/quest/m1/time/README.md) - every crate and package reads time through moq-time or @moq/time, and every test runs on a controlled clock; ranks above the fork, whose switch adopts its instant
- [Hard fork](/quest/m1/quic/fork/README.md) - quinn hard-forked in-tree as `moq-quic`, ranked ahead of perf; the rest of the QUIC line follows it
- [Cluster routing](/quest/m1/cluster-routing/README.md) - any node routes toward a broadcast's origin over CDN and P2P links alike, with per-origin routes and path-less announces
- [Flat questlines](/quest/m1/quest-flat-lines.md) - moq pins the current quest CLI, lands its questline branches on main, and retires them
- [Binding audio delay](/quest/m1/binding-surface.md) - moq-ffi and every wrapper configure and observe audio playout delay
- [Per-frame arrivals in @moq/watch](/quest/m1/watch-arrivals.md) - the audio and video decoders expose a window of recent frame arrivals, late and skipped marks included, as a signal
- [Bump web-transport-iroh for the capsule close](/quest/m1/iroh-capsule-bump.md) - condition: moq-dev/web-transport#419 ships in a release, then moq's iroh HTTP/3 client reports a peer's close capsule
Expand Down Expand Up @@ -161,7 +160,7 @@ disabled rung strands WHEP, HLS, and moq-mux export viewers.
- [BBR ACK cleanup](/quest/m1/bbr-ack-cleanup.md) - packet bookkeeping scales with completed entries instead of scanning the flight on every ACK
- [Perf](/quest/m1/perf/README.md) - eliminate measured hot-path costs across moq-uring, kio, and the moq-net model
- [Benchmark regressions in CI](/quest/m1/bench-ci.md) - PRs get a non-blocking comparison of the Criterion benches they affect, and a nightly trend on main alerts on regressions
- [Mergeable bench buckets](/quest/m1/bench-buckets.md) - moq-bench emits per-interval latency buckets that sum across processes and hosts
- [Backport mergeable bench buckets](/quest/m1/bench-buckets.md) - release receives main's per-interval latency buckets and their tests
- [Relay session bench](/quest/m1/bench-relay.md) - the same scenario through moq-relay's own connection handling
- [Read-only lookup](/quest/m1/read-only-lookup.md) - a live track lookup stops waking the front and every demand watcher
- [Rust-backed @moq/net](/quest/m1/rs2ts/README.md) - measure browser baselines, complete WASM bindings, and adopt Rust behind @moq/net before the later JS-only stage
Expand Down
8 changes: 4 additions & 4 deletions quest/m1/archive/replay-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ this by hand-building a catalog.
A live playlist stays capped even for a durable timeline; listing past the
window is the explicit `moq_hls::export::Config::history` mode, which `moq
export hls` does not expose yet. Give it a flag here. History mode lists from
the records the timeline restates when the exporter joins (at most 256 from a
`moq-mux` publisher), so "the whole recording" also needs the exporter to
read a longer recording's stored history rather than only its live
restatement.
stored timeline groups, including records older than the live restatement
(#5236). Reuse that recovery in the end-to-end proof rather than implement it
again. [Retained-floor history](/quest/m1/archive/history-floor.md) and
[HLS failure signaling](/quest/m1/hls-failure-signal.md) remain separate work.

Add a CI test that records a broadcast longer than the default window, replays
it, and asserts the stock exporter lists segment 0 with a durable
Expand Down
59 changes: 16 additions & 43 deletions quest/m1/bench-buckets.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,24 @@
# [S] moq-bench: mergeable interval buckets
# [S] Backport moq-bench's mergeable interval buckets

## Goal

Every `moq-bench` JSONL line carries that interval's latency histogram in a
versioned, documented bucket layout, so the buckets from several bench
processes on several hosts sum element-wise over any window of whole report
intervals into one distribution; a window cutting through an interval cannot
separate that interval's samples. A percentile computed once from the summed buckets matches one
computed from the concatenated samples binned by the same layout and overflow
rule: the buckets are lossy, so the match is exact at bucket resolution, not
at raw-sample precision.
The `release` line carries main's mergeable interval latency histograms, so
load harnesses can combine several bench processes over whole report
intervals. Preserve the version-1 sparse millisecond buckets, interval
bounds, documentation, and regression tests already landed on `main`.

## Plan

Main-side draft implements the sparse version 1 histogram and interval bounds.
Remaining: after the main PR merges, backport the landed commit and any missing
#5021 interval delta to release in a separate draft. Do not cherry-pick an
unlanded main draft; keep this quest until the backport exists.


Decided 2026-10-05 by the maintainer: percentiles neither window nor merge,
and a load harness sums several generators against one relay, so the bench
emits mergeable buckets.

- `Latency` (`rs/moq-bench/src/stats.rs`) counts 1 ms buckets for the whole
run and diffs them each interval for the `latency_interval_*` percentiles
([#5021](https://github.com/moq-dev/moq/pull/5021)); this quest emits that
same delta in a mergeable layout, so the two share one representation.
- 60,001 dense buckets per line is too much JSON. Pick a compact layout (sparse
non-zero buckets, or a log-linear layout with bounded relative error) and
record why.
- The output documents: the layout version, units, the interval's start and
end, the sample count, and what an empty or partial interval (the first and
the last) looks like.
- Harness rule: publisher and subscriber run on one host, so latency closes
on one clock and buckets from several hosts merge without skew;
`latency_clock_skew` keeps flagging a violation. Replace the README's
advice to NTP-sync separate publisher and subscriber hosts
(`rs/moq-bench/README.md`, "Machine-readable output") with this rule.
- A test sums fixture buckets from two runs and checks the percentiles
against the concatenated samples, binned by the same layout and the same
overflow bucket (60,000 ms and above today) before the percentile is
taken. Update `rs/moq-bench/README.md`.

Lands on main, then is backported to `release` as an additive cherry-pick
PR, like [#4882](https://github.com/moq-dev/moq/pull/4882), since downstream load
harnesses track `release` (decided 2026-10-05). The backport carries #5021's
delta along if `release` does not have it yet.
[#5268](https://github.com/moq-dev/moq/pull/5268) landed as `0a47269be`.
Decided in the quest audit: only its release backport remains; do not reopen
the histogram layout decision. Backport that commit in a separate PR to
`release`, including [#5021](https://github.com/moq-dev/moq/pull/5021)'s interval
delta if it is still absent there. Downstream load harnesses track `release`,
which is why the maintainer requested this backport on 2026-10-05.

Run the landed histogram merge and interval tests on the backport and keep
the same JSONL contract: merging is exact at bucket resolution, a partial
interval cannot be split, and publisher/subscriber measurements share one
host clock. Preserve the README's layout and clock documentation.

Public API: none (CLI output only). Wire: none.
4 changes: 4 additions & 0 deletions quest/m1/c/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ client build and run against the released 0.8.0 archive, not only in-tree.

The hand-written crate gets no more feature work: its shutdown, CMake library,
and fetch quests were abandoned for this line, and hidden is done.
Decided in the quest audit: [claim epochs](/quest/m1/claim-answer-epochs.md)
is a narrow correctness exception. Its existing claim API migrates with
Rust and JS so C cannot retain the unsafe accept path while this line waits.
That change owns its C tests and upgrade notes; other API reshaping stays here.

## Required

Expand Down
7 changes: 7 additions & 0 deletions quest/m1/claim-answer-epochs.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ Public API: breaking. A claim request is answered through `prepare` and
`publish`, and a public claim takes no epoch, in Rust, JS, moq-ffi, moq-c and
every binding wrapper, plus the claim docs. Wire: none.

Decided in the quest audit: migrate the hand-written C claim API in this
change as a narrow correctness exception to the
[C freeze](/quest/m1/c/README.md). Leaving its existing accept path would
preserve the identity bug, so claim safety does not wait for generated C.
This permits only the claim migration and its tests and upgrade notes;
the broader C API still waits for the generated replacement.

## Related

- [Announcement takeover](/quest/m1/announce-takeover.md) - its claim-to-route operation is `Request::prepare` then `publish`; TAKEOVER then removes the cold-start reset
Expand Down
8 changes: 2 additions & 6 deletions quest/m1/dropped-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Consumers never decide behavior by matching an error; errors are diagnostics.

- Rust already maps IETF `PUBLISH_DONE` Unauthorized to `Error::Unauthorized`,
and a closed source's standing route no longer re-requests it.
- #4179 fixes revoked upstream subscriptions and #4120 preserves session death
and resumed-track errors. After #4179 reaches `main`, verify the remaining
- #4179 fixed revoked upstream subscriptions and #4120 preserves session death
and resumed-track errors. Both are on `main`; verify the remaining
track paths (source close, route removal, broadcast withdrawal) locally and
over a mock session, and map JS `PUBLISH_DONE` Unauthorized to #4179's shared
error. Preserve causes at the source rather than remapping `Dropped` at
Expand Down Expand Up @@ -79,10 +79,6 @@ Consumers never decide behavior by matching an error; errors are diagnostics.

Public API: none expected; error values consumers observe change. Wire: none.

## Required

- [Auth](/quest/m1/auth/README.md) - its Unauthorized quest (#4179, done on the line) supplies shared Unauthorized errors and revoked-stream handling

## Closes

- [#5347](https://github.com/moq-dev/moq/issues/5347) - `export ts --stitch --linger` exits on `internal error` when a catalog request lands on a dying publisher
Expand Down
9 changes: 5 additions & 4 deletions quest/m1/ffi-shape/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ The line landed on `main` in #4519 (2026-10-09) with its json/flate, net,
media, and request-accept children, and the remaining children PR straight to
`main`. Decided by the maintainer, 2026-10-09:

- Land now rather than keep collecting on the line branch, because questline
branches are retiring ([Flat questlines](/quest/m1/quest-flat-lines.md)) and
each `main` merge meant hand-porting moq-ffi changes onto moved code.
- Children PR directly to `main`, so moving a binding layer does not require
hand-porting concurrent moq-ffi changes onto a separate line branch.
- The bindings still break once per release, not once per merge: binding
releases (moq-ffi and the Python, Go, Swift, Kotlin, Dart, and C++
packages) wait until [Codecs](/quest/m1/ffi-shape/codec.md) merges
Expand Down Expand Up @@ -59,7 +58,9 @@ Settled shape:
hand-written moq-c is out of scope: the
[generated C](/quest/m1/c/README.md) and C++
bindings inherit this shape from moq-ffi, so reshaping the hand-written C
ABI would break C users twice.
ABI would break C users twice. The narrow
[claim-epoch correctness exception](/quest/m1/claim-answer-epochs.md) does
not expand this layer reshaping to the hand-written ABI.
- `rs/moq-ffi/AGENTS.md` records the per-language namespace pattern `json`
set.

Expand Down
71 changes: 0 additions & 71 deletions quest/m1/quest-flat-lines.md

This file was deleted.

9 changes: 6 additions & 3 deletions quest/m1/stats/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
`rs/moq-audio/src/playback` is already counted privately.
- `moq-cli` folds the counters into `hang::stats::Snapshot` on the stats
interval and writes it through `moq_json::snapshot`, with the `.z` sibling.
A TS import flattens `ts::stats::Snapshot` in as `mpegts`, and a TS
export flattens its egress counters into `.echo` the same way. `transport` comes from
the connection's `ConnectionStats`.
`transport` comes from the connection's `ConnectionStats`.
Decided in the quest audit: this quest owns generic per-rendition reporting;
[TS health stats](/quest/m2/ts-health-stats.md) owns serializing and flattening
TS container counters under `mpegts` in publisher stats and export `.echo`.
That integration stays in m2 so this quest does not duplicate its work.
- Feedback: after reading a catalog with an `echo` section, the player
resolves the echo path against the broadcast, appends `<name>.echo`, and
publishes there with the fixed feedback
Expand All @@ -53,4 +55,5 @@

## Related

- [TS health stats](/quest/m2/ts-health-stats.md) - adds TS-specific counters after this generic reporting plumbing lands
- [Encrypted native CLI](/quest/m1/e2ee/cli.md) - refuses stats and feedback on an encrypted broadcast
7 changes: 4 additions & 3 deletions quest/m1/tstd/mux-overhead.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ Decided 2026-10-12:
into one PES while the PES fits the PID's B, timed by the first frame's
PTS. This applies to every audio stream the export frames (AAC, MP2, AC-3,
E-AC-3), not only DVB AC-3.
- Land after [#5363](https://github.com/moq-dev/moq/pull/5363), which reworks
the DVB AC-3 framing this packs.
- [#5363](https://github.com/moq-dev/moq/pull/5363) landed the DVB AC-3 framing
this packs. Video leak accounting must land first too, so the full-rate
proof covers every part of #5362 before this quest closes it.
- Test: a generated CBR source with no nulls, at the source's own
`--mux-rate`, exports for the whole clip and passes the strict T-STD check.

## Closes

- [#5362](https://github.com/moq-dev/moq/issues/5362) - a full-rate CBR contribution feed exports at its own rate

## Related
## Required

- [TS export admits video at its full leak](/quest/m1/tstd/video-leak.md) - #5362 point 2
Loading
Loading