Merge main into dev#2013
Merged
Merged
Conversation
…#1903) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…pport (#1902) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…#1905) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…nt-tls-* flags consistent (#1901) Co-authored-by: Claude <noreply@anthropic.com>
…ds (#1908) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…enchmark) (#1912) Co-authored-by: Claude <noreply@anthropic.com>
…r::request_broadcast (#1913) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
#1914) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…xport) (#1915) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Codex <codex@openai.com>
…ks) (#1918) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Luke Curley <luke.curley@discordapp.com>
…1858) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…updates (#1832) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…1942) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Luke Curley <kixelated@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Replace the consume-side-only catalog::Filter with one selection type that reads the same at both ends of the pipeline. - New moq_mux::select module: Broadcast/Video/Audio fluent builders (default selects nothing; opt a role in, narrow by name/codec, empty field = any). - catalog::Select replaces Filter/FilterVideo/FilterAudio; Stream::filter() -> Stream::select(selection). The adapter is immutable, dropping the old reactive set-mid-stream machinery. - fmp4::Import::with_select restricts which roles are published (new() unchanged, so existing callers still import everything). - moq-hls uses it on both ends: per-rendition export selects only its own axis, and import publishes master-playlist variants video-only beside a separate audio rendition (the track-selection half of #1940). Breaking moq-mux change, targeting main during the pre-semver-bump window. The discontinuity-sequence change from #1940 is intentionally left for a separate PR.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…1968) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…pt path) (#1974) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a devTools group so `gh` is available under `nix develop` for opening and reviewing PRs. Build-only groups are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1998) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Reconciles main's backported crates and new features with dev's architecture. Dev's shapes win on wire protocol (moq-lite-05), the moq-net API, and the moq-mux restructure; main's features are ported on top, notably: - moq-mux/hang: FLAC, MP3, and Opus-over-TS codec support, select::Broadcast rendition selection, fMP4 zero-duration and discontinuity fixes - moq-cli: unified endpoint grammar (binary renamed to moq), CORS origins, per-sink frame-drop latency, HLS import via moq-hls - moq-rtmp/srt/rtc: library-only crates with client (dial-out) roles, ICE timeout, SDP rejected m-line fix, session runner - moq-native/relay: unified client TLS verification (OS platform verifier), client TLS reuse for auth HTTP, internal listener folded into --server-bind, HTTPS cert arrays - moq-net: announcement byte-usage stats ported onto dev's tier labels - moq-json/js: DEFLATE extracted to moq-flate/@moq/flate, diffing serializer - js: qmux 0.1.3 (reconnect fix, requireProtocol), watch reload default on Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
The lockfile committed with the merge was regenerated by an install that aborted on a postinstall script, so it did not match the merged package.json set and failed CI's --frozen-lockfile check. Also strip a stray trailing blank line rustfmt flagged in libmoq's tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
…ode ignore The fresh quick-xml advisories have no reachable fix: the sole consumer chain is plist -> netdev -> netwatch -> iroh and even the latest plist pins quick-xml 0.39. netdev parses local macOS system configuration, not attacker-controlled XML. RUSTSEC-2025-0141 no longer matches any crate (http-cache moved off bincode 1.x), so its ignore is removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
The platform capture stream is not Send, so Publish::run cannot be spawned on the JoinSet once the capture feature is enabled. Select it against the JoinSet on the current task instead, matching the previous CLI's shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
…isher logs Three harness fixes surfaced by this PR's smoke run (the first since #1952, as the workflow only triggers on test/smoke changes or nightly on main): - The python client never awaited the now-async subscribe_media (#1761 made it a coroutine; #1952 fixed subscribe_catalog but missed this one). - libmoq.a bundles openh264 (C++) and moq-vaapi (libva), so the C client link needs -lstdc++ -lva -lva-drm on Linux. - The rust publisher failed every leg in CI while staying alive, and the harness gave no clue why: the rust subscriber's stderr went to /dev/null and the publisher log was only dumped if the process died. Keep subscriber stderr in the leg log and dump the publisher log when a whole round fails. rust -> rust passes locally with these changes; the publisher-log dump is there to diagnose the remaining CI-only failures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
…:select Also dump the relay log when the smoke matrix fails: the relay's view is the only place that records why it closed a session, and the current CI failure (qmux/WebSocket sessions severed at SETUP with close code 4) is invisible without it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
Main added cargo-nextest alongside its justfile switch to nextest (#1947); the merge kept the justfile but the auto-merge dropped the flake tool. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
…n on failure The merge ported main's behavior of tearing down the session when the uni SETUP stream send fails. On dev's protocol that send is best-effort (a failure just means the peer treats us as having no capabilities), and on the qmux/WebSocket transport it can fail benignly. Closing on it turned a tolerable transient into a fatal 'connection closed: 4', which severed every WebSocket/TCP session right after version negotiation. This is the regression behind the failing moq-native broadcast_websocket* and moq-relay internal_tcp_* nextest cases and the smoke matrix's rust/ python publisher legs. Restores dev's best-effort debug-log behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
libmoq.a statically bundles moq-video (openh264/vaapi/cuda). Those worker threads use priority-protected mutexes, and tearing them down at normal process exit can trip glibc's __pthread_tpp_change_priority assertion and abort with a core dump, even though the moq data path already delivered a frame. The client only needs to confirm receipt, so _exit(0) right after, skipping the dependency's atexit teardown. Fixes the flaky rust -> c leg. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
The merge resolution's PublishDecoder::finish() avc3 arm flushed the Annex-B split and decoded the trailing access unit but never called import.finish(), so on stdin EOF the H.264 track was never closed. A downstream subscriber/exporter would hang waiting on the final group instead of seeing end-of-broadcast. The other arms (fmp4/ts/flv) all finalize; origin/main's avc3 TrackStream did split-flush + decode-tail + import.finish(). Restores the missing finish(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfH4fCnLu9WHGdAjwW8L3Y
kixelated
enabled auto-merge (squash)
July 2, 2026 20:16
kixelated
disabled auto-merge
July 2, 2026 20:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge main into dev
Merges
main(63 commits) intodev(137 commits since the last sync). The branches had diverged heavily because several dev crates (moq-mux, moq-hls, moq-rtc, moq-rtmp, moq-srt) were squash-backported to main and then evolved independently on both sides, producing ~180 conflicted files including whole-crate add/add conflicts.Resolution policy
request_broadcast/subscribe,Arc<Info>ownership, two-phase accept, mandatory timestamps, no per-frame compression), and the moq-mux restructure (per-codec splitters,import/module).Main-side features preserved
select::Broadcastrendition selection (replaces dev'scatalog::Filter/Target), fMP4 zero-duration fix (Fix fMP4 zero-duration samples #1933), discontinuity sequence through fMP4 import (moq-hls: preserve discontinuity sequence through fMP4 import #1945), codec/container correctness fixes (fix(moq-mux): codec/container correctness fixes from #1918 review (#1923) #1925).moq(moq-cli: unified endpoint grammar (binary renamed tomoq) #1985),--cors-origin([codex] configure moq-cli CORS origins #1996), per-sink--latency-max(feat(moq-cli): per-sink frame-drop latency for the export gateways #1998), HLS import routed through moq-hls ([codex] Route HLS CLI import through moq-hls #1939). Dev's capture stack, H.264/H.265 elementary sinks, and rendition-selection flags (--video-name/--video-codec/--audio-name/--audio-codec) were ported onto the new grammar.--server-bind(Fold the internal listener into --server-bind (one authenticated accept path) #1974), HTTPS cert arrays ([codex] support relay HTTPS cert arrays #1932). Dev's noq-default backend and composable web router kept.moq-flate/@moq/flate(feat(flate): extract group-scoped DEFLATE into moq-flate / @moq/flate #1905), diffing serializer (perf(moq-json): generate merge patches with a diffing serializer (+ benchmark) #1912), compressed-budget delta gating (refactor(moq-json): gate group rolls on already-written deltas #1909);@moq/qmux0.1.3 reconnect fix (fix(js/net): bump @moq/qmux to 0.1.3 to fix reconnect hang #1957,withoutProtocolreplaced by therequireProtocoldefault); watchreloaddefaults to enabled ([codex] default watch reload to enabled #1984).Deliberate drops (flagged for review)
--video-width-max/--video-height-max/--video-pixels-max/--video-bitrate-max/--audio-bitrate-maxCLI flags: main's moq-mux: API cleanup before the semver bump #1941 deleted thecatalog::Targetsoft-matching API they rode on, so there is no surviving library surface. Can be re-added if targets return./SETUP path validation from feat(moq-net): moq-lite-05 SETUP message + PATH parameter #1954: not ported because dev exposes the raw path viaRequest::path()and stricter validation could break UDS?path=callers. Say the word if you want it enforced on dev.--internal-tier: gone with the[internal]listener fold (Fold the internal listener into --server-bind (one authenticated accept path) #1974); tier now comes from the auth layer (--auth-mtls-tier/ auth APItier). Docs updated.hang::Catalog::compressed_track()(main-only helper): removed; it used the pre-reshapemoq_net::Tracktype and had no callers.COMPRESSED_NAME+default_track_info()cover its use.CI fixes made along the way
connection closed: 4, severing every WebSocket/TCP session right after version negotiation. This broke themoq-native broadcast_websocket*andmoq-relay internal_tcp_*tests and every rust/python publisher leg of the smoke matrix. Reverted to dev's best-effort behavior;lite/session.rsis now byte-identical to dev.bun.lockregenerated to match the merged package.json set.plistpins quick-xml 0.39; only parses local macOS config via netdev), drop the dead bincode ignore.Publish::runcannot ride the JoinSet under--all-features).Filter/TargettoStream::select.cargo-nextest(main added it with the justfile's nextest switch; the auto-merge dropped it).subscribe_media(feat(moq-ffi)!: defer dynamic track accept so media tracks declare a timescale #1761 made it a coroutine; fix(smoke): update interop clients to the current dev APIs #1952 fixed onlysubscribe_catalog); the C client link gets-lstdc++ -lva -lva-drmfor the openh264/vaapi objects inlibmoq.a; publisher + relay logs are dumped on failure.Verification
cargo check --workspace --all-targets,cargo clippy -D warnings,cargo doc -D warnings,cargo fmt/sortpass locally (excludingmoq-video's nvenc/vaapi defaults andmoq-gst, which need CUDA/libva/GStreamer system libs absent in the sandbox;moq-video --no-default-featuresand the capture-feature moq-cli build pass).[::]:0won't bind), so they were verified by root-causing against CI plus the byte-for-byte revert to dev; CI has IPv6 and exercises them.bun run checkpasses for all JS packages including the demo;bun testpasses 454/454.moq import avc3/moq export fmp4).nvidia-video-codec-sdkgit patch entry is intentionally absent fromCargo.lock, matching dev's state (the fork is unreachable from the sandbox).Cross-package sync
Docs updated alongside code:
doc/bin/cli.md(newmoqgrammar),doc/bin/relay/config.md(--server-bindfold, tier flags),doc/concept/layer/hang.md,doc/lib/rs/crate/moq-mux.md,rs/CLAUDE.md(crate map: moq-cli/moq-rtc roles),demo/pub/justfile. The swift/kt/go/py wrappers had no conflicting changes; note that main's #1978 (TLS system root control in moq-ffi) shipped without wrapper/doc updates on main, so that gap predates this merge.(Written by Claude Fable 5)