Skip to content

Merge main into dev - #4214

Merged
kixelated merged 39 commits into
devfrom
claude/merge-main-into-dev-1f2e40c
Sep 26, 2026
Merged

kixelated merged 39 commits into
devfrom
claude/merge-main-into-dev-1f2e40c

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Merges main (1f2e40c4a, 37 commits) into dev.

Conflicts and how they were resolved

API / wire impact

None beyond what each side already carries. Cluster::scope is unchanged except the comment naming the hidden opt-in moq-lite-07-wip.

Verification

just check against origin/dev (full suite; justfile is in the diff).

(Written by Grok 4.7)

kixelated and others added 30 commits September 25, 2026 05:44
…4127)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…s it (#4104)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…count (#4142)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…4123)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…section (#4089)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: moq-bot[bot] <186640430+moq-bot[bot]@users.noreply.github.com>
…ks (#4137)

Co-authored-by: Brad Greenway <brad.greenway@surveillx.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…4125)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
An IETF live join delivers nothing below the group its SUBSCRIBE_OK names as
Largest, so declare that as the copy's start. A parked track's warm cache
waiting on the copy then sees the upstream moved past it and live readers
skip it, as they already do on lite-06+.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
## Problem

`moq play`'s media tasks (`rs/moq-cli/src/play/media.rs`) sit behind the `play` feature and talk straight to a cpal `Engine` and a winit `EventLoopProxy`. CI only compiled them in the nightly clippy run, so regressions like #3966's rendition-switch gap were measured by hand with a real speaker.

## Approach

- New private seam `play::output`: `Output` (the window's wake handle plus a speaker opener), `Speaker`, and `Sink`. Production implements them on `EventLoopProxy<Event>`, `playback::Engine`, and `playback::Sink`; `Media`, `play_video`, `play_audio`, and `drain` are generic over them. No other production change beyond reading `tokio::time::Instant` (the wall clock unless a test pauses it) and passing `drain` the depth it already knew.
- `play::fake::Recorder` (test-only) stands in for both: its sink primes its latency in silence, drains in real time, re-pads on underflow the way `fixed-resample`'s ring does, and cuts what it holds when dropped. It records each write's sounding interval on tokio's clock.
- `an_audio_rendition_switch_leaves_no_gap` drives the real `Media` task over an in-process origin: a PCM rendition is retired for a replacement mid-stream at a 500 ms delay, on a paused clock. It asserts the silence between the old tail and the new first sample is under one audio chunk (it measures ~10 ms, the partial period `drain` leaves). Reverting #3966's fix (draining inside `play_audio` before returning) fails it with a 500 ms gap.
- CI: `just rs play` runs `nextest -p moq-cli --features play`. `test-changed` (the per-PR Test job), `check-changed` when testing (local `just check`), and the unscoped `check --all` / `ci test` run it whenever moq-cli is selected, which includes any change to moq-audio, moq-video, or moq-mux. The dev shell already carries the ALSA build dependency.
- Completes and deletes `quest/m1/play-harness.md`; `play-tunein-backpressure.md` is now unblocked and notes that it owns the fake presenter for the video queue.

## Impact

- No public API or wire changes. Everything is private to the `moq` binary's `play` feature.
- The per-PR Test job compiles moq-cli a second time with `play` (wgpu, winit, cpal) when moq-cli is selected.

## Alternatives

- Making `media.rs` compile without `play`, so the default test pass covers it. The tasks need `moq-video`/`moq-audio` decoders, which are optional deps of the CLI on purpose; the quest chose the feature-enabled test pass instead.
- A callback for the wake instead of a trait. The repo prefers handles over callbacks, and the speaker opener needs a type anyway.

## Follow-ups

- `drain` returns once 10 ms or less is buffered and then drops the sink, which removes it from the mix, so every retired rendition and every finite track loses up to its last 10 ms. The test's tolerance absorbs it; worth a quest if it is audible.
- The harness has no fake presenter for the video queue yet; `play-tunein-backpressure` adds it with its regression test.

(Written by Claude Opus 5.5)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…4129)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: moq-bot[bot] <186640430+moq-bot[bot]@users.noreply.github.com>
kixelated and others added 9 commits September 25, 2026 15:30
…cks (#4192)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…4195)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
origin.rs polls a track query through kio::Task, and the mock holds uni
streams in a Mutex. Both imports were on one side of the merge and the
call sites on the other.
@kixelated
kixelated enabled auto-merge September 25, 2026 23:50
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 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-09-25T23:55:46.254190Z f4106fa PR opened
ℹ️ 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

Copy link
Copy Markdown
Collaborator Author

MERGE

Branch sync: main (1f2e40c4a, 37 commits) into dev. No new product design here beyond what each side already carries; the value is keeping dev current with a documented conflict pass.

Positive improvement? Yes. dev picks up main's track-tail, warm-cache, lite-07-wip, mux catalog, auth, and quest work without inventing a second path for each.

Worth the complexity? Yes for a 37-commit sync. The PR body names every conflict and the chosen side. Spot-checks match that write-up:

  • moq-auth.md: keeps dev's Key::decode::<T> and main's legacy put/get read/write (aligned with the merged Claims/Scope wire).
  • quest/m1/README.md: keeps origin-mount, drops finished reconnect-test-ports / decoded-frames, keeps main's test-flakes quest.
  • quest/m2/js-discontinuity.md: restore from main (open requirement that an omitted end must not write a cadence-estimated duration marker); quest/m2/README.md link restored.
  • ietf/subscriber.rs: main's Poll<Result<Ended, Error>> with Ended::{Group,Track} plus waiter.context().
  • lite/publisher.rs: AtomicU64/Ordering for lite-07 stream count; call sites already use waiter.context().
  • origin.rs + mock.rs: follow-up commit correctly restores kio::Task and Mutex that one side of the merge dropped while the other still calls them.
  • relay/connection.rs: leaves authorize/Grants deleted; hidden peers stay on Cluster::scope.

Different approach? Rebase would rewrite history already on main; a merge PR is the right shape for this sync. No reason to reopen the individual main PRs here.

CI was still pending at review time; the description claims just check against origin/dev. Merge once those checks are green.

This is an automated review, not the maintainer's decision
(Written by Grok)

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

ℹ️ 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/tail.rs
Comment on lines +91 to +92
if self.grace.poll(waiter).is_ready() {
return Poll::Ready(());

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 Keep waiting for streams whose headers already arrived

When an IETF PUBLISH_DONE arrives after a group or fill handler has decoded its header but before it finishes reading the first object, Counted has not yet incremented Tail::streams(). This branch nevertheless settles after one second, allowing the caller to run track.finish() with a final sequence below the unopened group; when the handler resumes, opening that valid final group is rejected as closed and its payload is lost. Track active handlers separately and apply the grace only to streams whose headers never arrived.

Useful? React with 👍 / 👎.

Comment thread rs/moq-ffi/src/binary.rs
Comment on lines +43 to +47
pub fn publish_binary_snapshot(
&self,
name: String,
config: MoqBinaryConfig,
) -> Result<Arc<MoqBinarySnapshotProducer>, MoqError> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mirror the binary publishers into every wrapper

This adds a new UniFFI publishing surface, but the ergonomic Python, Go, Swift, Kotlin, and Dart packages and their binding docs do not add the corresponding config, producer handles, or BroadcastProducer methods. In particular, Python, Go, and Swift hide the generated MoqBroadcastProducer behind wrappers with no forwarding method, so consumers of those public packages cannot use this feature at all. Mirror the new surface across the required wrappers and documentation in this change.

AGENTS.md reference: AGENTS.md:L94-L96

Useful? React with 👍 / 👎.

@kixelated
kixelated disabled auto-merge September 26, 2026 00:09
@kixelated
kixelated enabled auto-merge September 26, 2026 00:09
@kixelated
kixelated merged commit 21d3310 into dev Sep 26, 2026
21 checks passed
@kixelated
kixelated deleted the claude/merge-main-into-dev-1f2e40c branch September 26, 2026 00:53
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.

2 participants