Skip to content

feat(ffi)!: bindings carry and honor catalog reference epochs - #6244

Merged
kixelated merged 4 commits into
mainfrom
quest/m1/reference-epoch-bindings
Oct 22, 2026
Merged

kixelated merged 4 commits into
mainfrom
quest/m1/reference-epoch-bindings

Conversation

@kixelated

@kixelated kixelated commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Quest: /quest/m1/reference-epoch-bindings.md (deleted here).

Summary

A native app now gets the same guarantee as Rust and @moq/watch: a rendition whose catalog reference names an epoch fails, instead of playing, when its broadcast is proven to serve another publisher instance.

  • MoqVideo / MoqAudio gain epoch: Option<String> beside broadcast, filled from the catalog.
  • MoqBroadcastConsumer::resolve(reference, epoch) takes the epoch as a required second argument and passes it to moq_mux::Source::resolve.
  • MoqMediaTrackConsumer::subscribe, MoqMediaGroupConsumer::fetch, MoqVideoConsumer::subscribe, and MoqAudioConsumer::subscribe read the epoch off the rendition.
  • An empty reference with an epoch goes through the source too, so the epoch is checked against the catalog's own broadcast ("without broadcast, it names the catalog's own instance"). A standalone broadcast (no origin) came through no route and has no epoch to prove, so there the epoch is best effort, the same as on an epochless route.
  • Wrappers: Swift resolve(_:epoch:), Python resolve(reference, epoch), Go Resolve(ctx, reference, epoch). Kotlin and Dart alias the UniFFI type directly; the checked-in Dart bindings are regenerated.

Decision: the resolve shape

Settled by the maintainer: keep resolve(reference, epoch) with a required second argument. It mirrors moq_mux::Source::resolve(rel, epoch) and @moq/watch's relativeBroadcast(effect, broadcast, epoch), adds no exported type, and has no default, so every caller decides about the epoch instead of silently dropping it. A reference record (MoqReference { broadcast, epoch }) and resolving a MoqRendition directly were considered and rejected.

C

The hand-written libmoq (rs/moq-c) is unchanged. The 2026-10-20 maintainer decision recorded in /quest/m1/c/README.md freezes it and lands this quest's C half on the generated C package. That package is generated from moq-ffi, so it inherits the reference epoch with no extra work; the quest's mention there is removed with the quest.

Public API and wire impact

  • Breaking for the moq-ffi UniFFI API and every wrapper: resolve gains a required epoch argument, and MoqVideo / MoqAudio gain epoch (defaults to null in the generated bindings; a Rust struct literal adds epoch: None). MIGRATE.md entries are added for rs/moq-ffi, py/moq-rs, py/moq-ffi, swift, swift/ffi, go/wrapper, go/ffi, kt/moq, kt/moq-ffi, dart/moq, dart/moq_ffi, and cpp/moq.
  • The mismatch surfaces as MoqError::Mux (from moq_mux::Error::EpochMismatch).
  • C ABI: none.
  • Wire: none.

Tests

  • moq-ffi: resolve_honors_the_reference_epoch covers a matching, mismatched, and epochless reference, an epoch on an epochless route, an empty reference against the catalog's own epoch, a malformed epoch, and the rendition-based MoqMediaTrackConsumer::subscribe. catalog_exposes_rendition_broadcast_references now also checks that the epoch crosses the binding.
  • just test interop --all passed before the merge with main. just check passes on the merged head (rs, py, kt, go, dart, cpp, obs, quest), except check flake, which cannot build a github-runner image in the sandbox (unshare: Operation not permitted).

Not changed

  • doc/lib/*: no page covers resolve or rendition references, so there is nothing to update.

Suggested follow-ups

  • A typed MoqError variant for an epoch mismatch, if an app needs to tell it apart from other Mux failures (no consumer today).

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 2 commits October 21, 2026 20:50
MoqVideo and MoqAudio expose the rendition's optional `epoch`, and
MoqBroadcastConsumer::resolve takes it beside `reference`, mirroring
moq_mux::Source::resolve and @moq/watch. The rendition-based consumers and
libmoq's rendition resolution pass it through, so a broadcast proven to
serve another publisher instance fails the rendition instead of playing.

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

Copy link
Copy Markdown
Collaborator Author

Quest outcome: implemented with the second-optional-argument resolve(reference, epoch) shape (A). It mirrors moq_mux::Source::resolve and @moq/watch, with no default, so every caller decides about the epoch. B (a reference record) and C (resolve a MoqRendition) are laid out in the description for the maintainer to pick. Rust unit tests, just check (all but an environmental check flake failure), and just test interop --all pass. Left as a draft until the shape is settled.

(Written by Claude Opus 5.5)

The 2026-10-20 maintainer decision on main (#6092) freezes the hand-written
libmoq and lands this quest's C half on the generated C package, which is
generated from moq-ffi and so inherits the reference epoch. The rs/moq-c
changes are restored to main, and the quest's reference in
/quest/m1/c/README.md is removed with the quest.

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

Copy link
Copy Markdown
Collaborator Author

Decision settled by the maintainer: keep resolve(reference, epoch) with a required second argument (option A). The PR body records it.

Merging main brought in the 2026-10-20 maintainer decision from moq-dev/moq#6092: the hand-written libmoq is frozen, and this quest's C half lands on the generated C package. So 5f264e0 restores rs/moq-c to main (the moq_consume_video / moq_consume_audio epoch check, its test, and its MIGRATE.md entry). The generated package comes from moq-ffi, so it inherits the epoch with no extra work. The quest's mention in /quest/m1/c/README.md is removed along with the quest. If the libmoq behavior fix should land anyway as a narrow correctness exception, like claim epochs, it's one revert of that merge's rs/moq-c hunk.

(Written by Claude Opus 5.5)

@kixelated
kixelated marked this pull request as ready for review October 22, 2026 05:03
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 7 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9655367d-f152-4d83-97ea-bb6357756e8b
📥 Commits

Reviewing files that changed from the base of the PR and between 0cf22aa and c77f56f.

📒 Files selected for processing: 25
  • cpp/moq/MIGRATE.md
  • dart/moq/MIGRATE.md
  • dart/moq_ffi/MIGRATE.md
  • dart/moq_ffi/lib/src/moq.dart
  • dart/moq_ffi/test/leak_test.dart
  • go/ffi/MIGRATE.md
  • go/wrapper/MIGRATE.md
  • go/wrapper/subscribe.go
  • kt/moq-ffi/MIGRATE.md
  • kt/moq/MIGRATE.md
  • py/moq-ffi/MIGRATE.md
  • py/moq-rs/MIGRATE.md
  • py/moq-rs/moq/subscribe.py
  • quest/m1/README.md
  • quest/m1/c/README.md
  • quest/m1/reference-epoch-bindings.md
  • rs/moq-ffi/MIGRATE.md
  • rs/moq-ffi/src/audio.rs
  • rs/moq-ffi/src/consumer.rs
  • rs/moq-ffi/src/media.rs
  • rs/moq-ffi/src/test.rs
  • rs/moq-ffi/src/video.rs
  • swift/MIGRATE.md
  • swift/Sources/Moq/Broadcast.swift
  • swift/ffi/MIGRATE.md
  • 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 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-22T05:52:39.557701Z c77f56f 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: 5f264e09a2

ℹ️ 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-ffi/src/consumer.rs
…+ packages

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Oct 22, 2026
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merging. Since Codex's review of 5f264e0, the only change is c77f56f: MIGRATE.md entries for kt/moq, kt/moq-ffi, py/moq-ffi, swift/ffi, and cpp/moq, which addresses the one open finding. It only touches docs, so no fresh review is needed.

Decision recorded: resolve(reference, epoch) keeps a required epoch argument (maintainer's choice), mirroring moq_mux::Source::resolve and @moq/watch.

Follow-up: a typed MoqError variant for an epoch mismatch, if an app needs to tell it apart from other Mux failures.

(Written by Claude Opus 5.5)

Merged via the queue into main with commit 744b909 Oct 22, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/reference-epoch-bindings branch October 22, 2026 08: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