Skip to content

feat(obs): disable simulcast rungs the grant cannot fund - #7029

Merged
kixelated merged 27 commits into
mainfrom
quest/m1/simulcast-rung-disable
Nov 3, 2026
Merged

kixelated merged 27 commits into
mainfrom
quest/m1/simulcast-rung-disable

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Quest: quest/m1/simulcast-rung-disable.md. This PR lands the OBS rung disable and rewrites the quest to the remaining shaped-uplink proof.

Summary

  • OBS follows the shared rule instead of mirroring it. cpp/obs/src/moq-rate.h (a C++ copy of moq_mux::rate::Control without the rung rule) and its test are deleted. Each retunable video encoder follows its reservation through moq-ffi's new MoqRateControl, which wraps moq_mux::rate::Control and reads both the grant and whether a session probes for it.
  • Ladder from the output's encoders. Every video encoder on the output encodes the same program. An encoder's lower rendition is the one with the next lower configured bitrate. That track is published first (recursively), so the higher one sits one track priority below it and the allocator funds the lower one first.
  • Disable and resume. A Disabled target marks a discontinuity (once the track has written a frame), sets the catalog enabled: false, and drops the encoder's packets. OBS cannot stop one encoder of a live output or force it to keyframe. After an Enabled target, the rung resumes at the encoder's next natural keyframe with enabled: true. Stop restores the configured bitrate whenever the applied one moved.
  • FFI (rs/moq-ffi):
    • MoqRateControl / MoqRatePolicy { max_bps, lower_bps } / MoqRateTarget { Enabled { bitrate_bps }, Disabled }. update(&MoqReservation) feeds the current grant and probe state on the ambient clock, for a sender that is driven per frame.
    • MoqVideoInit.lower: Option<MoqMediaTrackProducer> publishes a pre-encoded track one priority below the lower video track. A lower audio track is refused.
    • MoqMediaTrackProducer::set_enabled(bool) flips the catalog enabled of a video track. An audio track refuses.
  • moq-mux: import::VideoInit.priority (defaults to PRIORITY.video), import::Track::set_enabled (video only, Error::WrongKind for audio), and set_enabled on the AV1, VP8, and VP9 importers, matching H.264/H.265.
  • Bindings: Python (RateControl, RateTarget, TrackProducer.set_enabled, lower= on both video importers), Swift (same), Go (RateControl, RatePolicy, RateTarget*, TrackProducer.SetEnabled, and media.VideoInit as a struct with Lower *TrackProducer), Kotlin and Dart aliases, and regenerated Dart bindings. doc/lib/* and doc/bin/obs.md describe the pre-encoded path and the OBS ladder.
  • Quest: rewritten to the shaped-uplink proof. BBR3 aging has since landed, so it has no Required; its Plan uses main's rate-stepping moq-shaper profiles (cellular-step). Summaries in quest/m1/README.md and quest/m2/probe/README.md are updated.

Impact

  • Wire: none (enabled is already in the catalog).
  • Additive, FFI: MoqRateControl, MoqRatePolicy, MoqRateTarget, MoqMediaTrackProducer::set_enabled, and MoqVideoInit.lower (UniFFI default None; nullptr in C++).
  • Additive, moq-mux: import::VideoInit::priority (the struct is #[non_exhaustive] with a constructor), import::Track::set_enabled, and {av1,vp8,vp9}::Import::set_enabled.
  • Breaking, Go wrapper: media.VideoInit is a struct rather than an alias of the generated record. Composite literals with Format, Data, Label, and Hint compile unchanged. A MIGRATE note is added.
  • Behavior, OBS: with several video encoders, a higher one now publishes at a lower track priority and stops sending while its grant cannot fund it. With one encoder, nothing changes.
  • Not changed: the C ABI (rs/moq-c, c/moq). OBS uses the generated moq-ffi package, so nothing consumes a C equivalent yet (see decision 4).

Decisions settled

The maintainer accepted every recommendation in a /quest-complete session:

  1. Rate rule for OBS: MoqRateControl in moq-ffi wraps moq_mux::rate::Control, replacing the C++ MoQRate mirror (done here).
  2. Pre-encoded track priority: the MoqVideoInit.lower handle, matching MoqVideoProducerOptions.lower, not an explicit priority (done here). MoqMediaTrackStreamProducer::video accepts lower too, but a stream producer cannot itself be passed as one.
  3. Only retunable encoders disable: a rung needs OBS_ENCODER_CAP_DYN_BITRATE and CBR/VBR/ABR to get a RateControl. A CQP/CRF or non-retunable top encoder still sits one priority below its lower one but never disables.
  4. C ABI parity: left to a follow-up quest until a C consumer needs it.

Choices made

  • Disabled packets are dropped and the rung resumes at the encoder's next natural keyframe, rather than restarting the encoder. OBS cannot stop or keyframe one encoder of an active output, so the resume waits up to one keyframe interval.
  • The lower rendition's ceiling is the configured bitrate that rendition recorded at init, not its live settings, which the grant may already have retuned.
  • MoqRateControl::update takes the reservation, not a grant plus a probe flag, so a caller can't forget the probe gate. MoqReservation::probed therefore stays unexported.
  • A rung disabled before its first frame skips the discontinuity marker. The marker resets the splitter, which still holds the extra data's SPS/PPS until a keyframe adopts them, and an encoder that sends headers only as extra data (OBS's x264) never repeats them. There is no timeline to break yet anyway.
  • The OBS ladder test drives Retarget directly with no encoder following. A localhost session's real grant would otherwise move the targets mid-test. The rule itself is covered by moq_mux::rate's tests and model.

Follow-ups

  • C ABI rung disable for pre-encoded media (decision 4): moq_publish_media_set_enabled, the media track's lower/priority, and a C rate control over moq_reservation, with doc/lib/c.
  • Raw-stream simulcast rungs: MoqMediaTrackStreamProducer can't be passed as a lower, and it has no set_enabled, so a ladder made only of byte-stream producers can't link priorities or disable a rung. Parity needs the stream producer to record its priority, to export set_enabled, and a lower type that accepts either producer. Raised by CodeRabbit (r4436515610).

Checks

On head b4dff1fa37 (main at 622d7bc0c5 merged):

  • just ci origin/main (inside nix develop, via quest gate) on 95ce36573e: every module passed (check rs, test rs, check py, test py, check c, check cpp, check obs_compile, check go, check kt, check js, test js, and the lint modules). check dart failed because the merged generated bindings were stale. 0238c502f2 regenerates them, and check dart then passes. Swift was skipped locally because Linux has no Swift toolchain.
  • b4dff1fa37 is a conflict-free merge of origin/main that touches only moq-quic, moq-uring, quest files, and the lockfile. None of these overlap this PR.
  • quest check --base origin/main: ok.
  • just obs test (TSan) on c672fbec30: every MoQOutput, moq_source, and settings test passes. The only cpp/obs change since is main's 01c6e7e80f (CMake qlog option), and check obs_compile and check cpp pass on the merged tree.

Land history

  • 16:36Z merge_conflict (MIGRATE.md, Kotlin aliases, quest Plan, Swift Media.swift): resolved here. Main's moq-dev/moq#7319 formatting gates reflowed the Swift and Kotlin, and main's moq-dev/moq#7334 made moq-shaper step its rate, so the quest Plan now uses that instead of asking for it.
  • The land fixer pushed an equivalent merge (0b4f430067) at 16:41Z; this branch merges it with -s ours (same parents, this resolution kept) rather than force-pushing.
  • 16:55Z batch test rs failed (exit 101) on 0b4f430067. The posted log is truncated before nextest's summary, so the failing test is not visible. test rs passes locally on the same tree content and on the newer base three times, so it looks like a flake or another batch member.
  • 18:15Z iterate: CI on dc718e72c4 passed (5/5), and after this branch merged main at 951cca678c the full local just ci gate passed, test rs included. Nothing on this branch reproduces the batch failure, so the code is unchanged. The CodeRabbit thread on rs/moq-ffi/src/media.rs:375 is refuted (reply) and listed under Follow-ups.
  • 2026-11-02 iterate: auto-merge was disabled (it had been enabled at 40abd59716 under the old landing flow, and the PR has conflicted with main since). Main has no equivalent change (moq-rate.h and the quest are still there), so the PR still applies. Merged origin/main (41f60ec46e). go/wrapper/MIGRATE.md keeps both entries, this PR's media.VideoInit note and main's moq-dev/moq#7484 captures note. py/moq-rs/moq/types.py keeps RateTarget and takes main's move of Range (main now imports it with Timestamp). The Dart bindings were regenerated (0238c502f2), and main was merged again at 622d7bc0c5 (conflict-free). No new automated review findings were posted since the last iterate, and the one CodeRabbit thread stays refuted.

Review

  • Reviewer: Codex (quest review), gpt-6.1-sol, medium effort, new session 01a19f99 (the whole branch against origin/main at 622d7bc0c5). The previous session 01a19810 is keyed to a local branch that another worktree has checked out, so this one starts fresh and reviews everything.
  • Round 1 on 95ce36573ef9ac9bace677e19df2f31530999dfa: no findings.
  • Round 2 on b4dff1fa3762ecb94935cdc5fcd0591818442c90 (the regenerated Dart bindings and a conflict-free merge of main): no findings.
  • Earlier sessions: Codex, gpt-6.1-sol, medium. Session 01a19810 round 1 on c672fbec30: none. Session 01a195f3 round 1 on d7e63636f6: none. Session 01a19158 on 11481709 found one issue, fixed in 92046c6bfd, then none. CodeRabbit's cpp/obs/src/moq-output.cpp:694 finding was fixed in a7959e2e74, and its doc/bin/obs.md:49 finding in 11481709. Its rs/moq-ffi/src/media.rs:375 finding (a raw-stream producer as lower) is refuted on decision 2 (reply), and CodeRabbit withdrew it. It is listed under Follow-ups.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 3 commits October 27, 2026 23:36
OBS follows each video encoder's grant through moq-ffi's new MoqRateControl,
the same moq_mux::rate::Control the native publishers use, replacing the C++
MoQRate mirror. A rung above a lower encoder sits one track priority below it
(MoqVideoInit.lower), drops its packets while disabled (catalog enabled=false
via MoqMediaTrackProducer::set_enabled), and resumes at the next keyframe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Python, Swift, and Go wrap MoqRateControl, MediaTrackProducer.set_enabled,
and the video init's lower rendition; Kotlin and Dart alias them. The docs
describe the pre-encoded path and the OBS ladder, and the quest is rewritten
to the remaining shaped-uplink proof, which requires BBR3 aging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title OBS disables simulcast rungs the grant cannot fund, proven on a shaped uplink feat(obs): disable simulcast rungs the grant cannot fund Oct 28, 2026
@kixelated
kixelated marked this pull request as ready for review October 29, 2026 15:49
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The change adds reservation-based rate control with enabled or disabled sender targets and optional lower-rendition bitrate policies. Video producer APIs can link renditions to set relative priority and change a track’s advertised enabled state. Rust FFI and language bindings expose these APIs. OBS applies rate targets to encoders, initializes linked tracks in dependency order, and resumes disabled tracks on keyframes. Tests cover rendition priority, disablement, and resumption.

Merge Risk: Moderate · up to 0b4f4

Raw-stream simulcast ladders cannot use the new linked-priority behavior, and a failed OBS resume can leave a rendition advertised as available. Resolve these issues before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 62.96% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: disabling simulcast rungs when their grant cannot fund them.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description is clearly related to the changeset. It names the quest document it lands against and explains that the OBS C++ rate copy (cpp/obs/src/moq-rate.h and its test) is removed in favor of m…
Full details: Description check

Explanation

The description is clearly related to the changeset. It names the quest document it lands against and explains that the OBS C++ rate copy (cpp/obs/src/moq-rate.h and its test) is removed in favor of moq-ffi's MoqRateControl. It also covers the ladder and disable/resume logic in the OBS output, the new moq-ffi, moq-mux, and binding APIs (Python, Swift, Go, Kotlin, Dart), the Go VideoInit struct change, and the documentation updates. These match the raw summary. The description also lists decisions, test runs, and review history, which adds detail beyond what the check requires.

Full details: Docstring Coverage

Explanation

Docstring coverage is 62.96% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 27 functions across 21 files. (4 skipped: 4 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • 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

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
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: 9779b9f6-c493-4b7f-9c62-013f2b008fa8
Commits

Reviewing files that changed from the base of the PR and between e8f805a and 0b4f430.

Files selected for processing: 10
  • dart/moq_ffi/lib/src/moq.dart
  • go/wrapper/MIGRATE.md
  • go/wrapper/media/media.go
  • kt/moq/src/jvmAndAndroidMain/kotlin/dev/moq/Aliases.kt
  • py/moq-rs/moq/media.py
  • quest/m1/README.md
  • quest/m1/simulcast-rung-disable.md
  • rs/moq-ffi/src/media.rs
  • rs/moq-ffi/src/test.rs
  • swift/Sources/Moq/Media.swift
Files skipped from review as they are similar to previous changes: 2
  • quest/m1/README.md
  • go/wrapper/MIGRATE.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 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-31T03:59:34.182222Z c8a11af 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: fc15a13e01

ℹ️ 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 cpp/obs/src/moq-output.cpp Resolved

@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: fc15a13e01877256923d6fa88be6d6d7d2c8887c.

No actionable bugs found in the OBS disable/resume path, lower-rendition priority propagation, mux enabled setters, or the FFI/wrapper changes. The discontinuity path preserves cached codec parameters while clearing partial frames, and OBS waits for a natural keyframe before advertising the rung enabled again.

Direction: replacing the duplicated C++ rate rule with the shared Rust control is a good simplification. Keeping the configured ceiling separate from the applied bitrate also makes stop-time restoration and ladder discovery clearer. The deferred shaped-uplink proof remains important: the targeted OBS test drives Retarget directly, so it does not establish the complete grant/probe/encoder feedback loop or BBR3 recovery behavior.

Verification: static GitHub review of the changes and relevant surrounding code, including an independent FFI/bindings pass. No tests, binding builds, real OBS runs or shaped-network experiments performed; reported validation was not independently reproduced.

kixelated and others added 2 commits October 29, 2026 18:12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A higher rung's first packet started its lower rung's track, before an
encoder that supplies parameter sets only after its first frame had them,
so the lower track was cached without them. Wait for the lower's own first
packet instead, and open every track on a keyframe.

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

@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: 20a56a3.

The direct two-rung startup case reported in #7029 (comment) is addressed, with focused header-readiness and initial-keyframe coverage. Deferring publication is the right direction, but one P2 remains inline: recursive deferral must propagate through a three-rung ladder rather than permanently publishing the top rung without its lower relation.

GitHub-only static delta and surrounding-code/test review. No OBS tests, builds, binding checks, or shaped-uplink experiments were run. The remaining end-to-end bandwidth proof is not established by the targeted fixture.

(Written by OpenAI)

Comment thread cpp/obs/src/moq-output.cpp Resolved
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

Prior P2 fixed: the recursive startup-deferral finding is addressed. After recursive initialization, an absent lower track now defers its caller too, so the top rung cannot be cached without its lower relation. The expanded 8/4/2 Mbps fixture delays the bottom headers and verifies both priority steps once startup resumes. The earlier direct two-rung header fix remains intact.

No new actionable bugs found in this delta. The narrow propagation check is a sound, simpler fix than repairing already-published tracks. Compared against the previous reviewed commit 20a56a3; the only intervening commit changes this check and its regression fixture.

Verification: static GitHub delta and surrounding VideoInit/VideoData/test review. No OBS tests, builds, binding checks or shaped-uplink experiments were run; the fixture does not establish the deferred end-to-end grant/probe/encoder feedback proof.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for ba63bd17c7:

  • Merged main and resolved the conflicts: MediaProducer keeps the PR's video priority but drops its cached demand, since main now reads demand() from the importer each time (#7110). Kept both MIGRATE.md entries and both new moq-ffi tests, and regenerated the Dart bindings. The quest drops its BBR3-aging blocker, which #7017 landed.
  • Codex finding (r4414612631): a higher rung no longer starts its lower rung's track before the lower encoder has its headers. It waits for the lower's first packet, and every video track opens on a keyframe.
  • Follow-up finding (r4419539590): that wait now carries up the whole ladder. The test covers an 8/4/2 ladder with the bottom headers delayed.
  • Ran locally: the OBS unit tests (plain), cargo test/clippy -D warnings for moq-ffi, cargo fmt, clang-format, and quest check.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 30, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for d637f98cee:

  • The old GitHub merge queue ejected ba63bd17c7 as merge_conflict. Merged main (80cafb3afe) locally. Git resolved every overlap, including the quest link lists, so no conflict was hand-resolved. The regenerated Dart bindings (just dart generate) match the merged moq.dart exactly.
  • Ran locally: cargo nextest run -p moq-mux -p moq-ffi (2158 passed), just go check, and quest check --base origin/main.
  • Codex reviewed the merged head (quest review, gpt-6.1-sol, medium) and found nothing. The body's ## Review records it.
  • Queuing for quest land (squash).

(Written by Claude Opus 5.5)

@moq-bot

moq-bot Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

quest land removed this pull request from the queue: the batch check failed (exit 1).

  test_core 0.6.20 (0.6.21 available)
  vm_service 15.3.0 (15.4.0 available)
  web 1.1.1 (1.1.2 available)
Got dependencies!
14 packages have newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 105.0.0 (111.0.0 available)
  analyzer 14.1.0 (14.7.0 available)
  code_assets 2.0.0 (2.1.0 available)
  coverage 1.15.1 (1.16.0 available)
  crypto 3.0.7 (3.0.8 available)
  frontend_server_client 4.0.0 (4.2.0 available)
  http_multi_server 3.2.2 (3.2.3 available)
! moq_ffi 0.0.0-dev from path ../moq_ffi (overridden)
  shelf 1.4.2 (1.4.3 available)
  shelf_static 1.1.3 (1.2.0 available)
  test 1.32.0 (1.33.0 available)
  test_api 0.7.14 (0.7.15 available)
  test_core 0.6.20 (0.6.21 available)
  vm_service 15.3.0 (15.4.0 available)
  web 1.1.1 (1.1.2 available)
Got dependencies!
14 packages have newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.
Publishing moq 0.1.0 to https://pub.dev:
├── CHANGELOG.md (<1 KB)
├── LICENSE (1 KB)
├── MIGRATE.md (16 KB)
├── README.md (1 KB)
├── analysis_options.yaml (<1 KB)
├── bench
│   └── ffi.dart (5 KB)
├── lib
│   ├── audio.dart (2 KB)
│   ├── json.dart (2 KB)
│   ├── media.dart (4 KB)
│   ├── moq.dart (<1 KB)
│   ├── src
│   │   ├── aliases.dart (7 KB)
│   │   ├── client.dart (10 KB)
│   │   ├── durations.dart (<1 KB)
│   │   ├── epoch.dart (<1 KB)
│   │   ├── server.dart (5 KB)
│   │   ├── stream.dart (2 KB)
│   │   └── version.dart (<1 KB)
│   └── video.dart (3 KB)
├── pubspec.yaml (<1 KB)
└── test
    ├── cancellation_test.dart (7 KB)
    ├── docs
    │   ├── prelude.dart (<1 KB)
    │   └── samples.dart (4 KB)
    └── moq_test.dart (24 KB)

Total compressed archive size: 29 KB.
Validating package...
Package validation found the following hint:
* Non-dev dependencies are overridden in pubspec.yaml.
  
  This indicates you are not testing your package against the same versions of its
  dependencies that users will have when they use it.
  
  This might be necessary for packages with cyclic dependencies.
  
  Please be extra careful when publishing.
The server may enforce additional checks.

Package has 0 warnings and 1 hint.
ci: check py failed
ci: check gh failed
ci: seconds per module
   237  check py (failed)
   831  check rs
   337  test rs
  1049  check rs_shapes
   425  check c
   192  check cpp
    22  check obs_compile
   260  check js
    57  test js
    17  check markdown
     1  check gh (failed)
   223  check kt
    51  check flake
     1  check swift
    85  check go
     0  check drill
     2  check quest
     3  check obs
     1  check ts_paths
    17  check shell
     0  check large_files
     1  check toml
     0  check nix
     0  check justfile
   118  check dart
  2336  wall time
error: recipe `ci` failed on line 104 with exit code 1

.

@moq-bot
moq-bot Bot disabled auto-merge November 1, 2026 16:55
@moq-bot moq-bot Bot removed the quest:merge label Nov 1, 2026
@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

quest land removed this pull request from the queue: the batch check failed (exit 101).

…�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/moq-pattern#0.1.2 not found in Cargo.lock
�[2m2026-11-01T16:55:01.504988Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/moq-net/fuzz#moq-net-fuzz@0.0.0 not found in Cargo.lock
�[2m2026-11-01T16:55:01.543130Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/kio#0.6.2 not found in Cargo.lock
�[2m2026-11-01T16:55:01.543181Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/kio/macros#kio-macros@0.1.0 not found in Cargo.lock
�[2m2026-11-01T16:55:01.543194Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/moq-congestion#0.1.0 not found in Cargo.lock
�[2m2026-11-01T16:55:01.543205Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/moq-quic#0.1.0 not found in Cargo.lock
�[2m2026-11-01T16:55:01.544838Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mcargo_cyclonedx::generator�[0m�[2m:�[0m Hash for package ID path+file:///work/rs/moq-quic/fuzz#moq-quic-fuzz@0.0.0 not found in Cargo.lock
�[2m2026-11-01T16:55:01.630278Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mgenerate�[0m: �[2mmaturin::sbom�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m2.99s �[3mtime.idle�[0m�[2m=�[0m2.80µs
�[2m2026-11-01T16:55:01.674598Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m:�[1mcompile_cdylib�[0m: �[2mmaturin::compile�[0m�[2m:�[0m Setting crate_type to cdylib for Rust >= 1.64.0
�[2m2026-11-01T16:55:01.676724Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m:�[1mcompile_cdylib�[0m: �[2mmaturin::compile�[0m�[2m:�[0m Running env -u CARGO "cargo" "rustc" "--features" "testing,openh264" "--message-format" "json-render-diagnostics" "--locked" "--manifest-path" "/work/rs/moq-ffi/Cargo.toml" "--lib" "--crate-type" "cdylib"
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.14s
mbx[savings]: the running total stands at 11d 57m across 13447 builds. nobody is counting except the box.
�[2m2026-11-01T16:55:03.238680Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m:�[1mcompile_cdylib�[0m: �[2mmaturin::build_orchestrator�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m1.56s �[3mtime.idle�[0m�[2m=�[0m8.83µs
🚉 Overriding platform tag from _PYTHON_HOST_PLATFORM environment variable as linux_x86_64.
�[2m2026-11-01T16:55:03.444416Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mglobset�[0m�[2m:�[0m glob `Glob("**/moq_ffi/_uniffi/**/*")` converted to regex: `"(?-u)^(?:/?|.*/)moq_ffi/_uniffi(?:/|/.*/)[^/]*$"`
�[2m2026-11-01T16:55:03.444554Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mglobset�[0m�[2m:�[0m glob `Glob("**/__pycache__/**/*")` converted to regex: `"(?-u)^(?:/?|.*/)__pycache__(?:/|/.*/)[^/]*$"`
�[2m2026-11-01T16:55:03.444614Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mglobset�[0m�[2m:�[0m built glob set; 0 literals, 0 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 2 regexes
�[2m2026-11-01T16:55:03.448624Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::build_context::repair�[0m�[2m:�[0m copy_back_cargo_outputs: copied unpatched /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/libmoq_ffi.so -> /work/target/py/debug/libmoq_ffi.so
�[2m2026-11-01T16:55:20.138962Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::binding_generator::uniffi_binding�[0m�[2m:�[0m Running cd "/work" && env -u CARGO_BUILD_TARGET "cargo" "run" "--bin" "uniffi-bindgen" "--features" "cli" "generate" "--no-format" "--language" "python" "--out-dir" "/home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/uniffi/moq_ffi._uniffi" "--config" "/work/rs/moq-ffi/uniffi.toml" "--library" "/home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/libmoq_ffi.so"
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.98s
     Running `target/py/debug/uniffi-bindgen generate --no-format --language python --out-dir /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/uniffi/moq_ffi._uniffi --config /work/rs/moq-ffi/uniffi.toml --library /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/libmoq_ffi.so`
warning: /work/rs/moq-ffi/uniffi.toml looks like an old-style --config override file. The --config flag now expects a global config file with [defaults], [crates.<name>], and/or [crate-roots] sections. Old-style flat config files are no longer supported.
writing out /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/uniffi/moq_ffi._uniffi
writing /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/uniffi/moq_ffi._uniffi/moq.py
�[2m2026-11-01T16:55:25.127345Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::binding_generator�[0m�[2m:�[0m Removing previously built module /work/py/moq-ffi/moq_ffi/_uniffi/libmoq_ffi.so
�[2m2026-11-01T16:55:25.127465Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::binding_generator�[0m�[2m:�[0m Installing /work/py/moq-ffi/moq_ffi/_uniffi/libmoq_ffi.so from /home/check/mbx-targets/check/v1/7a4aae51b2e53b173e0e88b328d8b5d16a3ff418f0f523578c8ab24ae8dfd401/py/maturin/libmoq_ffi.so
�[2m2026-11-01T16:55:25.127640Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::binding_generator�[0m�[2m:�[0m Generating file /work/py/moq-ffi/moq_ffi/_uniffi/__init__.py
�[2m2026-11-01T16:55:25.127798Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::binding_generator�[0m�[2m:�[0m Generating file /work/py/moq-ffi/moq_ffi/_uniffi/moq.py
�[2m2026-11-01T16:55:25.129723Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer�[0m�[2m:�[0m Adding moq_ffi.pth from /work/py/moq-ffi
�[2m2026-11-01T16:55:25.129741Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi.pth"
�[2m2026-11-01T16:55:25.130287Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi-0.4.12.dist-info/sboms/moq-ffi.cyclonedx.json"
�[2m2026-11-01T16:55:25.130325Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi-0.4.12.dist-info/METADATA"
�[2m2026-11-01T16:55:25.130334Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi-0.4.12.dist-info/WHEEL"
�[2m2026-11-01T16:55:25.130341Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi-0.4.12.dist-info/licenses/LICENSE-APACHE"
�[2m2026-11-01T16:55:25.130345Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::virtual_writer�[0m�[2m:�[0m Tracked entry "moq_ffi-0.4.12.dist-info/licenses/LICENSE-MIT"
�[2m2026-11-01T16:55:25.245807Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::module_writer::wheel_writer�[0m�[2m:�[0m Adding moq_ffi-0.4.12.dist-info/RECORD
📦 Built wheel to /tmp/.tmpkkewoX/moq_ffi-0.4.12-py3-none-linux_x86_64.whl
�[2m2026-11-01T16:55:25.246124Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m:�[1mbuild_uniffi_wheel�[0m: �[2mmaturin::build_orchestrator�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m23.6s �[3mtime.idle�[0m�[2m=�[0m5.34µs
�[2m2026-11-01T16:55:25.246212Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m:�[1mbuild_wheels_inner�[0m: �[2mmaturin::build_orchestrator�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m26.6s �[3mtime.idle�[0m�[2m=�[0m851ns
�[2m2026-11-01T16:55:25.246219Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1mbuild_wheels�[0m: �[2mmaturin::build_orchestrator�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m26.6s �[3mtime.idle�[0m�[2m=�[0m892ns
✏️ Setting installed package as editable
�[2m2026-11-01T16:55:25.887472Z�[0m �[34mDEBUG�[0m �[1mdevelop_cmd�[0m:�[1minstall_wheel�[0m:�[1mconfigure_as_editable�[0m: �[2mmaturin::develop�[0m�[2m:�[0m running UV_PYTHON="/work/.venv/bin/python" "uv" "pip" "show" "--files" "moq-ffi" �[2m�[3mwheel_filename�[0m�[2m=�[0m/tmp/.tmpkkewoX/moq_ffi-0.4.12-py3-none-linux_x86_64.whl�[0m
�[2m2026-11-01T16:55:25.989103Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1minstall_wheel�[0m:�[1mconfigure_as_editable�[0m: �[2mmaturin::develop�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m109ms �[3mtime.idle�[0m�[2m=�[0m2.12µs �[2m�[3mwheel_filename�[0m�[2m=�[0m/tmp/.tmpkkewoX/moq_ffi-0.4.12-py3-none-linux_x86_64.whl�[0m
�[2m2026-11-01T16:55:25.989138Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m:�[1minstall_wheel�[0m: �[2mmaturin::develop�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m743ms �[3mtime.idle�[0m�[2m=�[0m582ns �[2m�[3mwheel_filename�[0m�[2m=�[0m/tmp/.tmpkkewoX/moq_ffi-0.4.12-py3-none-linux_x86_64.whl�[0m
🛠 Installed moq-ffi-0.4.12
�[2m2026-11-01T16:55:26.001915Z�[0m �[32m INFO�[0m �[1mdevelop_cmd�[0m: �[2mmaturin::commands::develop�[0m�[2m:�[0m close �[3mtime.busy�[0m�[2m=�[0m29.9s �[3mtime.idle�[0m�[2m=�[0m3.72µs
DEBUG Command exited with code: 0
uv pip install --no-deps -e moq-rs
Using Python 3.14.8 environment at: /work/.venv
Resolved 1 package in 1ms
   Building moq-rs @ file:///work/py/moq-rs
      Built moq-rs @ file:///work/py/moq-rs
Prepared 1 package in 6.42s
Installed 1 package in 7ms
 + moq-rs==0.6.0 (from file:///work/py/moq-rs)
bash ../sh/local.sh uv run --no-sync pytest moq-rs/tests/ moq-ffi/tests/
error: recipe `test` failed on line 65 with exit code 143
ci: test rs failed
ci: seconds per module
   321  check py
    38  test py (cancelled)
    80  check rs
   279  test rs (failed)
   359  check c (cancelled)
   360  wall time
error: recipe `ci` failed on line 107 with exit code 101

.

@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer: This maintainer pick already used its mechanical fi·x attempt. Run /quest-iterate to diagnose the repeated failure, then pick it again.

(written by codex / Codex)

kixelated and others added 2 commits November 1, 2026 09:06
Both merge e8f805a with 802cadc; keep this branch's resolution (swift-format layout, combined shaper bullet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 3 commits November 2, 2026 19:59
…ng-disable

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng-disable

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

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

No new actionable defects found. OBS behavior, rate policy and regression tests remain unchanged. The regenerated Dart disposal allocates status before marking the object disposed and detaching its finalizer, preserving ownership if allocation fails; the remaining changes are largely base adaptations and formatting.

Verification: static GitHub comparison and wrapper inspection only; no builds or tests run.

@kixelated
kixelated added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 61cb704 Nov 3, 2026
8 of 9 checks passed
@kixelated
kixelated deleted the quest/m1/simulcast-rung-disable branch November 3, 2026 05:28
kixelated added a commit that referenced this pull request Nov 3, 2026
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