Skip to content

fix(net): preserve IETF timestamps across negotiated lite hops - #6300

Merged
kixelated merged 6 commits into
mainfrom
quest/m1/ietf-extension/serve-timed
Oct 23, 2026
Merged

kixelated merged 6 commits into
mainfrom
quest/m1/ietf-extension/serve-timed

Conversation

@kixelated

@kixelated kixelated commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

A timed moq-transport track loses its timestamps at the first moq-lite relay hop, even when both peers negotiate ietf. A separate unchecked flag also duplicates the track's already-carried ingress version, so the two can disagree after a hop.

Approach

Use the original IETF version (Info::ietf()) as the sole unchecked-timestamp provenance. Preserve that track's timescale only for a negotiated extension peer, consistently across TRACK_INFO, SUBSCRIBE, FETCH, and datagrams. A non-extension peer still receives it untimed. Listings (TRACKS_ADD) stay untimed even to an extension peer: they carry no TRACK_PROPERTIES, so a relay would lose the provenance and re-list the track as timed native lite; the extension already requires the Track Stream for listed tracks. Derive the receiver's rewind policy from the same provenance, so an IETF arrival-time rewind does not become a native-lite violation after a hop.

Mirror the private ingress-version metadata in JS (Info.ietf replaces Info.unchecked). JS has no ietf passthrough implementation, an explicit epic non-goal, so its lite egress stays untimed. Synchronize the timing explanation in doc/concept/moq-lite.md and both matching drafts.

Merged main to keep the public-ingest and priority refactors (moq-dev/moq#6111, moq-dev/moq#6142); a resume test from main that set unchecked: true now sets moq-transport provenance instead. Retires the finished quest/m1/ietf-extension/serve-timed.md; its epic README now holds only the nightly moxygen work.

Impact

  • Public API: none. Rust's crate-private track::Info::unchecked and JS's @internal Info.unchecked are replaced by the existing private ingress provenance. lite_timescale (crate-private / @internal) now takes whether the hop negotiated ietf.
  • Wire: no new fields, messages, or encoding changes. Negotiated lite-07-wip ietf peers now retain a relayed track's timescale and its existing timestamp prefixes. Unextended and published (lite-05/06) peers keep their previous untimed behavior. The lite draft relaxes the frame-0 ordering MUST and the "serve untimed" MUST only where a negotiated extension identifies unchecked provenance; the ietf extension draft states that it does, and that a listing stays untimed.
  • Consumers: Rust relay meshes forwarding IETF content, including FETCH-only readers and datagrams. Native moq-lite rewind checks remain intact.

Validation

  • Pre-fix reproduction: the existing original-units passthrough test fails with None instead of Some(42ms) across the negotiated hop and passes after the change.
  • After merging main: cargo nextest run -p moq-net --all-features 3028 pass (11 skips); js/net bun test 2635 pass.
  • The hop test asserts the listing is untimed for every offer; it fails when the listing advertises the IETF timescale.
  • just check: js, drafts, rs, quest, and drill stages pass; the flake stage stops at the unchanged Nix runner-image build because this host denies unshare writing /proc/self/uid_map (host limitation, not the branch).
  • just test interop --all: all 127 checks pass across rust, python, go, cpp, js, js-native-node, js-native-bun, c, and gst, including delivery, auth refusals, browser close code, CLI FETCH, finite tails, compression, and drop coverage.
  • quest check --base origin/main --branch quest/m1/ietf-extension/serve-timed passes.

Alternatives

Keeping two independent provenance flags permits disagreement after a hop. Sending timestamps to an unextended peer would subject unchecked arrival times to native-lite checks. Adding JS extension support would expand this beyond its epic's boundary.

Follow-ups

None new. The ietf-extension epic keeps the nightly moxygen conformance job.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 2 commits October 22, 2026 02:51
@kixelated kixelated changed the title Timed moq-transport tracks cross a lite-07 mesh fix(net): preserve IETF timestamps across negotiated lite hops Oct 22, 2026
kixelated and others added 2 commits October 22, 2026 14:42
…on/serve-timed

# Conflicts:
#	drafts/draft-lcurley-moq-lite.md
#	rs/moq-net/src/model/track.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review October 22, 2026 21:53
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

(Written by Claude Opus 5.5)

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0184cc68-e728-42f5-81e3-ffcab8e3b4c9
📥 Commits

Reviewing files that changed from the base of the PR and between fd59eb1 and 28b06a9.

📒 Files selected for processing: 17
  • doc/concept/moq-lite.md
  • drafts/draft-lcurley-moq-ietf.md
  • drafts/draft-lcurley-moq-lite.md
  • js/net/src/ietf/subscriber.ts
  • js/net/src/lite/publisher.test.ts
  • js/net/src/lite/track_stream.test.ts
  • js/net/src/track.test.ts
  • js/net/src/track.ts
  • quest/m1/ietf-extension/README.md
  • quest/m1/ietf-extension/serve-timed.md
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-net/src/lite/ietf.rs
  • rs/moq-net/src/lite/publisher.rs
  • rs/moq-net/src/lite/track.rs
  • rs/moq-net/src/model/group.rs
  • rs/moq-net/src/model/resume.rs
  • rs/moq-net/src/model/track.rs
💤 Files with no reviewable changes: 1
  • quest/m1/ietf-extension/serve-timed.md

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

Walkthrough

The changes replace the internal unchecked-track flag with IETF version provenance in JavaScript and Rust. MoQ Lite serving now uses IETF extension negotiation to determine whether it includes track timescales and timestamps. Protocol text and tests describe preservation across negotiated hops, untimed listings, and untimed service when peers do not negotiate the extension.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 28b06

No identified issue prevents merging. Timestamp forwarding follows negotiation, while track listings remain untimed as intended.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 10 files. (6 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title names the main change: timestamps from IETF tracks are preserved across moq-lite hops when the ietf extension is negotiated. It matches the changeset, which replaces the unchecked flag with …
Description check Passed The description states the problem (timed moq-transport tracks lose timestamps at the first moq-lite hop), the approach (Info::ietf() as sole provenance, negotiated-only timescale preservation, JS mir…
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: Title check

Explanation

The title names the main change: timestamps from IETF tracks are preserved across moq-lite hops when the ietf extension is negotiated. It matches the changeset, which replaces the unchecked flag with Info.ietf and makes lite_timescale depend on negotiation. The title follows the fix(net) convention and is 62 characters.

Full details: Description check

Explanation

The description states the problem (timed moq-transport tracks lose timestamps at the first moq-lite hop), the approach (Info::ietf() as sole provenance, negotiated-only timescale preservation, JS mirror with Info.ietf replacing Info.unchecked), validation, and impact. It matches the raw summary's changes across Rust, JS, drafts, and the quest docs.

Full details: Docstring Coverage

Explanation

Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 10 files. (6 skipped: 4 unsupported, 2 too large.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

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

Warning

Some tools did not complete. Review the errors below.

🔧 Clippy (1.99.0)

Clippy execution timed out

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 22, 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-23T01:33:54.478660Z 28b06a9 New commits
ℹ️ 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.

@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: f83ee181e8

ℹ️ 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 thread rs/moq-net/src/lite/publisher.rs Outdated
Some(crate::broadcast::TracksEvent::Added { name, info }) => lite::TracksEvent::Added {
name: name.to_string().into(),
info: lite::TrackInfo::serve(&info, shared.version),
info: lite::TrackInfo::serve(&info, shared.version, ietf),

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 Preserve IETF provenance in forwarded track listings

When an IETF track listing crosses a negotiated ietf hop, this now forwards its timescale, but TRACKS_ADD carries no TRACK_PROPERTIES; the receiver therefore stores the listed Info with properties: None. If that relay forwards the listing over a second, unextended hop, lite_timescale(false) mistakes it for a native-lite track and advertises the timescale again, while the subsequent Track/SUBSCRIBE path correctly serves the media untimed. A client may skip the Track Stream based on TRACKS_ADD, as the base protocol permits when it did not negotiate the extension, and then parse the untimed group framing as timestamped. The listing representation must retain unchecked provenance across relays or avoid advertising this timescale where provenance cannot accompany it.

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.

Valid: the receiving relay stored the listed Info without provenance and would re-list it as timed native lite. Fixed in e36ee4a: TRACKS_ADD now lists a moq-transport track untimed even to an extension peer (the Track Stream stays authoritative, and the extension already forbids skipping it). The hop test now asserts the listing is untimed for every offer and fails if the listing advertises the timescale; the ietf draft says the same.

(Written by Claude Opus 5.5)

TRACKS_ADD carries no TRACK_PROPERTIES, so a relay receiving the listing
loses the unchecked provenance and would re-list the track as timed native
lite to an unextended peer, whose media is served untimed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Oct 22, 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 23, 2026
Resolve the moq-lite draft conflict by keeping main's 2^61 timestamp
bound beside this branch's negotiated-extension exception to the
frame 0 ordering rule, and both changelog entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit 6b8de09 Oct 23, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/ietf-extension/serve-timed branch October 23, 2026 04:18
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