Skip to content

feat(lite): the ietf extension records provenance as the ingress version - #6107

Merged
kixelated merged 10 commits into
mainfrom
quest/m1/ietf-extension/lite
Oct 21, 2026
Merged

kixelated merged 10 commits into
mainfrom
quest/m1/ietf-extension/lite

Conversation

@kixelated

@kixelated kixelated commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Implements quest/m1/ietf-extension/lite, as decided in moq-dev/moq#6072. A track that crosses a lite-07 hop with the ietf extension now carries the moq-transport version it was published on once, in TRACK_PROPERTIES. Before this, every Property Block and TRACK_PROPERTIES carried its own Encoding code. A track published over moq-lite carries no version, and a peer cannot attach moq-transport state to it. Behavior across the hop is otherwise the same as in moq-dev/moq#6058.

  • Model: object::Encoding is deleted. object::Block is { bytes, immutable }. object::TrackProperties is { version: ietf::Version, values }. track::Info::properties is now Some for every track a moq-transport publisher published, even one with no properties, and None for a moq-lite track. New crate-private accessors are track::Info::ietf() and group::Consumer::ietf().
  • moq-transport egress reads the source version from the group's own track info, ietf::object::write(properties, source, ...). It applies the same single-relay rules from that version as before:
    • Incompatible immutable bytes are refused.
    • Across draft 19, a mutable 0x06 is dropped and a sealed one is refused.
    • On draft 14 and 15 there is no track block, so the immutable check is skipped there.
  • Ingress helpers: ietf::object::{same_bytes, block, check, values} and Wire::defined take an exact ietf::Version instead of an Encoding family. Version::ALL, drafts(), family() and delivery_timeout() are deleted.
  • Message-level properties: ietf::Properties::unknown is now a plain Vec<Property> in the message's own draft. accepted_info/refused take the session version.
  • lite subscriber:
    • A new lite::Framing { timescale, ietf }, derived from the accepted track::Info, replaces the timescale that was threaded through TrackEntry, FrameIngest, ServeLoop, FetchServeRun and begin_subscription/prepare_establish. The redundant timescale parameters are removed.
    • FetchServeRun keeps the whole track info, so a fetched group inherits the version too.
    • On a versionless track, a non-zero Group State is refused with PROTOCOL_VIOLATION, and a non-zero Datagram State or any record block is refused as malformed.

Public API

