Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3c1b809
chore(quest): claim quest/m1/ietf-drop/d14-17.md
kixelated Oct 25, 2026
47ffd18
wip(net): drop moq-transport drafts 14-17 from the moq-net library
kixelated Oct 25, 2026
346955b
wip(net): compile moq-net tests without drafts 14-17
kixelated Oct 25, 2026
386d366
wip: drop drafts 14-17 from the relay, tooling and CI lanes
kixelated Oct 25, 2026
f63daba
wip(relay): draft-18 raw SETUP in the token tests
kixelated Oct 25, 2026
33994a6
wip(net): sweep draft 14-17 residue from comments and tests
kixelated Oct 25, 2026
6875a99
fix(net): keep the moql SETUP on draft-14's u16 size
kixelated Oct 25, 2026
c85fe40
feat(net)!: drop moq-transport drafts 14 through 17 from @moq/net, in…
kixelated Oct 25, 2026
86d747d
fix(test): typecheck interop helpers and lint the single-draft confor…
kixelated Oct 25, 2026
2036e94
test(net): keep the anonymous split-horizon dial on moq-lite-01
kixelated Oct 25, 2026
1c8a6df
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 25, 2026
b7a421a
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 25, 2026
906cbbd
chore(quest): size the ietf-drop parent now that its children landed
kixelated Oct 25, 2026
d0ab85a
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Oct 25, 2026
c503e05
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 25, 2026
5d6d06f
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 25, 2026
fc8685c
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 25, 2026
9204b01
quest: leave the request-ID history decision in d14-17
kixelated Oct 25, 2026
45060e7
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Oct 25, 2026
98ee1b7
fix(moq-net): track only the peer's highest request ID
kixelated Oct 25, 2026
d7b81ea
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 26, 2026
a33e174
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 26, 2026
af43f0b
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 26, 2026
0cffdd7
quest: narrow the remaining quests to drafts 18 and 22
kixelated Oct 26, 2026
29d33cd
docs(moq-net): separate the drafts 14-17 migration entry
kixelated Oct 26, 2026
1cd9471
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 26, 2026
400f1ff
quest: narrow newly landed quest text to drafts 18 and 22
kixelated Oct 26, 2026
3489720
fix(test): run the moxygen conformance cells without a single-draft loop
kixelated Oct 26, 2026
b572b50
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 26, 2026
1507094
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
a2958eb
fix(net): drop the merge's unused helpers
kixelated Oct 27, 2026
8879669
test(tokio): stall the reply SETUP defers, offering lite-02
kixelated Oct 27, 2026
0f05029
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
af015ed
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
f96b825
Merge remote-tracking branch 'origin/main' into d14-17-land-abd8
kixelated Oct 27, 2026
51b8d7e
style: format the merge
kixelated Oct 27, 2026
bab07ce
quest: name only draft 18 in the relative-filter note
kixelated Oct 27, 2026
8b91970
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
59cafd5
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
4641e52
test(ffi): show a token nothing carries on moq-lite-06
kixelated Oct 27, 2026
69a9a88
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
a37e947
Merge remote-tracking branch 'origin/main' into d14-17-land-abd8
kixelated Oct 27, 2026
fcaa59f
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
db6606c
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
0d22fda
fix(net): yield while skipping a fetch payload
kixelated Oct 27, 2026
0b71d54
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
f9da34f
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
5c272c3
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
65f6db2
docs(net): name draft 18 where comments said draft-17+
kixelated Oct 27, 2026
c6268a7
test(net): expect the moql SETUP's own type error after #6905
kixelated Oct 27, 2026
641c41e
Merge origin/main into quest/m1/ietf-drop/d14-17
kixelated Oct 27, 2026
ea45122
Merge origin/main into drop-d14-17
kixelated Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/interop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
nix develop --command just test interop "${args[@]}"
shell: bash -leo pipefail {0}
env:
INTEROP_ARGS: ${{ github.event_name == 'pull_request' && '--publishers rust --subscribers rust,js-native-node,js-native-bun --versions moq-transport-14,moq-transport-22' || '--all --versions ietf' }}
INTEROP_ARGS: ${{ github.event_name == 'pull_request' && '--publishers rust --subscribers rust,js-native-node,js-native-bun --versions moq-transport-18,moq-transport-22' || '--all --versions ietf' }}
HARNESS_RUNS: ${{ runner.temp }}/moq-test-runs
HARNESS_RESULTS: ${{ runner.temp }}/moq-test-runs/results.jsonl

Expand Down
4 changes: 2 additions & 2 deletions doc/bin/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ rtsp` one per RTSP session, and `import ts --program all` one per program.
A restarted process takes the name at once: viewers see the broadcast restart,
and their next subscribe reaches the new run instead of waiting for its group
numbers to catch up. Epochs cross a connection only on moq-lite 07, which is
opt-in, and on moq-transport draft 17 and later, and order by the host's clock
opt-in, and on moq-transport, and order by the host's clock
there, so a host whose clock runs behind the old run's waits for it to close.
Other versions carry no epoch, so a restart from another session is the newest
route at an equal cost, or a better one.
Expand Down Expand Up @@ -484,7 +484,7 @@ the break. A stitch waits for the replacement's first catalog snapshot until it
arrives or the replacement goes, keeping the old publisher playing meanwhile,
so even the default `--follow 0s` switches to a replacement that is still
starting. Without `--stitch` the export stays on the old publisher while it is
up. Only lite-07 and moq-transport draft 17+ sessions carry epochs, so on the
up. Only lite-07 and moq-transport sessions carry epochs, so on the
default version every return is a replacement. A failure other than the
publisher leaving, such as a codec TS cannot carry, exits 1 at once. Only `ts`
can mark a break, so the other formats refuse `--linger`, the released spelling
Expand Down
2 changes: 1 addition & 1 deletion doc/bin/gstreamer.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ unknown versions fail startup. QUIC durations are milliseconds, with zero
disabling the local idle timeout or keep-alive.
Each run from `READY` publishes under a fresh
[publisher epoch](/concept/moq-lite#publisher-epochs), so on moq-lite 07 (opt-in)
or moq-transport draft 17 and later, viewers switch to a restarted pipeline at once instead of stalling on the old
or moq-transport, viewers switch to a restarted pipeline at once instead of stalling on the old
one; reconnects within a run keep it. The first catalog waits for a timed buffer
to place the shared wall clock and for every requested pad to negotiate its
rendition, including any codec config carried in its first buffers. A linked pad
Expand Down
2 changes: 1 addition & 1 deletion doc/bin/obs.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Enter a relay URL explicitly. On the shared anonymous relay, use a unique path
such as `https://cdn.moq.dev/anon/your-stream`. A URL with `?jwt=` fills the
token field. Editing the token while live presents the new one without
reconnecting, on a session that carries in-band authorization: a
`moq-transport` draft-17 or later version pinned under Advanced settings, with
`moq-transport` draft-18 or later version pinned under Advanced settings, with
a relay that negotiates the MoQ Auth extension. The default protocol does not
yet, so there the dock reports the new token as refused and it applies on the
next reconnect or Go Live.
Expand Down
2 changes: 1 addition & 1 deletion doc/bin/relay/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ key can itself be **scoped** at generation (`--root`, `--publish`,

### In-band renewal

On moq-lite-07-wip or moq-transport draft-17 and later with MoQ Auth negotiated,
On moq-lite-07-wip or moq-transport draft-18 and later with MoQ Auth negotiated,
a client can present another JWT without reconnecting. Present its replacement
before the current grant expires and keep the returned token handle alive.
The auth handle a reconnecting connection owns (native `Connection::auth()`,
Expand Down
11 changes: 3 additions & 8 deletions doc/bin/relay/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ Each broadcast carries the list of relays it passed through. That hop list
catches loops and picks the shortest route, and every relay breaks ties the
same way so the cluster converges instead of flapping. Both wire protocols
carry it: natively on moq-lite, and via the [cluster extension](/draft/moq-cluster)
on moq-transport 17+.

moq-transport drafts 14 and 15 cannot ask for every broadcast (an empty
namespace prefix is illegal before draft 16), so a link to a peer without the
MoQ Solicit extension, such as moxygen, learns only what that peer announces
unasked. moxygen announces nothing unasked on draft 14.
on moq-transport.

A track from a moq-transport publisher keeps its Object IDs, object properties,
and END\_OF\_GROUP status objects across a moq-lite-07 link, since relays
Expand All @@ -44,7 +39,7 @@ resuming it; the RTMP, SRT, and WHIP ingests mint one per connection. Epochs
order by creation time, so a reconnect to a different gateway assumes the two
gateways' clocks roughly agree. Seamless failover needs a publisher that
announces an epoch and, on every link the route crosses, moq-lite 07 or
moq-transport draft 17 or later with the [epoch extension](/draft/moq-epoch). A route
moq-transport with the [epoch extension](/draft/moq-epoch). A route
without an epoch, including every route on moq-lite 06 and older or a
moq-transport link without the extension, keeps its subscriptions until it goes or a track fails
upstream, and any other route winning it is announced as a restart. Viewers
Expand Down Expand Up @@ -100,7 +95,7 @@ max_hops = 6
```

The same setting is `--cluster-max-hops` or `MOQ_CLUSTER_MAX_HOPS`. It covers
moq-lite-03 through moq-lite-07-wip and moq-transport drafts 17 through 22 when
moq-lite-03 through moq-lite-07-wip and moq-transport drafts 18 through 22 when
the MoQ Cluster extension is negotiated. A forwarded path counts this relay's
own hop even when its peer appends it on receipt. Older versions and peers
without hop paths hide their depth, which this setting cannot bound.
Expand Down
17 changes: 6 additions & 11 deletions doc/bin/relay/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ allow.uid = [1001]

[listen.extensions] # moq-transport SETUP extensions to offer, each on by default.
# The relay always offers ietf, for moq-lite-07 relay links.
auth = false # Decline MoQ Auth (draft 17+).
auth = false # Decline MoQ Auth.
solicit = false # Decline MoQ Solicit, so peers may announce unasked.
epoch = false # Decline MoQ Epoch, so routes over moq-transport carry no epoch (draft 17+).
epoch = false # Decline MoQ Epoch, so routes over moq-transport carry no epoch.
```

`timeout` bounds the whole handshake, transport through MoQ SETUP and auth
Expand Down Expand Up @@ -127,11 +127,9 @@ certificate, route hop, or cluster-looking URL alone does not select peer limits
```toml
[limits.client]
announces = 1000 # Simultaneous broadcasts or namespaces.
requests = 10000 # Other simultaneous moq-transport requests.

[limits.peer]
announces = 100000
requests = 20000

[limits.peer.quic]
max_streams = 100000 # Concurrent QUIC streams per direction.
Expand All @@ -147,13 +145,10 @@ not throttled by `[quic]` limits sized for one viewer, for example
`--limits-peer-quic-max-streams=200000`. Peers over WebSocket, TCP, or iroh keep
their transport's own limits.

These are the defaults. Each subscription and FETCH holds a stream on moq-lite
and on moq-transport draft 17 and later, as does each PUBLISH a peer's track
listing gets, so `[quic]` or `[limits.peer.quic]` `max_streams` bounds them
there, and a peer past it waits rather than fails.
On drafts 14 to 16, `announces` and `requests` together size the request
window instead, which every request counts against, so very small values can
prevent other requests from progressing. Size peer limits
These are the defaults. Each subscription and FETCH holds a stream, as does each
PUBLISH a peer's track listing gets, so `[quic]` or `[limits.peer.quic]`
`max_streams` bounds them, and a peer past it waits rather than fails. The
removed `requests` limit is refused at startup. Size peer limits
for the combined traffic they carry, and use session peak counters to check
announcement and subscription headroom. Exceeding `announces` closes the session
with `TOO_MANY_REQUESTS`; reconnecting with the same load will exceed it again.
Expand Down
21 changes: 10 additions & 11 deletions doc/concept/moq-lite.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ against any moq-transport relay (including
implement in an afternoon. The wire spec is
[draft-lcurley-moq-lite](/draft/moq-lite).

Rust and TypeScript speak moq-lite 01 through 06 and moq-transport drafts 14
Rust and TypeScript speak moq-lite 01 through 06 and moq-transport drafts 18
through 22. Clients offer `moq-lite-06` first. moq-lite 07 is still in progress
(`moq-lite-07-wip`, and only when both sides enable it). It is the version that
carries [publisher epochs](#publisher-epochs).
Expand Down Expand Up @@ -132,11 +132,11 @@ authorization and hidden names work exactly as without one.
of the old instance, so a new subscriber never sees its cached groups.

The epoch and the restart message travel on moq-lite 07, which is opt-in.
moq-transport carries the epoch from draft 17 when both sides offer the [epoch
moq-transport carries the epoch when both sides offer the [epoch
extension](/draft/moq-epoch), on by default. A restart onto another epoch is
advertised before the old one is withdrawn, so the path is never absent, and one
that gains or loses an epoch is an end then a start. Older moq-lite versions,
older moq-transport drafts, and a side that declines the extension carry no
that gains or loses an epoch is an end then a start. Older moq-lite versions
and a side that declines the extension carry no
epoch. Without an epoch, any other route winning is a restart, even a reconnect
over the same path, since nothing says it serves the same bytes. A peer that
ignores the end and start may keep cached objects of the old run under the same
Expand All @@ -158,7 +158,7 @@ compared. A subscription uses the preferred link that has a route and moves to t
next when that route goes; a publisher pushes the same broadcast to every CDN.

The move resumes without a seam only between routes with the same epoch, which
needs moq-lite 07, or moq-transport draft 17 or later with the epoch extension,
needs moq-lite 07, or moq-transport with the epoch extension,
on both links. A CDN link that carries no epoch makes moving onto it, or back
off it, a restart, and the player requests the path again. Both links must
also speak the same protocol and draft: a copy's track info records the
Expand Down Expand Up @@ -231,13 +231,12 @@ code and the session stays up. A client that publishes outside its grant closes
the session with `UNAUTHORIZED`, naming the path. A session whose last
credential expires closes with `EXPIRED_AUTH_TOKEN` instead: refresh the token
and reconnect, rather than treating the credential as invalid. moq-transport carries the same
exchange on draft-17+ through the [MoQ Auth extension](/draft/moq-auth), with
exchange through the [MoQ Auth extension](/draft/moq-auth), with
the same patterns. Older versions have no grant; the URL token keeps working
everywhere. On moq-transport an added token is kept even without the extension,
so an announcement can name it: it rides that `PUBLISH_NAMESPACE` as its
authorization token. Naming a fresh token renews the announcement in place with
`REQUEST_UPDATE` from draft 16, and re-announces it on drafts 14 and 15, so it
can outlive the token it started with. A token added to a reconnecting
`REQUEST_UPDATE`, so it can outlive the token it started with. A token added to a reconnecting
connection's auth handle is presented on every session it makes, so the
announcement keeps it across a reconnect with no re-add or re-announce; one
added to a single session's handle ends with that session. moq-lite has no
Expand Down Expand Up @@ -292,9 +291,9 @@ moq-lite-07 carries range by range and older wire versions as the single span
covering them. A relative or time anchor resolves on the hop that publishes the
track, and over moq-lite-07, which carries a relative or time start upstream and
reports the live edge and media time, so a copy resolves the ends itself. A Rust
moq-transport copy on draft 17 and later accepts anchors its cache can already
moq-transport copy accepts anchors its cache can already
resolve and sends group bounds upstream; it refuses an unknown time end. Older
wires accept absolute anchors but refuse time anchors and relative anchors other
moq-lite versions accept absolute anchors but refuse time anchors and relative anchors other
than the live and default starts. An untimed track refuses a time anchor. At the live
edge, a time end
may let one group through before its first frame shows it starts past the end:
Expand All @@ -320,7 +319,7 @@ across its subscribers.
A track is timed or untimed: it declares a timescale or none, and a frame that
doesn't match is refused. No receiver fills in an arrival time, so an untimed
track is judged by the wall clock alone. Tracks from moq-lite before 05, or from
moq-transport without a `TIMESCALE` (every track on drafts 14-16), arrive
moq-transport without a `TIMESCALE`, arrive
untimed. moq-lite 05 and 06 cannot declare an untimed track, so there its
frames go out stamped with their send time; the work-in-progress 07 carries it
untimed.
Expand Down
Loading
Loading