Skip to content

feat(c)!: announce through moq_announce_route - #7151

Merged
kixelated merged 2 commits into
mainfrom
quest/m1/c/announce-route
Oct 29, 2026
Merged

kixelated merged 2 commits into
mainfrom
quest/m1/c/announce-route

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Since moq-dev/moq#7044, a C publisher announces with moq_publication_announce, which took the shared moq_route. That struct had no epoch, so a C publisher could not announce a restart, and it accepted any caller-supplied hops, so a local publisher could claim relay hops it never took. moq-ffi's MoqAnnounceRoute already carries only a cost and an epoch. C also had no way to mint an epoch, so moq_broadcast_request_prepare needed one generated by hand.

Approach

Quest: quest/m1/c/announce-route.md (deleted here, finished).

  • moq_announce_route { cost, epoch, epoch_len } mirrors MoqAnnounceRoute. moq_publication_announce takes it; NULL or zeroed is still the default route. An epoch that is not canonical UUIDv7 text fails with MOQ_ERROR_INVALID_CONFIG.
  • moq_mint_epoch(char *dst, size_t dst_len) writes MOQ_EPOCH_LEN (36) bytes of fresh UUIDv7 text, like moq-ffi's moq_mint_epoch.
  • moq_route now describes a received route: moq_announce_event gains a trailing route field (hops, cost, epoch), borrowed from the announcement like prefix and captures. Before this, no call returned a moq_route, so it had nothing to describe once announcing moved off it.
  • Tests: a minted epoch is ordered UUIDv7 text, short or NULL buffers are refused; a locally announced route reaches a listener with its cost and epoch and no hops; a non-UUIDv7 epoch is refused; a re-announce under a new epoch reaches the listener as MOQ_ANNOUNCE_KIND_RESTART carrying the new epoch. The anonymous-hop announce test is gone along with announced hops.
  • doc/lib/c gains a short Publish sample (compiled by just rs c-tests), and the rs/moq-c README lists the new signature.

Unchanged: c/moq's probe, the C++ package, and the OBS plugin already announce through moq-ffi's generated AnnounceRoute and mint_epoch.

Choices made without asking (open to review):

  • I wired moq_route into moq_announce_event instead of deleting it. This keeps the planned "stays for received routes" role and matches MoqAnnounce.route. Deleting it would be smaller, but C subscribers would then have no way to see an epoch or hops.
  • moq_route leaves out moq-ffi's anonymous flag, since a C caller can find it by scanning hops for a 0.
  • moq_mint_epoch writes into a caller buffer sized by MOQ_EPOCH_LEN and returns the length, rather than returning a struct by value. This matches how other C inputs take const char * plus a length.
  • A bad epoch maps to the existing MOQ_ERROR_INVALID_CONFIG. I did not add a dedicated code like moq-ffi's InvalidEpoch.
  • No MIGRATE.md edit, since the root AGENTS.md says only the release cut writes those sections. The Impact bullet below is the migration note.

Impact

  • Breaking (C ABI): moq_publication_announce(uint32_t, const moq_announce_route *) replaces const moq_route *. Migrate &(moq_route){.cost = c} to &(moq_announce_route){.cost = c} and drop any hops, which the origin now builds. To announce a restart, mint a fresh epoch per run with char e[MOQ_EPOCH_LEN]; moq_mint_epoch(e, sizeof e); and set .epoch = e, .epoch_len = sizeof e. Viewers then see MOQ_ANNOUNCE_KIND_RESTART instead of a stalled broadcast.
  • Breaking (C ABI layout): moq_route loses its role as an input and gains moq_string epoch. moq_announce_event gains a trailing moq_route route. Rebuild against the new header.
  • Added: moq_mint_epoch, MOQ_EPOCH_LEN, moq_announce_route.
  • Wire: none.

Alternatives

  • Refuse non-empty hops on the shared moq_route, or validate hop values. The maintainer rejected both on 2026-10-28 in favor of a separate struct that mirrors moq-ffi.
  • Delete moq_route outright, as described above.

Follow-ups

  • moq_broadcast_request_prepare reports a malformed epoch as MOQ_ERROR_INVALID_CODE, which reads as wrong. MOQ_ERROR_INVALID_CONFIG would match moq_publication_announce. This is a small break, so I left it out of this PR.
  • No moq-c test covers hops on a route received over a relay session. The local tests show only that hops are empty.

Checks: just ci passed locally. So did just rs c-tests (C fixtures plus doc samples against the generated moq.h), cargo test -p moq-c (149 passed), cargo clippy -p moq-c --all-targets --all-features -D warnings, and quest check --base origin/main.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 2 commits October 28, 2026 15:04
moq_publication_announce takes a cost and an optional UUIDv7 epoch, matching
moq-ffi's MoqAnnounceRoute, so a C publisher can announce a restart and can no
longer claim relay hops. moq_mint_epoch mints the epoch, and moq_route now
describes the received route each moq_announce_event carries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title moq-c announces through its own route struct feat(c)!: announce through moq_announce_route Oct 28, 2026
@kixelated
kixelated marked this pull request as ready for review October 28, 2026 22:32
@coderabbitai

coderabbitai Bot commented Oct 28, 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 34 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
  • 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: 9738732e-60b7-487d-bb24-8c4bed93930f
Commits

Reviewing files that changed from the base of the PR and between 53c0dcd and a64b5a5.

Files selected for processing: 7
  • doc/lib/c/index.md
  • quest/m1/c/README.md
  • quest/m1/c/announce-route.md
  • rs/moq-c/README.md
  • rs/moq-c/src/api.rs
  • rs/moq-c/src/origin.rs
  • rs/moq-c/src/test.rs
  • 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 28, 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-28T22:33:30.809936Z a64b5a5 Draft marked ready
ℹ️ 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 left a comment

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.

Automated review by review (OpenAI)

Reviewed commit: a64b5a5.

No actionable bugs found in the changed code. Separating publish inputs from observed routes is the right direction: callers can supply cost/epoch without forging relay hops, matching the existing moq-ffi conversion. The fixed-length mint API reuses Epoch validation/generation, and received route pointers borrow allocations owned by the announcement record until it is freed. Keeping the received-route struct is justified by exposing restart identity and routing information. The C signature/layout break is explicitly documented.

Verification: static review of the diff, announcement ownership/lifetime, FFI string parsing, Epoch implementation, header-generation setup, and moq-ffi counterpart. I did not build the generated C header, run tests, or verify received relay-hop behavior; that integration coverage remains a documented gap.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merging at head a64b5a57b0c3b99e78ef3be98eca53d5b88e7717.

  • Reviews: Codex reacted with a thumbs-up (no findings), and the automated review posted from the maintainer's account found no actionable bugs. No unresolved threads.
  • CI: all 12 checks passed on this head.
  • quest check --base origin/main --branch quest/m1/c/announce-route passes. The quest file is deleted here, so the quest is finished.
  • No changes since review. The maintainer approved merging.
  • The choices listed in the body (keep moq_route for received routes, no anonymous flag, caller-buffer moq_mint_epoch, reuse MOQ_ERROR_INVALID_CONFIG) stand as written.
  • The C API gaps follow-up is planned in moq-dev/moq#7195.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 4f7f7c4 Oct 29, 2026
12 checks passed
@kixelated
kixelated deleted the quest/m1/c/announce-route branch October 29, 2026 05:47
kixelated added a commit that referenced this pull request Oct 29, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 29, 2026
#7151 landed on main and already fills moq_route's epoch for
every received announcement, so the planned receiving-side quest has no
work left.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant