Skip to content
Merged
15 changes: 9 additions & 6 deletions quest/m0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

## Goal

The work in flight now, in two independent tracks. Relay hardening: legal
moq-transport input never fails a session in current interop coverage, every resource a peer can make the relay hold is bounded by what
it sent or by a budget, and no peer input panics the process. Identity: nothing treats who published a route as what it carries; a path and
the epoch on its route are the only content identity, and every first-party
publisher that can restart mints a fresh epoch, so #4741 stalls nobody.
The work in flight now. Relay hardening: legal moq-transport input never fails
a session in current interop coverage, every resource a peer can make the
relay hold is bounded by what it sent or by a budget, and no peer input panics
the process. Identity: nothing treats who published a route as what it
carries; a path and the epoch on its route are the only content identity, and
every first-party publisher that can restart mints a fresh epoch, so #4741
stalls nobody. Alongside them: fixes for the `release` line, CI cost, and the
recurring audits.

## Plan

Expand All @@ -26,7 +29,7 @@ edge, which embeds moq-relay; it moved there on 2026-09-28.
Identity: the [broadcast epoch](/quest/m0/broadcast-epoch/README.md) line
gates the next release (decided 2026-10-03:
#4741 resumes an un-epoched republish into the old broadcast and stalls its
viewers). #4741 can merge to main, but no release ships until first-party
viewers). #4741 is on main, but no release ships until first-party
publishers mint epochs. Backport patches cut from `release` don't carry
#4741 and aren't gated (decided 2026-10-08).

Expand Down
4 changes: 0 additions & 4 deletions quest/m0/broadcast-epoch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,3 @@ End+Start. The child quests own their focused regressions.
## Required

- [Reference announcements](/quest/m0/broadcast-epoch/reference-announcements.md) - native readers restart a replaced referenced sibling on its announcements, never past a named epoch

## Related

- [JS consume identity](https://github.com/moq-dev/moq/pull/5254) - requests carry the serving prefix's epoch and new winners cannot reuse an old cached broadcast
18 changes: 11 additions & 7 deletions quest/m0/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,18 @@ Decisions (maintainer, 2026-10-13):
and run uncached.
- Decided 2026-10-19: the merge queue is trusted like `main`, since a queued
PR is about to land. Rust cache writers are the jobs on `main` and in its
queue, and no separate warm rebuilds what landed.
queue, and no separate warm rebuilds what landed. Since
[#6040](https://github.com/moq-dev/moq/pull/6040) the queue runs on the
self-hosted `moq-queue` runner with mbx's local store, so the R2 writers are
the hosted Nightly jobs on `main`.
- Self-hosted CI is dropped: hosted runners plus the R2 caches replace the
spare-desktop runner, its cache server, and the cache release it waited on.
Reopened 2026-10-19, conditionally: [faster runners](/quest/m0/ci/runners.md)
compares it again once the pipeline is optimized. Since 2026-10-20 the
queue runs on the persistent `nix/runner` VM; that quest records its
measurements.
Reopened 2026-10-19, conditionally, to compare runners once the pipeline
was optimized. Decided 2026-10-22 (maintainer): the queue runner is the
persistent `nix/runner` VM (no host mounts or tailnet, firewalled to public
egress), in use since 2026-10-20. Over 32 one-pass entries it took a median
5.5 minutes per merged PR (p90 11.9, at most 24.2) against 21 minutes on a
hosted runner, with no per-minute bill. Blacksmith is not pursued.

Decided 2026-10-15: local CPU admission, test-cost reductions, and setup
reductions are all m0. `quest gate` owns generic command admission; repositories
Expand All @@ -77,7 +82,6 @@ The historical samples locate candidates; they are not controlled benchmarks.

- [Require the release gate](/quest/m0/ci/release-gates.md) - condition: the next cut carries `release-gate.yml`; then release PRs require it
- [Share local check capacity](/quest/m0/ci/local-gate.md) - gate expensive phases and bound internal fanout
- [Verify the R2 Rust cache](/quest/m0/ci/mbx-r2-verify.md) - condition: the maintainer bootstrap; then measure hits, restore time, and expiry
- [Verify the R2 Rust cache](/quest/m0/ci/mbx-r2-verify.md) - condition: the maintainer bootstrap; then measure the hosted Nightly jobs' hits, restore time, and expiry
- [Verify the Nix cache](/quest/m0/ci/nix-cache-verify.md) - confirm CI and releases use `nix.moq.dev` and retire Cachix
- [First shared FFI release](/quest/m0/ci/nightly-ffi-reuse.md) - condition: the first `moq-ffi-v*` tag that runs `Release FFI`, and a `Shipping sizes` run; verify the wrappers and size keys
- [Faster runners](/quest/m0/ci/runners.md) - pick hosted, Blacksmith or the NixOS desktop from measurements of the optimized queue
41 changes: 23 additions & 18 deletions quest/m0/ci/mbx-r2-verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,33 @@

## Goal

Condition: the `mbx-moq-dev` bootstrap in `infra/README.md` is complete,
including the `cache-write` Environment's `gh-readonly-queue/main/*` branch
policy, and the merge queue has merged Rust changes since. Check it with
`gh run list --workflow check.yml --event merge_group`.

Then confirm the cache earns its keep, and record the numbers in the PR that
closes this:

- Each merge queue and `main` job's `Check the cache` step reports
`effective read-write`, and a release pull request's reports
`effective read-only`.
- The merge queue's Check show mbx remote hits for code the queued
pull request did not touch, and Nightly's macOS and Windows jobs hit what
the previous Nightly wrote.
Condition: the `mbx-moq-dev` bootstrap in `infra/README.md` is complete and
scheduled Nightly runs on `main` have built Rust since. Check it with
`gh run list --workflow nightly.yml --branch main`.

Then confirm the cache earns its keep for the hosted jobs that still use R2
(Nightly on `main`, release pull requests, and the macOS and Windows jobs),
and record the numbers in the PR that closes this:

- Each Nightly job's `Check the cache` step reports `effective read-write`,
and a release pull request's reports `effective read-only`.
- Nightly's Linux, macOS and Windows jobs hit what the previous Nightly
wrote.
- Restore plus build time against the 150-210s Actions restore of the ~6 GB
store it replaced, from the same diff before and after.
- Each object expires 30 days after upload, and the queue builds only what
its diff selects, so an expired crate stays cold until a queue or `main`
job builds it again. Count how often a queue entry pays that rebuild.
store it replaced, from the same commit before and after.
- Each object expires 30 days after upload, so a crate no Nightly builds in
that window stays cold for the next hosted job. Count how often a Nightly
job pays that rebuild.
- Bucket size and request counts after a month, against the 30-day expiry in
`infra/mbx/lifecycle.json`. Shorten or lengthen it from that.

## Plan

Decided 2026-10-22 (maintainer): narrowed to hosted jobs. Since
[#6040](https://github.com/moq-dev/moq/pull/6040) the merge queue runs on the
self-hosted `moq-queue` runner with mbx's local store, so it neither reads nor
writes R2.

## Related

- [Require the release gate](/quest/m0/ci/release-gates.md) - the macOS and Windows jobs this cache serves
Expand Down
45 changes: 27 additions & 18 deletions quest/m0/ci/nix-cache-verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,47 @@

## Goal

`nix.moq.dev` serves CI and releases: Nix jobs substitute the dev shell
instead of building it, release tags substitute on a clean machine, its
bucket sizes hold under the 30-day expiry, and Cachix is retired.
`nix.moq.dev` serves CI and releases: hosted Nix jobs enter the dev shell
without compiling it, release tags substitute on a clean machine, its bucket
sizes hold under the 30-day expiry, and Cachix is retired.

## Plan

[#5693](https://github.com/moq-dev/moq/pull/5693) wired `nix.moq.dev` into
CI. The maintainer ran the bootstrap in `infra/README.md` on 2026-10-19 and 2026-10-20 (the
release tag ruleset, both buckets and the Worker, the `cache-write`
Environment's tag policies and secrets, and the signing key). Check it with
`curl https://nix.moq.dev/nix-cache-info` and
`gh run list --workflow cache.yml --branch main`.
`curl https://nix.moq.dev/nix-cache-info`.

Decided 2026-10-22 (maintainer):
[#6040](https://github.com/moq-dev/moq/pull/6040) deleted `cache.yml`, so
nothing pushes the dev shell to `nix.moq.dev`; only `release-nix.yml` pushes,
on release tags. First measure one hosted Nightly job's dev-shell entry time,
no earlier than 2026-11-20: `cache.yml`'s last push to `nix.moq.dev` ran
2026-10-20, and those paths serve a warm entry until the 30-day expiry
removes them. If it still compiles `uniffi-bindgen-go`, `uniffi-bindgen-cpp` and `quest`
(the 12-14 minute baseline below), restore a dev-shell push. Otherwise this
narrows to release-tag substitution and Cachix retirement.

Then confirm it, and record the numbers in the PR that closes this:

- The first `main` warm pushes the dev shell, and a later merge queue or
Nightly job enters `nix develop` without compiling uniffi-bindgen-go. The
baseline, measured 2026-10-16 in Nightly run 38897397428: every workload
spent 12-14 minutes building `uniffi-bindgen-go`, `uniffi-bindgen-cpp` and
`quest` before entering the dev shell, because Cachix had no copy.
- A hosted Nightly job enters `nix develop` without compiling
uniffi-bindgen-go. The baseline, measured 2026-10-16 in Nightly run
38897397428: every workload spent 12-14 minutes building
`uniffi-bindgen-go`, `uniffi-bindgen-cpp` and `quest` before entering the
dev shell, because Cachix had no copy.
- The next `moq-relay-v*` or `moq-cli-v*` tag pushes from all three
`release-nix.yml` legs, and `nix run github:moq-dev/moq/<tag>#moq-relay
--accept-flake-config` substitutes on a clean machine.
- Dev shell upload time and both bucket sizes after a month, against the
30-day expiry in `infra/nix/lifecycle.json`. A path expires 30 days after
its upload even while CI still reads it, and only the next warm restores
it, which runs on a flake or `nix/**` change or a dispatch. Look for jobs
that fell back to source builds in that window. If they recur, add a daily
schedule to `cache.yml` (and alert on its scheduled failures) or switch to
a closure-aware collector (niks3).
- Both bucket sizes after a month, against the 30-day expiry in
`infra/nix/lifecycle.json`. A path expires 30 days after its upload even
while CI still reads it. If a dev-shell push is restored, look for jobs
that fell back to source builds once its paths expired, and refresh it on a
schedule or switch to a closure-aware collector (niks3) if they recur.
- Delete the `CACHIX_AUTH_TOKEN` secret and the `kixelated` Cachix cache once
the maintainer decides downstream flakes have had long enough to switch.
the maintainer decides downstream flakes have had long enough to switch,
along with `smoke.yml`'s Cachix substituter and its push step for the nix
channel.

## Related

Expand Down
43 changes: 0 additions & 43 deletions quest/m0/ci/runners.md

This file was deleted.

8 changes: 3 additions & 5 deletions quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ before those quests).
The moq-transport passthrough fields remain crate-private, the existing
explicit exception to the public model audit.

Added 2026-10-16: refresh, ranked after moq-transport passthrough, whose
dynamic-groups path it promotes. It is a breaking `Demand` change, so it
lands before the cut.
Added 2026-10-16: refresh, a breaking `Demand` change, so it lands before
the cut.

Added 2026-10-20 (maintainer): the probe target, native probing, and the
native rung disable moved up from the [m2 probe epic](/quest/m2/probe/README.md),
Expand Down Expand Up @@ -78,6 +77,7 @@ lite-07 stream type here.
- [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
- [Broadcast archives](/quest/m1/archive/README.md) - ANNOUNCE, TRACKS, and a SUBSCRIBE per track record every track under a prefix to any object_store, a host serves a stored broadcast back, and the catalog drops its archive pointer for an opt-in `hls` field
- [Compressed tracks](/quest/m1/compress/README.md) - a track flagged `compress` is DEFLATEd per group by moq-net, forwarded compressed, and inflated once on the relay for peers that cannot signal it; `catalog.json.z` and moq-flate go away
- [lite-06 max sequence](/quest/m1/lite06-max-sequence.md) - group sequence 2^62-1 reaches a lite-06 subscriber or is refused loudly, instead of vanishing
- [Finalize moq-lite-07](/quest/m1/lite07-finalize.md) - when the maintainer cuts it, lite-07 negotiates as `moq-lite-07` and the next release ships it
- [Moxygen minimal interop](/quest/m1/smoke-moxygen.md) - waiting on Moxygen to send a registered filter type, then the smoke lane stops hiding its failure
- [More tests under load](/quest/m1/test-flakes-2/README.md) - the second round of load-only failures, one quest per flake, fixed at the cause
Expand Down Expand Up @@ -105,14 +105,12 @@ lite-07 stream type here.
- [WebGPU on Safari](/quest/m1/webgpu-safari.md) - the WebGPU renderer is verified on Safari 26 for macOS and iOS
- [Interop finish](/quest/m1/interop-finish.md) - the interop matrix proves a clean broadcast finish across implementations
- [Exporters follow a rendition to a new track](/quest/m1/export-rendition-rebind.md) - the fMP4, TS, MKV and FLV exporters rebuild a rendition whose resolved `track` or `broadcast` changes under the same ID
- [lite-06 max sequence](/quest/m1/lite06-max-sequence.md) - group sequence 2^62-1 reaches a lite-06 subscriber or is refused loudly, instead of vanishing
- [Track live signal](/quest/m1/track-live.md) - a reader can wait for its track's feed to be live, so a player skips old cached groups while a fresh upstream subscription starts
- [moq-net compiles once](/quest/m1/net-erase-transport.md) - the session drivers stop monomorphizing per transport and per crate, saving several MiB of the relay, FFI library, `libmoq` and CLI
- [Audio devices on ARM](/quest/m1/audio-devices-arm.md) - `just rs audio-devices` passes on the hosted ARM runner
- [CI housekeeping](/quest/m1/ci-housekeeping.md) - validate queue nextest at 24 threads and remove the actionlint queue ignore after its release
- [Interop audio delivery](/quest/m1/interop-audio.md) - every interop subscriber decodes and checks the publishers' 440 Hz tone, and the Rust publisher sends Opus and AAC
- [Native audio decode conformance](/quest/m1/audio-decode-conformance.md) - Opus and AAC decode through every moq-audio backend, moq-c, and moq-ffi is checked against known tones and clips, like moq-video's suite
- [Allocation-free single-range subscriber window](/quest/m1/window-alloc.md) - a one-range subscribe resolves its window without a heap allocation, recovering the join cost per-subscriber ranges added
- [moq-net internals](/quest/m1/net-internals.md) - no per-group session clones, no transport type parameter in lite and IETF internals, and the `Local` check measured
- [Main is no slower than release](/quest/m1/release-perf/README.md) - every benchmark where main is slower than release is fixed or accepted with a reason, checked by a final paired run before the cut
- [Subscribe update churn](/quest/m1/subscribe-update-churn.md) - a viewer sends SUBSCRIBE_UPDATE only on a meaningful change, measured after the publisher stall fix
Expand Down
13 changes: 10 additions & 3 deletions quest/m1/audio-devices-arm.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ The recipe first ran nightly on 2026-10-20 and failed all five playback
tests on ARM; nothing owned it
([moq-dev/moq#6155](https://github.com/moq-dev/moq/pull/6155)).
[moq-dev/moq#6175](https://github.com/moq-dev/moq/pull/6175) then fixed
PulseAudio's 20 ms playback period for these tests. Check a nightly after
#6175 first: if ARM passes, delete this quest. Otherwise reproduce on ARM
and fix the cause, not the timing.
PulseAudio's 20 ms playback period for these tests.

But Nightly
[39600361153](https://github.com/moq-dev/moq/actions/runs/39600361153)
(2026-10-21, before #6175 merged) already passed all five on
`ubuntu-24.04-arm`, after the 2026-10-20 failure, with no moq-audio change
between. So a green nightly alone does not prove #6175 fixed it: the failure
may be intermittent. Decided 2026-10-22 (maintainer): delete this quest only
after three consecutive green Nightlies on ARM; on another failure, reproduce
on ARM and fix the cause, not the timing.

Public API: none. Wire: none.

Expand Down
3 changes: 1 addition & 2 deletions quest/m1/audio-jitter-target/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ native playback against its budgets.
## Required

- [Watch](/quest/m1/audio-jitter-target/watch.md) - the browser's measured target, proven on Chrome and Safari against the public relay
- [Capped budgets](/quest/m1/audio-jitter-target/capped-budgets.md) - post-cap nightlies confirm AAC bursty discards about as much audio as Opus bursty, and every browser row's budgets are re-measured from them
- [Opus near-zero budgets](/quest/m1/audio-jitter-target/opus-near-zero-budgets.md) - post-flush nightlies confirm the first row no longer stalls, and its budgets are tightened from them
- [Capped budgets](/quest/m1/audio-jitter-target/capped-budgets.md) - post-cap nightlies confirm AAC bursty discards about as much audio as Opus bursty and the first row no longer stalls, and every browser row's budgets are re-measured from them

## Closes

Expand Down
Loading
Loading