moq-lite-05: sync wire with drafts HEAD (SETUP stream, broadcast epoch, drop cache hint, rename ANNOUNCE)#1847
Merged
Merged
Conversation
…, add broadcast epoch, rename ANNOUNCE) Brings the moq-lite-05 (Lite05Wip) wire and naming in line with the two latest drafts commits: - #34: remove the Publisher Cache hint from TRACK_INFO. Retention is now a best-effort cache, not a guaranteed minimum, so the field no longer rides the wire. The local retention window (model TrackInfo.cache) stays and falls back to DEFAULT_CACHE on the subscriber. - #35: rename ANNOUNCE -> ANNOUNCE_BROADCAST and ANNOUNCE_INTEREST -> ANNOUNCE_REQUEST (wire names only; stream/message IDs unchanged), and add a per-broadcast Epoch. The epoch is carried end-to-end: BroadcastInfo.epoch is a SystemTime defaulting to now (the instant the instance was created), encoded on the wire as milliseconds since 2020-01-01 UTC. The origin's route selection now prefers the newer instance (larger epoch) among equal-length routes, then falls back to the existing deterministic hash tie-break, so a cluster still converges. Shortest hop chain still wins first to preserve routing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
…fts #26/#27) Adds the lite-05 SETUP message exchanged on a unidirectional Setup Stream (DataType::Setup = 1). Each endpoint opens the stream once, sends a single SETUP advertising its capabilities, and FINs. The two SETUPs are independent: neither side blocks on the peer's before opening other streams. - #26: SETUP message + negotiated Probe capability levels (None/Report/Increase). The SETUP body reuses the parameter framing (Parameters gained typed varint/ bytes accessors). The subscriber now gates opening a PROBE stream on the peer having advertised Probe >= Report in its SETUP; unknown future levels saturate to Increase. Older versions have no Setup Stream and keep probing unconditionally. - #27: Path Setup Parameter for URI-less transports. Client::with_path sets the request path advertised in the client's SETUP (native QUIC / qmux over TCP/TLS); servers never send one. The peer's SETUP (incl. path) is decoded and recorded; wiring the received path into relay routing is left for a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
…ort cache Aligns doc/concept/layer/moq-lite.md with the drafts #26/#27/#34/#35 sync: - SETUP now advertises per-endpoint capabilities (e.g. bitrate probing) and, on URI-less transports, the request path. The two SETUPs are independent. - Broadcasts carry an epoch so duplicate/republished advertisements converge on the newest instance. - The per-track cache is described as a best-effort local retention window, no longer announced on the wire (it previously referenced the removed SUBSCRIBE_OK field). Also drops the stale per-hop wording in line with drafts #28. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
Browser-side counterpart to the Rust lite-05 SETUP work, required for browser<->relay interop now that each endpoint exchanges a SETUP on a uni stream (DataType.Setup = 1): - New lite/setup.ts: ProbeLevel (None/Report/Increase, unknown saturates to Increase) and a size-prefixed Setup message over a private Parameters bag (varint count + id/length/value triples), gated to DRAFT_05_WIP+. - On lite-05 session start the connection sends our SETUP (probe = Report; path undefined, since WebTransport carries the URI), decodes the peer's SETUP in the uni dispatch, and threads it to the Subscriber. - runProbe() now waits for and gates on the peer's advertised probe level on lite-05+; older drafts probe unconditionally as before. (Written by Claude) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
kixelated
pushed a commit
that referenced
this pull request
Jun 21, 2026
dev advanced 3 commits while this PR was open (#1845 PTS-exposing TS Export + PCR-paced SRT egress, #1847 moq-lite-05 wire sync, #1819 always-on hardware encoders). Re-merged dev and reconciled two conflicts: - nix/overlay.nix: kept this PR's cargo+sccache CI direction (dev's tip still carries the crane `moqChecks`; the cargo switch lives on main, #1821). - rs/moq-mux/src/container/ts/export.rs: combined dev's #1845 Frame-returning `Export::next` (PTS/keyframe-stamped) with this PR's generic `catalog::Catalog` trait (main's #1815 mpegts rename). Updated the moq-cli drain helper to read `frame.payload` and refreshed two stale `scte35::Ext` comments. Verified: moq-mux (279), moq-cli, moq-srt tests pass; workspace clippy -D warnings and fmt clean (excluding the crates that need libva/gstreamer system libs unavailable in this sandbox: moq-video/libmoq/moq-boy/moq-gst); JS type-checks and biome clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BQ9o9paZnRLpYRgbyjUwFV
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs the
moq-lite-05(Lite05Wip/DRAFT_05_WIP) implementation with the latest commits on moq-dev/drafts, across Rust (rs/moq-net), TypeScript (js/net), and the concept docs. All wire changes are gated to lite-05+; older drafts are unaffected.Drafts covered
What changed
#35 — Broadcast Epoch + ANNOUNCE renames
ANNOUNCE→ANNOUNCE_BROADCAST,ANNOUNCE_INTEREST→ANNOUNCE_REQUEST. Rust typesAnnounce/AnnounceInterestand the JSAnnounce/AnnounceInterestclasses renamed to match (both internal to the privatelitemodule / package surface).BroadcastInfo.epochis aSystemTimedefaulting tonow()(the instant the instance is created), encoded on the wire as milliseconds since 2020‑01‑01 UTC (a varint after the suffix, before the hop chain). JS represents it as the same ms‑since‑2020 number.route_key) now prefers the newer instance (larger epoch) among equal‑length hop chains, then falls back to the existing deterministic hash tie‑break. Shortest hop chain still wins first, preserving routing; the epoch and hops are forwarded unchanged so a cluster still converges.#34 — Remove the Publisher Cache hint
cacheduration is gone from the TRACK_INFO wire message. Retention is now best‑effort, not a guaranteed minimum. The local retention window (model::TrackInfo.cache) stays and falls back toDEFAULT_CACHEon the subscriber.#26 / #27 — SETUP stream
DataType::Setup = 1). Each endpoint opens it once, sends a single SETUP message advertising its capabilities, and FINs. The two SETUPs are independent (neither side blocks on the peer's before opening other streams).None/Report/Increase; unknown future levels saturate toIncrease). The subscriber now only opens a PROBE stream if the peer advertisedProbe >= Report. Older versions keep probing unconditionally.Client::with_path(Rust) sets the path advertised in the client's SETUP; servers never send one. The peer's SETUP (incl. path) is decoded and recorded.Parametersbag gained typed varint/bytes accessors in Rust; a private mirror in JS).#28 + concept docs
doc/concept/layer/moq-lite.mdupdated: SETUP capabilities + URI‑less path, broadcast epoch convergence, and the cache reframed as a best‑effort local window (it previously referenced the removedSUBSCRIBE_OKfield).Cross-package sync
rs/moq-net↔js/net: mirrored (announce/track wire, the SETUP stream, probe gating). Browser↔relay interop is preserved now that both ends exchange a Setup uni stream.doc/concept: updated as above.Not in scope (follow-up)
js/nethas no multi-route origin tree, so the epoch tie-break is Rust-only there (the JS side decodes the epoch but has nothing to dedup).Test plan
cargo test -p moq-net --lib— 396 passedcargo test -p moq-relay --lib— 123 passedcargo checkonhang,moq-relay,libmoq,moq-ffi,moq-mux,moq-benchcargo clippy -p moq-net— clean;cargo fmtcd js/net && bun test— 189 passed;bun run check(tsc) +biome checkcleanOne design point worth a reviewer's eye: the epoch as
SystemTime-now meansBroadcastInfo::new()stamps the current wall clock, so two locally-created broadcasts at the same path now resolve by creation time (newer wins) rather than purely by hash. Cross-route/relayed cases are unaffected (epoch is forwarded unchanged).🤖 Generated with Claude Code
https://claude.ai/code/session_0118VcLtfuukFERQ8ito5dUG
(Written by Claude)
Generated by Claude Code