Skip to content

fix(quic): a paused stream holds only its stream window - #8794

Merged
moq-bot[bot] merged 7 commits into
mainfrom
fix/quic-paused-stream-window
Nov 15, 2026
Merged

moq-bot[bot] merged 7 commits into
mainfrom
fix/quic-paused-stream-window

Conversation

@kixelated

@kixelated kixelated commented Nov 15, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

A bulk transfer through a relay over QUIC or WebTransport could end Evicted partway, even with a writer awaiting group::Producer::ready and a single reader that keeps reading (found validating moq tcp in #8741, since removed).

moq-net's ingest paces a group by its fastest reader: when the reader falls behind, ingest stops reading the stream, so flow control pushes back to the publisher. It charges a paused stream its stream window (1 MiB by default) against half the connection window (4 MiB). moq-quic broke that assumption. It granted MAX_STREAM_DATA from the bytes a lease moved out of the receive buffer, not the bytes the reader took, and every lease moves everything that has arrived. So a stream that ingest stopped reading kept granting credit until it held the whole connection window. Then the stuck-window pass evicted it. The trace: the paced stream held 3.9 MB of lease plus 0.3 MB unread, against a 4 MiB connection window.

Approach

In moq-quic, stream credit now starts from what the reader took: assembler.bytes_read() minus the leased bytes it has not taken yet (Leased::untaken, which includes bytes out in a Lease). Handing a lease back queues MAX_STREAM_DATA for what was taken. A reader that stops taking now holds its stream window and no more, which is what ReceiveWindow and moq-tokio's DEFAULT_STREAM_RECEIVE_WINDOW docs already promised.

A reader waiting for a unit larger than the stream window (lease(want)) gets credit for the whole unit, which the connection window still bounds. The credit is sent even when the increase is below the usual eighth-of-a-window threshold, because nothing the reader takes while it waits would add to it. Without that, a reader waiting on a unit a few bytes past its credit deadlocks.

moq-net's charge also misses one more hold. poll_read_frame keeps the credit of the bytes it took into a frame's unsealed segment (up to 1 MiB) until the segment seals, and a stream paused mid-segment keeps that credit beside its stream window. coding::Reader now counts those bytes, and Pause::pause(taken) reserves stream window + taken (Pullfrog's finding).

The repro is a moq-relay sim test over simulated QUIC. A moq-lite-07-wip socket session sends 40 MB in 8 KiB frames, with the writer awaiting ready, and the reader drains at about 64 MB/s. Before the fix it ends Evicted after 320 KiB.

Impact

  • No public API or wire change. Behavior change in moq-quic (and so in moq-tokio, moq-uring, WebTransport and qmux on top of it): a receive stream's credit tracks what its reader takes, not what it leases.
  • Behavior change in moq-net: a stream paused partway through a segment reserves that segment's taken bytes too, so fewer such streams pause before the cap and the rest read on.

Validation

  • quic_sim::a_socket_session_carries_a_bulk_transfer_losslessly: fails on main with after 327680 bytes: evicted, and passes with the fix (2.5 s). I also ran it locally with 5% loss, duplication and reordering on both client paths, and it passed (not committed, since it takes 18 s).
  • I instrumented StreamsState::evict on main to find the cause: wmd=5555014 recvd=5555014 held=3895495 rw=4194304 unread=298809, all on the paced stream.
  • moq-quic tests: leases_hold_one_stream_window replaces lease_spends_connection_window_only, which asserted the old behavior. It checks that leasing without taking stops at one stream window, and that taking returns stream credit but keeps connection credit until release. a_waiting_reader_gets_room_for_its_unit fails without the below-threshold rule.
  • Segment hold: a sim case with 4 MiB frames (2 to 4 sessions on one connection) paused streams holding up to 1048575 unreleased bytes while charged only the stream window. None of those runs evicted at the default windows, so the regression test is coding::reader::a_pause_mid_segment_reserves_what_it_took, plus a transport::boxed case for the larger charge.
  • just check passes: 12849 tests on the current head (8061 before the segment fix). One earlier run hit an unrelated flake: moq-rtmp server::tests::play_multitrack_to_capable_client fired a host-clock timer under load. It passes alone.
  • Not run on the real binary: no CLI that opens socket sessions is left since moq tcp was removed. The sim test runs moq-relay's real Connection over real moq-quic.

Alternatives

  • Charge a paused stream the whole connection credit it might hold, in moq-net. That would allow at most one paused stream, and moq-net can't see what the transport buffered.
  • Have ingest keep reading while paused, buffering outside the group. That moves the unbounded buffer instead of bounding it.

Follow-ups

  • Every stream partway through a large frame holds up to a segment of connection credit, paused or not. N concurrent large-frame streams therefore need N segments of connection window: a 1.5 MiB window evicted two of them in the sweep. That concurrency budget is kixel.ai's paused-credit quest, alongside the paused-credit cap.
  • More concurrent paused streams than the paused-credit cap (half the connection window, so two at moq-tokio's defaults) still read on and shed, per the decision in feat(net): pace relay ingest by the group's fastest reader #7388. kixel.ai plans this as a quest for its byte streams, since live media expects a slow reader to fall off.
  • The moq-rtmp host-timer flake above.

Caused by

Models

Size: M
Implementer: Claude Code, claude-opus-5-5, unknown effort (arm A)
Implementer: Claude Code, claude-opus-5-5, unknown effort (iterate, M, arm A)

(Written by Opus 5.5)

🤖 Generated with Claude Code

Review

mechanical fix by codex, gpt-6.1-sol, medium effort: Merged base and mechanically migrated new tests to its group/start and timestamp APIs; ran nix develop --command just ci base (12832 tests passed) and git diff --check base. (head 2d68e88)

Rewritten by quest review after each round.

  • Head: 3e5aff9

  • Base: origin/main at 77b8ec7

  • Risk: medium, the base has no RISK.md to name what is always high or customer-facing, so every change is medium

  • Classified: medium by default

  • Reviewer: Codex, gpt-6.1-sol, high effort

  • Session: 01a1de3b-898d-71c2-b3b9-c2921f26ae89, round 1

  • Score: 9/10, Receive-credit accounting appears consistent across leasing and pacing, with no actionable defects found; builds and tests were not run, as instructed.

  • Rounds: 1; first round 0; findings 0: fixed 0, refuted 0, open 0

  • Findings: none

  • Reviewer: Codex, gpt-6.1-sol, medium effort, shadow

  • Session: 01a1de3b-8988-7b01-ba53-d43247d8d25a, round 1

  • Score: 9/10, Source review found no actionable defects and supports landing, but builds and tests were not run as instructed.

  • Rounds: 1; first round 0; findings 0: fixed 0, refuted 0, open 0

  • Findings: none

kixelated and others added 2 commits November 14, 2026 22:26
Stream credit ran from the bytes a lease moved out of the assembler, not the
bytes its reader took, so a reader that leased and then stopped taking kept
granting the peer more, up to the connection window. moq-net's ingest pauses
a stream exactly that way to pace a slow reader, assuming it holds at most its
stream window, so a paced stream filled the connection window and the stuck
window evicted it: a bulk transfer through a relay ended Evicted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 15, 2026 07:11

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No critical issues — one gap worth a follow-up inline.

Reviewed changes

I reviewed the whole PR: moq-quic now grants stream credit from the bytes a reader takes, not the bytes it leases, and adds tests at the moq-quic and relay-sim levels.

  • Stream credit from taken bytes: Recv::max_stream_data now starts from bytes_read - Leased::untaken(), and the new lent field counts bytes that are out in a Lease, so a stream that ingest stops reading holds back its stream credit.
  • Room for a waiting unit: a reader blocked on lease(want) gets max(stream_window, want), and the short rule sends that credit even below the eighth-of-a-window threshold, which fixes the deadlock a few bytes past the limit.
  • Credit on hand-back: put_back (restore/release) and the Blocked branch of lease_inner now queue MAX_STREAM_DATA through the new queue_max_stream_data.
  • Tests: leases_hold_one_stream_window replaces the test that asserted the old behavior, a_waiting_reader_gets_room_for_its_unit covers the below-threshold rule, and a_socket_session_carries_a_bulk_transfer_losslessly reproduces the eviction through a relay over simulated QUIC.

I checked these and found no problem:

  • assembler.clear() keeps bytes_read, so the subtraction can't underflow after a stop or eviction.
  • An arrived() that clears want before the queued frame is written fixes itself when the reader leases again.
  • Plain Chunks reads have untaken() == wanted() == 0, so their behavior is unchanged.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

@coderabbitai

coderabbitai Bot commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Receive-stream lease accounting now tracks bytes held in outstanding leases. Stream-credit calculations use bytes taken and the waiting reader’s requested lease size. Lease operations report when updated credit requires transmission. Unit tests cover lease consumption and requests larger than the stream window. A QUIC simulator test transfers framed data through a relay and checks for complete, uncorrupted frames.

Merge Risk: Minimal · up to 92946

This change makes a paused QUIC stream hold only its own stream window instead of drawing credit up to the connection window. It also gives a reader waiting on a large message enough credit for it. The review found no concrete defect, and the new tests cover the changed behavior. The only leftover item is some doc comments that now understate the credit a stream may hold. The change looks safe to merge.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: a paused stream's receive credit is limited to its stream window in moq-quic. The changeset (lease.rs, recv.rs, moq-quic tests, and docs) implements stream credit trac…
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 specific and relevant to the changeset. It explains the problem (a receive stream's credit follows leased bytes instead of bytes the reader takes, so a paused stream can hold up to …
Full details: Title check

Explanation

The title names the main change: a paused stream's receive credit is limited to its stream window in moq-quic. The changeset (lease.rs, recv.rs, moq-quic tests, and docs) implements stream credit tracking bytes taken rather than bytes leased, which matches the title's subject and intent. The title uses the fix(quic) convention and is specific, under 60 characters, and free of noise.

Full details: Description check

Explanation

The description is specific and relevant to the changeset. It explains the problem (a receive stream's credit follows leased bytes instead of bytes the reader takes, so a paused stream can hold up to the connection window and get evicted). It describes the approach in moq-quic (credit from bytes taken, untaken accounting, queuing MAX_STREAM_DATA on lease handback, the below-threshold credit rule for waiting readers) and the moq-net pause charge for mid-segment bytes. It also lists the tests that cover these changes, the impact on moq-tokio, moq-uring, WebTransport and qmux, and the alternatives considered. The raw summary's file changes (lease.rs, recv.rs, state.rs, tests, README, and the moq-tokio docs) match these claims.

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

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: 38e8ce68-0d23-4111-8ebc-06fed93f94a4
Commits

Reviewing files that changed from the base of the PR and between 98ed0f8 and 9294662.

Files selected for processing: 8

  • rs/moq-quic/README.md
  • rs/moq-quic/src/connection/streams/lease.rs
  • rs/moq-quic/src/connection/streams/recv.rs
  • rs/moq-quic/src/connection/streams/state.rs
  • rs/moq-quic/src/tests/mod.rs
  • rs/moq-relay/tests/integration/quic_sim.rs
  • rs/moq-tokio/src/quic/driver/recv.rs
  • rs/moq-tokio/src/quic/driver/tests.rs

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

kixelated and others added 2 commits November 14, 2026 23:56
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pullfrog[bot]
pullfrog Bot previously approved these changes Nov 15, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found. The undercount I flagged last round is fixed in moq-net, where ingest knows what it holds.

Reviewed changes

Since the prior review, the new commits charge a paused stream for the part of an unsealed segment it has taken, and the docs now describe what a stopped reader holds.

  • Unreleased segment bytes tracked: coding::Reader::unreleased counts the bytes that poll_read_frame restores rather than releases, and resets to 0 when the segment seals. Inlining the lease borrows only self.stream, so the counter can update while the lease is live.
  • Larger pause charge: Pause::pause(taken) flows through boxed::RecvStream::pause to Shared::reserve. That reserves stream window + taken (capped at the connection window) against half the connection window. The amount is fixed at the first pause, which is correct because unreleased only changes after resume().
  • Tests: a_pause_mid_segment_reserves_what_it_took checks that the reservation equals the held credit. paused_streams_hold_at_most_half_the_connection_window now also covers a 25-byte segment hold that refuses a second pause.
  • Doc corrections: the Leased, ReceiveWindow, moq-quic README, recv.rs, moq-tokio poll_lease and sim-test docs now say that a stopped reader holds at most its stream window of untaken bytes, plus what it took and has not released.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 15, 2026
@moq-bot

moq-bot Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at 3e5aff9 because its merge_group build failed (failed_checks).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

Queue / Queue (job) failure at step Check:

… method
    |
164 -             .fetch_update(Ordering::AcqRel, Ordering::Acquire, |paused| {
164 +             .try_update(Ordering::AcqRel, Ordering::Acquire, |paused| {
    |

warning: `moq-net` (lib) generated 7 warnings (run `cargo fix --lib -p moq-net` to apply 7 suggestions)
    Finished `dev` profile [unoptimized] target(s) in 23.99s
mbx[cache]: object cache: 4 hits, 5 misses; 0 B downloaded, 0 B uploaded, 12.6 MiB stored locally
mbx[cache]: 27.41s session; 2.68s estimated compiler time avoided (summed across compilations)
mbx[cache]: Cargo artifact reuse and CI cache archive transfers are not included above
mbx[savings]: swept up 1.5 TiB logical so far. the broom is content-addressed.
##[endgroup]
##[group]test rs
sh/rs/select.sh test "$LIST"
rs: selecting hang moq-archive moq-audio moq-auth moq-bench moq-boy moq-c moq-cli moq-crypto moq-ffi moq-gst moq-hls moq-json moq-loc moq-mux moq-net moq-net-tests moq-quic moq-relay moq-rtmp moq-rtsp moq-srt moq-stats moq-tokio moq-transcode moq-uring moq-video moq-webrtc qmux 
KIO_DENY_HOST_TIMERS=1 CARGO_BUILD_WARNINGS=deny RUSTC_WORKSPACE_WRAPPER='/nix/store/4klbl675argl2irhl89zrh2n14wilzx9-rust-minimal-1.98.1/bin/clippy-driver' bash sh/rs/nextest.sh cargo nextest run --locked --tests "$@"
   Compiling kio v0.6.2 (/var/cache/github-runner-work/moq/moq/rs/kio)
   Compiling bench-harness v0.0.1 (/var/cache/github-runner-work/moq/moq/rs/bench-harness)
   Compiling moq-sock v0.2.0 (/var/cache/github-runner-work/moq/moq/rs/moq-sock)
   Compiling moq-video v0.1.10 (/var/cache/github-runner-work/moq/moq/rs/moq-video)
   Compiling moq-v4l v0.1.0 (/var/cache/github-runner-work/moq/moq/rs/moq-v4l)
   Compiling moq-gst v0.4.12 (/var/cache/github-runner-work/moq/moq/rs/moq-gst)
   Compiling moq-c v0.7.0 (/var/cache/github-runner-work/moq/moq/rs/moq-c)
   Compiling moq-net v0.3.10 (/var/cache/github-runner-work/moq/moq/rs/moq-net)
   Compiling moq-congestion v0.1.0 (/var/cache/github-runner-work/moq/moq/rs/moq-congestion)
   Compiling moq-shaper v0.0.1 (/var/cache/github-runner-work/moq/moq/rs/moq-shaper)
error[E0560]: struct `model::group::Info` has no field named `sequence`
    --> rs/moq-net/src/coding/reader.rs:1278:40
     |
1278 |         let mut group = crate::group::Info { sequence: 0 }.produce();
     |                                              ^^^^^^^^ `model::group::Info` does not have this field
     |
     = note: available fields are: `start`

error[E0308]: mismatched types
    --> rs/moq-net/src/coding/reader.rs:1286:16
     |
1286 |                 timestamp: Some(crate::Timestamp::ZERO),
     |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Timestamp`, found `Option<Timestamp>`
     |
     = note: expected struct `model::time::Timestamp`
                  found enum `std::option::Option<model::time::Timestamp>`

   Compiling moq-crypto v0.0.11 (/var/cache/github-runner-work/moq/moq/rs/moq-crypto)
   Compiling moq-json v0.5.8 (/var/cache/github-runner-work/moq/moq/rs/moq-json)
   Compiling moq-loc v0.2.19 (/var/cache/github-runner-work/moq/moq/rs/moq-loc)
   Compiling moq-archive v0.0.11 (/var/cache/github-runner-work/moq/moq/rs/moq-archive)
   Compiling moq-quic v0.1.0 (/var/cache/github-runner-work/moq/moq/rs/moq-quic)
   Compiling hang v0.21.11 (/var/cache/github-runner-work/moq/moq/rs/hang)
   Compiling moq-auth v0.2.1 (/var/cache/github-runner-work/moq/moq/rs/moq-auth)
   Compiling moq-mux v0.10.11 (/var/cache/github-runner-work/moq/moq/rs/moq-mux)
   Compiling moq-stats v0.2.12 (/var/cache/github-runner-work/moq/moq/rs/moq-stats)
   Compiling qmux v0.7.0 (/var/cache/github-runner-work/moq/moq/rs/qmux)
   Compiling moq-uring v0.0.12 (/var/cache/github-runner-work/moq/moq/rs/moq-uring)
   Compiling moq-tokio v0.19.23 (/var/cache/github-runner-work/moq/moq/rs/moq-tokio)
   Compiling moq-audio v0.1.10 (/var/cache/github-runner-work/moq/moq/rs/moq-audio)
Some errors have detailed explanations: E0308, E0560.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `moq-net` (lib test) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
      Timing report saved to /var/cache/github-runner-work/moq/moq/target/cargo-timings/cargo-timing-20261115T102404772Z-efcac1b57bcf5093.html
error: command `/nix/store/85lxjwg78jw6rf7pqkf3vcq6291nrlfh-cargo-1.98.1-x86_64-unknown-linux-gnu/bin/cargo '--color=auto' test --no-run --message-format json-render-diagnostics --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/hang#0.21.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-archive#0.0.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-audio#0.1.10' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-auth#0.2.1' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-bench#0.1.0' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-boy#0.5.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-c#0.7.0' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-cli#0.14.2' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-crypto#0.0.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-ffi#0.4.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-gst#0.4.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-hls#0.5.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-json#0.5.8' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-loc#0.2.19' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-mux#0.10.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-net#0.3.10' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-net-tests#0.0.0' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-quic#0.1.0' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-relay#0.17.2' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-rtmp#0.3.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-rtsp#0.0.1' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-srt#0.3.11' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-stats#0.2.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-tokio#0.19.23' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-transcode#0.1.10' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-uring#0.0.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-video#0.1.10' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/moq-webrtc#0.3.12' --package 'path+file:///var/cache/github-runner-work/moq/moq/rs/qmux#0.7.0' --package moq-video --package moq-audio --examples --tests --benches --features 'moq-video/capture moq-audio/capture moq-audio/playback moq-cli/play moq-cli/openh264 moq-relay/io-uring moq-audio/bus moq-auth/fuzz moq-boy/openh264 moq-crypto/e2ee moq-crypto/sign moq-hls/server moq-json/bench moq-mux/fuzz moq-net/async moq-net/fuzz moq-quic/fuzz moq-relay/test-support moq-rtmp/fuzz moq-stats/bench moq-tokio/driver moq-tokio/net moq-uring/_probe moq-uring/fuzz moq-uring/quic moq-video/openh264 qmux/fuzz qmux/tcp qmux/tls qmux/ws qmux/wss' --timings --locked` exited with code 101
mbx[cache]: object cache: 0 hits, 31 misses, 3 bypassed; 0 B downloaded, 0 B uploaded, 340.9 MiB stored locally
mbx[cache]: 44.83s session; 0s estimated compiler time avoided (summed across compilations)
mbx[cache]: bypass reasons: 3 unsupported-crate-type
mbx[cache]: Cargo artifact reuse and CI cache archive transfers are not included above
mbx[savings]: 89824 compilations served. ask rustc how many it remembers doing.
error: recipe `test` failed on line 384 with exit code 101
error: recipe `test-changed` failed on line 104 with exit code 101
##[endgroup]
##[error]ci: test rs failed
error: recipe `ci` failed on line 120 with exit code 101
##[error]Process completed with exit code 101.
##[group]Run actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
with:
  name: cargo-timings
  path: target/cargo-timings/cargo-timing-*.html
  if-no-files-found: ignore
  retention-days: 14
  compression-level: 6
  overwrite: false
  include-hidden-files: false
  archive: true
env:
  BASE: 11551598ec4cd39be9c44374439d4a298bf30b90
  CHECK_FAIL_FAST: 1
  NEXTEST_TEST_THREADS: 24
  MBX_CACHE_LINKS: 1
  MBX_REMOTE_URL: 
##[endgroup]
With the provided path, there will be 3 files uploaded
Artifact name is valid!
Root directory input is valid!
Uploading artifact: cargo-timings.zip
Beginning upload of artifact content to blob storage
Uploaded bytes 165660
Finished uploading artifact content to blob storage!
SHA256 digest of uploaded artifact is 9c9918522b9dfbcf9d4102ed03fd9ab5c76317f3dd3dcd712372ba8b69b1cbd6
Finalizing artifact upload
Artifact cargo-timings successfully finalized. Artifact ID 14157706196
Artifact cargo-timings has been successfully uploaded! Final size is 165660 bytes. Artifact ID is 14157706196
Artifact download URL: https://github.com/moq-dev/moq/actions/runs/43703542479/artifacts/14157706196
Post job cleanup.
##[start-action display=Run jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de;id=__384d5d8a-462c-487a-ba8e-346e39654382.mbx]
##[end-action id=__384d5d8a-462c-487a-ba8e-346e39654382.mbx;outcome=skipped;conclusion=skipped;duration_ms=0]
Post job cleanup.
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git version
git version 2.56.0
Temporarily overriding HOME='/var/cache/github-runner-work/_temp/13407f9d-9287-4f0e-8b11-ab9664c86b79' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --global --add safe.directory /var/cache/github-runner-work/moq/moq
Removing SSH command configuration
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
Removing HTTP extra header
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
Removing includeIf entries pointing to credentials config files
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
A job completed hook has been configured by the self-hosted runner administrator
##[group]Run '/nix/store/qrn6ds64bzvwbm5nwf245ifz2c6jb9xw-ci-cache-gc.sh/bin/ci-cache-gc.sh'
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
##[endgroup]
evicted 123 objects and 0 action results (409.2 MiB logical); 50.0 GiB logical remain
dropped 1 stale checkout records
dropped 5 session event streams
removed 0 learned incremental units and 3 checkout directories (3.8 KiB logical); 13 units (2.4 GiB logical) remain
evicted 0 objects and 0 action results (0 B logical); 50.0 GiB logical remain
removed 2 target directories (2.1 MiB logical, 2 abandoned and 0 live); 14.1 GiB logical remain
Cleaning up orphan processes

(written by quest land watch)

@moq-bot

moq-bot Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer note:

The new tests used group and timestamp APIs replaced on base. Merged base and adapted the test initializers and bulk-transfer test using the same migration as base. Production behavior is unchanged. Validation: nix develop --command just ci base passed, including lint, formatting, documentation, dependency checks, and all 12,832 selected Rust tests. Protected paths match base.

(written by codex, gpt-6.1-sol, medium effort)

@moq-bot

moq-bot Bot commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

quest land watch: armed auto-merge on this pull request at 2d68e88, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix (codex, gpt-6.1-sol, medium effort): Merged base and mechanically migrated new tests to its group/start and timestamp APIs; ran nix develop --command just ci base (12832 tests passed) and git diff --check base..

(written by quest land watch)

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found. The new commits only move the tests to main's updated APIs. The fix itself is unchanged.

Reviewed changes

Since the prior review, the branch merged main and moved two tests to its current model APIs.

  • Receive-credit test migrated: a_pause_mid_segment_reserves_what_it_took now uses group::Info { start: 0 } and the non-optional frame::Info::timestamp.
  • Bulk-transfer sim test migrated: a_socket_session_carries_a_bulk_transfer_losslessly now calls append_group(0) and writes with Timestamp::unscaled(0). It ends with group.close(), which ends the group without a known end and still delivers every frame written. These calls match main's definitions in model/track.rs, model/time.rs and model/group.rs.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 15, 2026
Merged via the queue into main with commit 52732a0 Nov 15, 2026
6 of 7 checks passed
@moq-bot
moq-bot Bot deleted the fix/quic-paused-stream-window branch November 15, 2026 10:49
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