Skip to content

fix(net): pass lite-05/06 timestamps through - #6996

Draft
kixelated wants to merge 6 commits into
mainfrom
quest/m1/lite-timestamps-through
Draft

kixelated wants to merge 6 commits into
mainfrom
quest/m1/lite-timestamps-through

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m1/lite-timestamps-through.md (deleted here, with its links).

Problem

moq-dev/moq#6150 made receivers drop every timestamp read over moq-lite-05/06, because an untimed origin stamps send times there. As a result, a lite-06 reader of a timed feed (such as a stats feed) saw untimed frames. moq-dev/moq#6300 also served moq-transport tracks to moq-lite untimed unless the ietf extension was negotiated. Maintainer decision (2026-10-25): pass the timestamps through instead.

Approach

  • Rust: track::Info gets back a crate-private unchecked flag. The lite subscriber sets it on a lite-05/06 copy. TrackState::neighbors skips the moq-dev/moq#5803 rewind check for unchecked or moq-transport-provenance tracks. Frame, fetch, and datagram ingest keep the timestamps they read.
  • Publishing: Info::lite_timescale and group::Consumer::lite_timescale are gone. Every lite hop serves the track's own timescale and timestamps, including to TRACKS_ADD, lite-07 without the extension, and lite-05/06. An untimed track on lite-05/06 still carries its send time in milliseconds, as published.
  • JS: @moq/net mirrors this. The @internal track.Info.ietf becomes unchecked. lite-05/06 TRACK_INFO maps to a timed copy with unchecked. frameDecoder/readFrames lose their timed flag, and liteTimescale is gone.
  • Specs and docs: draft-lcurley-moq-lite (receiver text and changelog), draft-lcurley-moq-ietf (timestamps without the extension), doc/concept/moq-lite.md, and doc/setup/upgrade.md.
  • Tests: they reverse feat(lite): drop lite-05/06 timestamps so receivers check received groups #6150's expectations in moq-net, moq-tokio, moq-relay, moq-cli, the C/C++ probes, e2ee, and test/wasm. received_rewind.rs now covers:
    • a timed track crossing a lite-06 (and moq-transport) hop between two origins with its values, served on over lite-06, lite-07, and moq-transport;
    • send times from an untimed origin passing a lite-06 relay unchecked, with lite-07 refusing the out-of-order group;
    • out-of-order fetches on lite-05/06 being accepted with their send times.
  • Interop finish clients: they no longer assert that the .health frame is untimed. A lite-06 browser publisher's untimed health track now reaches every reader with send times.

Choices made without asking

  • track::Info equality (Rust PartialEq, JS resume compatible) ignores unchecked. It records how a copy arrived, not what it holds, so same-epoch copies over lite-06 and lite-07 still splice. Before this change they mismatched on timescale.
  • The JS Info.ietf field (@internal, unreleased) is renamed to unchecked. JS used it for nothing else.
  • has_media_time stays as the version predicate. It now means "set unchecked", and resolves_anchors keeps requiring it.

Impact

  • Public API: none in Rust (unchecked is crate-private). In JS, the @internal track.Info.ietf becomes @internal unchecked.
  • Wire: no format change. Receiver behavior changes:
    • A track received over moq-lite-05/06 arrives timed with the TRACK_INFO timescale. That is the publisher's media time, or send times in milliseconds for an untimed origin. Its groups are not rewind-checked.
    • A relay serves those, and moq-transport timestamps, on over every version. A lite-07 receiver still checks them, so a send-time origin's out-of-order group (or a moq-transport rewind without the ietf extension) may be refused downstream. This cost was accepted in the quest.
  • Migration: feat(lite): drop lite-05/06 timestamps so receivers check received groups #6150 and fix(net): preserve IETF timestamps across negotiated lite hops #6300 are unreleased, so against the last release this restores the lite-05/06 pass-through. The existing Unreleased MIGRATE.md notes from feat(lite): drop lite-05/06 timestamps so receivers check received groups #6150 (rs/moq-net and js/net: "A track received over moq-lite-05/06 arrives untimed…", "a relay serves it to moq-lite untimed") are now wrong. As the quest plans, the cut's migration audit reconciles them with this section: received lite-05/06 tracks keep their timestamps unchecked, and moq-transport timestamps cross moq-lite timed.

Alternatives

  • A wire flag telling lite-07 receivers a track is unchecked. The quest rejected it: rewinds are unsupported.
  • Keeping Info equality derived. Simpler, but it would refuse a same-epoch lite-06 copy beside a lite-07 one.

Checks

just ci passes. just test interop --all passes: the full matrix ran, and the finish matrix was rerun after the health-assertion fix.

Follow-ups

None found.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

@kixelated kixelated changed the title Lite-05/06 timestamps pass through fix(net): pass lite-05/06 timestamps through Oct 28, 2026

This branch has not been deployed

No deployments
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