None. Every changed item is crate-private (pub(crate), with // private: passthrough markers).

Wire

lite-07-wip only, and only when ietf is negotiated. Not published.

  • TRACK_PROPERTIES is Version (i) followed by the Property List.
    • Version is the moq-transport version code, for example 0xff000012 for draft 18, or 0 for a moq-lite track.
    • With Version 0 the list must be empty. Drafts 14 and 15 also require an empty list.
    • An unknown version code or a lite version code is malformed.
    • fits() counts the Version's varint size.
  • An object record's Properties and a datagram's Properties are now the bare Property Block, with no Encoding code. The record limit is now 65,536 bytes (was 65,537).
  • drafts/draft-lcurley-moq-ietf.md is updated, and just drafts check passes.

Tests

  • ietf::subscriber::passthrough_keeps_0x06_from_crossing_draft_19: a draft-18 publisher's mutable 0x06 is dropped and a sealed one refused at draft 19, both directly and through a lite-07 hop. The harness requires identical bytes on both paths.
  • ietf::publisher::track_property_0x06_does_not_cross_draft_19: the same check for track properties, directly and across the hop.
  • Mutation check: both tests above fail if the lite decode relabels draft 18 as draft 19, so they pin the carried version.
  • plain_media_crosses_unchanged: a lite-published track crosses with no version.
  • Malformed peer, refused in each place:
    • versionless TRACK_PROPERTIES carrying a list (track_properties_refuse_what_ingress_would_not_keep)
    • a relayed group on a versionless track (ietf_records_need_a_moq_transport_track)
    • datagram state on a versionless track (datagram_state_needs_a_moq_transport_track)
  • The codec tests are rewritten for exact versions: END record blocks only on draft 14, datagram shapes per draft, and a list exactly at the lite message limit beside its Version.

Checks

On head 68a9bb96fd:

  • just check: passed (7812 Rust tests, clippy, rustfmt, no-default-features moq-net, docs). 68a9bb96fd fixed what the unverified WIP commit left: rustfmt diffs, and group::Consumer::ietf flagged as dead code without the async feature.
  • One just check run hit export::redundant_importers_switch_through_bufferbloat_on_lite_07, a known flake on main tracked by quest/m1/test-flakes-2/redundant-failover-drift.md with a fix in moq-dev/moq#6113. It does not touch the ietf extension; the next run passed.
  • just test interop --all: passed.
  • quest check and just drafts check: passed.

Decisions

Settled with the recommended option, and confirmed by the maintainer.

  1. How TRACK_PROPERTIES encodes the version.
    • (a) ✅ The moq-transport version code, 5 to 8 bytes once per track, reusing crate::Version::code(). Self-describing, and the cost is paid once per track.
    • (b) The bare draft number, 1 byte.
  2. Size of the epic README (quest/m1/ietf-extension/README.md). Its last child is gone, so its remaining work is the nightly moxygen conformance job.
    • ✅ [L]: it needs a pinned moxygen build, a run per shared draft, a two-relay cluster, and possibly a routing decision for the 16-field namespace.
    • [M].

Follow-ups

  • Optionally, the lite publisher could refuse to send relay state for a group whose track has no version. Today only the receiver refuses it, and the case cannot occur because group state only comes from moq-transport ingress. Recommendation: skip it.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 5 commits October 20, 2026 15:26
…once per track

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… provenance quest

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ccessor

group::Consumer::ietf is only read by moq-transport egress, so moq-net without
the async feature flagged it as dead code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review October 21, 2026 00:21
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fd8e5b51-b78d-4cb2-bfc9-0e61c3d9ddd0
📥 Commits

Reviewing files that changed from the base of the PR and between a42689d and 3e0c5df.

📒 Files selected for processing: 20
  • drafts/draft-lcurley-moq-ietf.md
  • quest/m1/ietf-extension/README.md
  • quest/m1/ietf-extension/lite.md
  • quest/m1/ietf-extension/serve-timed.md
  • quest/m1/lite07-finalize.md
  • rs/moq-net/src/fuzz.rs
  • rs/moq-net/src/ietf/datagram.rs
  • rs/moq-net/src/ietf/object.rs
  • rs/moq-net/src/ietf/properties.rs
  • rs/moq-net/src/ietf/publisher.rs
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-net/src/ietf/version.rs
  • rs/moq-net/src/lite/datagram.rs
  • rs/moq-net/src/lite/ietf.rs
  • rs/moq-net/src/lite/publisher.rs
  • rs/moq-net/src/lite/subscriber.rs
  • rs/moq-net/src/lite/track.rs
  • rs/moq-net/src/model/group.rs
  • rs/moq-net/src/model/object.rs
  • rs/moq-net/src/model/track.rs
💤 Files with no reviewable changes: 3
  • quest/m1/lite07-finalize.md
  • quest/m1/ietf-extension/lite.md
  • rs/moq-net/src/ietf/version.rs

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

Walkthrough

The protocol draft and Rust implementation now use the publisher’s track version to interpret property blocks, Track Properties, group records, FETCH responses, and datagrams. The Rust changes add unified track framing for timescale, IETF version, and compression. Relay paths carry source-version information when encoding properties and apply draft-specific handling for property 0x06. The changes also update related tests, fuzz targets, and quest documentation.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 3e0c5

The change records a track's originating moq-transport version once and uses it to interpret property blocks across lite hops. No concrete merge-blocking problem was found in the supplied context, so it is ready to merge after normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the main change: recording IETF extension provenance as the ingress version for lite tracks.
Description check Passed The description is directly related to the changeset and explains the version propagation, model updates, wire changes, validation rules, and tests.
Docstring Coverage Passed Docstring coverage is 87.58% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 153 functions across 11 files. (6 skipped: …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 87.58% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 153 functions across 11 files. (6 skipped: 3 unsupported, 3 too large.)

✨ Finishing Touches
✨ Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T17:45:17.148869Z 3e0c5df Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kixelated
kixelated added this pull request to the merge queue Oct 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 21, 2026
# Conflicts:
#	rs/moq-net/src/fuzz.rs
#	rs/moq-net/src/lite/datagram.rs
#	rs/moq-net/src/lite/subscriber.rs
#	rs/moq-net/src/lite/track.rs
#	rs/moq-net/src/model/track.rs
@kixelated
kixelated disabled auto-merge October 21, 2026 07:33
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

The last merge of main combined this PR's lite::Framing with main's lite::Format (compressed tracks, #5928) in moq-net's lite datagram and subscriber paths. Please review that resolution.

(Written by Claude Opus 5.5)

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 72e47fb13c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kixelated
kixelated added this pull request to the merge queue Oct 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 21, 2026
kixelated and others added 2 commits October 21, 2026 09:56
# Conflicts:
#	rs/moq-net/src/lite/publisher.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

Merged origin/main. One conflict in rs/moq-net/src/lite/publisher.rs: main moved the group-open arm into GroupServe::poll_open, so this PR's change there (dropping the trailing self.ctx.version argument from lite::ietf::Records::start) now applies inside poll_open. A follow-up commit rustfmts that call.

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b9b178a780

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +325 to 326
w.varint(crate::Version::Ietf(properties.version).code())?;
w.slice(&encode_list(properties)?);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the TypeScript codec with the new wire format

This changes the lite-07 ietf extension from per-object Encoding codes to a track-level Version, but the commit contains no corresponding js/net codec change. That leaves the TypeScript implementation without the matching TRACK_PROPERTIES, object-record, and datagram framing required for cross-language support; update it alongside the Rust wire change.

AGENTS.md reference: rs/moq-net/AGENTS.md:L5-L5

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declining: js/net does not implement the ietf extension, so there is no TypeScript codec to update. Only Rust offers it (extensions.ietf), as doc/concept/standard.md states, and a JS peer never negotiates it.

(Written by Claude Opus 5.5)

Comment on lines 159 to 162
TRACK_PROPERTIES Message {
Message Length (i)
Encoding (i)
Version (i)
Property List (..)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Record the wire change in the draft changelog

This replaces the TRACK_PROPERTIES Encoding field with Version and removes each object's Encoding field, but the draft changelog still contains only “Initial version.” Add a bullet under the in-progress version so revision readers can identify this wire-incompatible semantic change.

AGENTS.md reference: drafts/AGENTS.md:L18-L18

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declining: draft-lcurley-moq-ietf has never been published (no -00 on the datatracker), so the in-progress -00 is the initial version and "Initial version." already covers it. A changelog bullet would describe a change from a revision no reader has seen.

(Written by Claude Opus 5.5)

# Conflicts:
#	quest/m1/ietf-extension/README.md
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

Merged origin/main again. Only the quest tree conflicted: main added quest/m1/ietf-extension/serve-timed.md as a child of the epic, requiring this PR's lite.md. The epic's Required list now holds only serve-timed.md, its title is unsized again since it has a child, and serve-timed.md no longer requires the deleted lite.md. quest check and just check pass.

(Written by Claude Opus 5.5)

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 3e0c5dfee8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for head 3e0c5dfee8:

  • Two origin/main merges. The first moved this PR's Records::start argument change into main's new GroupServe::poll_open, plus a rustfmt commit. The second updated the epic's Required list for main's new serve-timed.md child; that change was quest-only.
  • Sync audit: no MIGRATE.md entry is needed, since every changed item is crate-private (lite and ietf are private modules, and object is pub(crate)). doc/concept describes behavior that stays the same, and drafts/draft-lcurley-moq-ietf.md carries the wire change.
  • Checks: just check passed on the final head, with 8022 Rust tests, JS, and quest. just drafts check and just test interop --all passed on the first merge (b9b178a780); the second merge added only quest edits and main's own commits.
  • Codex: two findings on b9b178a780 were declined (no JS codec exists for the ietf extension; draft -00 is unpublished, so "Initial version." covers the change). Clean on 3e0c5dfee8.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit dbdce97 Oct 21, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/ietf-extension/lite branch October 21, 2026 23:13
kixelated added a commit that referenced this pull request Oct 22, 2026
Adapt fills to main's error-carrying drops (#6143): a fill's local drop
records its error, a cursor's given-up misses are named NOT_FOUND without
overwriting a known reason, and a held legacy fill rejects the group it
waited on with the error it was given up with. FetchServeRun takes the
track info (#6107), and the C dynamic handler keeps main's finished
broadcasts (#6157).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant