Skip to content

stitcher-moq: client on moq-tokio 0.19.20 (moqt-22), moq-dev-rs adapter fix for moq-relay 0.15, registry refresh - #134

Merged
englishm-cloudflare merged 6 commits into
englishm:mainfrom
riedlse:stitcher-moq-moqt22-client
Oct 2, 2026
Merged

englishm-cloudflare merged 6 commits into
englishm:mainfrom
riedlse:stitcher-moq-moqt22-client

Conversation

@riedlse

@riedlse riedlse commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Paramount's relay has run moq-relay 0.15.x since 2026-09-24 (0.15.8 since 09-28). It negotiates moqt-22, the Seattle target, as well as -20/-18. This PR brings the runner's side along.

  1. Our embedded test client moves off moq-native 0.19 to crates.io moq-tokio 0.19.20 / moq-net 0.3.8, the moq-relay 0.16.0 release train. It now offers MoQT drafts 14–22 and no moq-lite. With the old client, every moq-dev relay negotiated moq-lite-05, so the IETF path was never tested. The new crates also carry fix(net): accept EXPIRES in SUBSCRIBE_OK, PUBLISH_OK, and REQUEST_OK moq-dev/moq#4195: moq-net no longer refuses the EXPIRES parameter that libquicr and aiomoqt send in SUBSCRIBE_OK.
  2. The moq-dev-rs relay adapter follows 0.15's renamed settings. moqdev/moq-relay:latest refuses the old MOQ_SERVER_* names at startup, which is why every docker cell against it is red today. MOQ_AUTH_PUBLIC=** replaces the empty root value.
  3. Tests 5 and 6 now need evidence that the relay routed the SUBSCRIBE. moq-net resolves an IETF subscribe locally before SUBSCRIBE_OK, so the old tests passed before any round trip. Also in this change:
    • discovery uses the test namespace as its SUBSCRIBE_NAMESPACE prefix, not the empty prefix draft-14 forbids;
    • test 6 settles on the relay's namespace snapshot, and a clean REQUEST_ERROR passes;
    • teardown closes the subscriber first;
    • the client flushes its CONNECTION_CLOSE before exiting.
  4. Our registry entry lists draft-21/-22 and describes the relay we run.
  5. The client lists all seven tests. The new rendezvous-timeout reports SKIP not implemented, because moq-net 0.3 can't put RENDEZVOUS_TIMEOUT on a SUBSCRIBE.

Tested with this repo's run-interop-tests.sh --client stitcher-moq, old image against new on this branch. That covers every registered relay, docker and remote, except the four whose images we couldn't build locally (aiomoqt-relay ×2, moqx and moxygen docker).

  • The result is 13 → 18 passing of 31, with no regressions.
  • Newly passing: imquic moqt, libquicr moqt, moq-go, and moxygen on both transports.
  • moq-dev-rs ×3 go green through item 2.
  • Every remaining red cell was re-run three times and fails the same way with the old client.

After merge, ghcr.io/englishm/moq-interop-runner-stitcher-moq-client:latest needs a rebuild from builds/stitcher-moq; the nightly still runs the 2026-09-11 image.

…oqt-22)

The embedded client was built on crates.io moq-native 0.19, moq-dev's pre-0.15 line, which
cannot negotiate MoQT draft-22 (the Seattle interop target). Port it to moq-tokio 0.19.14 /
moq-net 0.3.2 — the stack Paramount's relay and publisher run since 2026-09-24:
connect::Config (tls.insecure, one dial per test), origin::spawn(), explicit announce()
once the broadcast and track exist, unannounce() for publish-namespace-done, and
routed_broadcast() for the announcement waits.

Two behavior changes, both about testing what the name says:
- The default offer is MoQT drafts 22..14 only. The old client offered moq-lite first, so
  against moq-dev relays (ours, cdn.moq.dev) it negotiated moq-lite-05 and those "passing"
  cells exercised nothing IETF. MOQ_CLIENT_VERSION still overrides the offer.
- subscribe-error reports "# SKIP" when moq-net answers the request locally (unroutable: no
  announced route covers the path) — as moq-dev's own runner client does — instead of
  claiming a relay REQUEST_ERROR that never happened. The old client passed it the same
  local way. subscribe-before-announce keeps passing but its outcome now says what it
  exercises: the late announce reaching an already-connected subscriber, then SUBSCRIBE_OK.
…pter

docker.io/moqdev/moq-relay:latest moved to the 0.15 line on 2026-09-23/24, which renamed
MOQ_SERVER_BIND / MOQ_SERVER_TLS_CERT / MOQ_SERVER_TLS_KEY to MOQ_LISTEN* and refuses to
start while an old name is set — so every `-> moq-dev-rs docker` cell has been red since
(0/18 on 2026-09-25). MOQ_AUTH_PUBLIC now takes moq-pattern globs, where `**` means
everything; the old empty value no longer does.

Verified with the compose harness: the adapter built FROM moqdev/moq-relay:0.15.3 with these
four settings starts and scores 66/4 across 13 client cells, identical to a stock 0.15.1 relay.
Paramount's relay has run moq-dev moq-relay 0.15.1 since 2026-09-24 and negotiates moqt-22
(verified from outside with the ported client: moq-transport-22, 6/6 cases). Add draft-21 and
draft-22, and replace the stale v0.14.15 notes: the relay now sits behind a moq auth serve
sidecar with the same anonymous posture, and the client target offers MoQT drafts only and
reports subscribe-error as SKIP when moq-net cannot put the SUBSCRIBE on the wire.
moq-net accepts an IETF subscription locally, before SUBSCRIBE_OK, because
objects can outrun the reply. So announce-subscribe and
subscribe-before-announce used to pass before the SUBSCRIBE had made a round
trip, against any relay. Both now pass only once the relay has routed the
SUBSCRIBE to this client's own publisher and no REQUEST_ERROR followed. An
abort that is not a REQUEST_ERROR (for example an answer that did not
decode) is reported as a local failure, not as a relay rejection.

Subscriber origins are scoped to the namespace under test, so namespace
discovery sends SUBSCRIBE_NAMESPACE with that prefix instead of the empty
prefix. Draft-14 forbids the empty prefix, and several relays reject it or
answer it without the namespaces already published.

subscribe-before-announce waits for the relay's namespace snapshot, over a
window sized from the measured RTT, before checking that nothing resolves.
A stale covering route is noted in the outcome instead of failing the test,
and a clean REQUEST_ERROR passes, as the spec allows.

Sessions now close subscriber first. The process also gives its last
CONNECTION_CLOSE time to go out before exiting. Without that, a relay still
holding the dead publisher session routed the next run's SUBSCRIBE to it:
6 of 8 back-to-back runs failed against moqt-nr without the pause, and 8 of
8 passed with it.

announce-only and publish-namespace-done now report what is observable:
moq-net surfaces no PUBLISH_NAMESPACE_OK.
…and end broadcasts with close()

0.19.20 is the moq-relay 0.16.0 release train (2026-09-30). It carries moq-dev #4195: moq-net
no longer refuses an EXPIRES parameter in SUBSCRIBE_OK, which libquicr and aiomoqt publishers
send. broadcast::Producer::finish() is deprecated since #4031 ("a broadcast end carries no
cause"), so publish-namespace-done ends its broadcast with close(); clippy -D warnings is clean.

The registry entry now names the relay Paramount runs (moq-relay 0.15.8), its one-element
moq-test/interop publish grant, and the client's crates.
The runner's inventory now has seven tests (docs/tests/README.md). rendezvous-timeout wants a
SUBSCRIBE carrying RENDEZVOUS_TIMEOUT; moq-net 0.3 decodes that parameter but its subscribe API
cannot send one, so the client reports `ok 5 - rendezvous-timeout # SKIP not implemented: ...`
(the interface's SKIP directive) instead of running it without the parameter, which would only
repeat subscribe-error. --list now prints all seven names in the inventory's order.
@riedlse
riedlse force-pushed the stitcher-moq-moqt22-client branch from 8fa5492 to af0a4ca Compare October 2, 2026 14:16
@englishm-cloudflare
englishm-cloudflare merged commit bc0100b into englishm:main Oct 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants