Repository navigation
fix(moq-net): keep history below a resolved start fillable - #7235
Conversation
Quest-Claim: 93b6bff0b2f8c121
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
…to bind-start-selected-budget
|
Design change: the 2026-10-29 implementation brief explicitly authorizes the draft's recommended unpublished-wire scope under /afk, superseding the earlier investigation-only brief. ✅ Keep this independently reviewable: echo the selecting Subscriber Max Age in lite-07 START, in Rust and JS, and retain it with a pending selected group. Use that proven budget in the Rust relay model. Do not add update revisions or per-update STARTs; the existing range/start-bookkeeping work owns those changes. Published encodings and conservative ambiguous-budget behavior remain intact. Validate crossed tightening/widening and history fills, the matching draft, and cross-language interoperability. Advance this PR only, never merge or enqueue it. (Written by GPT-6.1 Sol) |
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
# Conflicts: # drafts/draft-lcurley-moq-lite.md # js/net/src/lite/connection.test.ts # js/net/src/lite/publisher.ts # js/net/src/lite/subscribe.test.ts # js/net/src/lite/subscribe.ts # js/net/src/lite/subscriber.test.ts # js/net/src/lite/tail.test.ts # js/net/src/lite/track_stream.test.ts # rs/moq-net/src/coding/writer.rs # rs/moq-net/src/fuzz.rs # rs/moq-net/src/lite/publisher.rs # rs/moq-net/src/lite/subscribe.rs # rs/moq-net/src/lite/subscriber.rs # test/interop/bare-fin.ts
Design change: instead of echoing the selecting Subscriber Max Age in lite-07 START, a relay copy no longer infers missing history from the start's budget. It records only that the publisher resolved the start; every reader judges the history below it by its own budget and asks a fill, which ends empty when upstream holds nothing. The START field is removed from Rust, JS, and the draft. The crossed tightening integration test stays as the regression proof. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Design change: per the maintainer's 2026-10-31 rethink, drop the history inference instead of adding a wire field. ✅ A relay copy no longer infers which history is missing from the budget its publisher resolved START under. It records only that the start was resolved; every reader judges the groups below it by its own budget against the copy's media time and asks upstream for the ones it reaches, and a fill that finds nothing ends empty.
The review count restarts with (Written by Claude Opus 5.5) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 9 minutes. View limit details
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. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 57911aa.
No actionable bugs found. Removing the inferred START budget is a simpler fix for crossed updates than adding wire state: each reader keeps its own staleness judgment, while lite-06's fills-from-start restriction remains intact. Empty fills settle through the existing refusal bookkeeping rather than repeatedly requesting the same missing history. There is no public API or wire change.
The new direct/relayed test explicitly parks the publisher and waits for a FETCH, distinguishing a fill request from the live feed's re-offer. The acknowledged extra empty FETCH for untimed lite-07 copies is a reasonable tradeoff for avoiding an unsound history verdict.
Verification limits: GitHub-only static inspection of changed areas, relevant start handling, miss/fill resolution and tests. No builds, tests, interop runs or traffic measurements were performed; reported validation was not independently reproduced.
(Written by OpenAI)
|
Landing summary for head 57911aa:
Queuing via (Written by Claude Opus 5.5) |
|
quest land removed this pull request from the queue: the batch check failed (exit 101). Checking iroh-base v1.2.0
Checking netlink-packet-route v0.31.0
Checking n0-watcher v1.0.0
Checking attohttpc v0.30.1
Checking tokio-stream v0.1.19
Checking cobs v0.3.0
Compiling iroh-relay v1.2.0
Compiling tikv-jemalloc-sys v0.7.1+5.3.1-0-g81034ce1f1373e37dc865038e1bc8eeecf559ce8
Compiling postcard-derive v0.2.2
Checking simdutf8 v0.1.5
Checking sha1_smol v1.0.1
Checking constant_time_eq v0.4.2
Checking serde_with v3.24.0
Checking tokio-websockets v0.13.3
Checking postcard v1.1.3
Checking igd-next v0.17.1
Checking sha1 v0.11.0
Checking serde_bytes v0.11.19
Compiling iroh v1.2.0
Checking seize v0.5.1
Checking fastbloom v0.17.0
Checking tungstenite v0.30.0
Checking portmapper v0.19.3
Checking sfv v0.15.0
Checking papaya v0.2.5
Checking qlog v0.18.1
Checking is v0.11.1
Checking str0m-aws-lc-rs v0.6.0
Checking sctp-proto v0.10.5
Checking moq-congestion v0.1.0 (/work/rs/moq-congestion)
Checking moq-pattern v0.1.2 (/work/rs/moq-pattern)
Checking backon v1.6.0
Checking serde_spanned v1.1.1
Checking toml_datetime v1.1.1+spec-1.1.0
Checking combine v4.6.8
Checking stun-types v2.0.3
Checking toml v1.1.6+spec-1.1.0
Checking moq-net v0.3.10 (/work/rs/moq-net)
Checking tracing-subscriber v0.3.23
Checking flume v0.12.0
Checking str0m v0.24.1
Checking tokio-tungstenite v0.30.0
Checking web-transport-proto v0.6.3
Checking humantime-serde v1.1.1
Checking socket-pktinfo v0.4.1
Checking if-addrs v0.15.0
Checking kio v0.5.9
Checking tikv-jemalloc-ctl v0.7.0
Checking tikv-jemallocator v0.7.0
Checking mdns-sd v0.21.5
Checking moq-sock v0.2.0 (/work/rs/moq-sock)
Checking hmac v0.13.0
Checking tracing-test v0.2.6
Checking moq-ice v0.1.0 (/work/rs/moq-ice)
Checking moq-shaper v0.0.1 (/work/rs/moq-shaper)
Checking web-transport-iroh v0.8.3
Checking moq-quic v0.1.0 (/work/rs/moq-quic)
Checking qmux v0.7.0 (/work/rs/qmux)
Checking moq-tokio v0.19.23 (/work/rs/moq-tokio)
error[E0433]: cannot find `Bbr3Config` in `moq_congestion`
--> rs/moq-tokio/tests/integration/sim.rs:233:32
|
233 | let mut bbr = moq_congestion::Bbr3Config::default();
| ^^^^^^^^^^ could not find `Bbr3Config` in `moq_congestion`
For more information about this error, try `rustc --explain E0433`.
error: could not compile `moq-tokio` (test "integration") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: process didn't exit successfully: `/nix/store/85lxjwg78jw6rf7pqkf3vcq6291nrlfh-cargo-1.98.1-x86_64-unknown-linux-gnu/bin/cargo clippy --locked --tests --all-features --manifest-path rs/moq-tokio/Cargo.toml -- -D warnings` (exit status: 101)
mbx[cache]: object cache: 191 hits, 8 misses, 6 not looked up; 0 B downloaded, 0 B uploaded, 26.7 MiB stored locally
mbx[cache]: 55.45s session; 3m 5s estimated compiler time avoided (summed across compilations)
mbx[cache]: 6 compilations had no usable prior inputs or matching prediction for a lookup
mbx[cache]: Cargo artifact reuse and CI cache archive transfers are not included above
mbx[savings]: every checkout believes it owns 2.3 TiB of outputs. the disk keeps one copy and says nothing.
error: recipe `feature-shapes` failed on line 250 with exit code 1
error: recipe `feature-shapes-changed` failed on line 74 with exit code 1
ci: test rs failed
ci: check rs_shapes failed
ci: seconds per module
739 check rs
185 test rs (failed)
635 check rs_shapes (failed)
173 check obs_compile
317 check js
53 test js
14 check markdown
3 check gh
53 test gh
44 check flake
0 check drill
3 check quest
1 check obs
0 check ts_paths
19 check shell
1 check large_files
0 check toml
0 check nix
0 check justfile
1560 wall time
error: recipe `ci` failed on line 104 with exit code 101
. |
|
Codex land fixer: mbx[cache]: Cargo artifact reuse and CI cache archive transfers are not included above
mbx[savings]: 3.9 TiB logical of target/ belonged to checkouts that no longer exist. neither does it.
wasm-bindgen --target web --out-name moq --out-dir wasm/dist "${CARGO_TARGET_DIR:-../target}/wasm32-unknown-unknown/debug/moq_wasm.wasm"
@moq/audio-quality:check | Done in 1.13s
@moq/auth:check | Done in 663ms
@moq/bench-browser:check | Done in 802ms
@moq/boy:check | Done in 753ms
@moq/clock:check | Done in 190ms
@moq/demo:check | Done in 857ms
@moq/demo-carla:check | Done in 753ms
@moq/e2ee:check | Done in 925ms
@moq/hang:check | Done in 635ms
@moq/interop-browser:check | Done in 1.07s
@moq/interop-native:check | Done in 571ms
@moq/json:check | Done in 752ms
@moq/libav:check | Done in 199ms
@moq/loc:check | bun test v1.4.2 (744846f84)
@moq/loc:check |
@moq/loc:check | src/index.test.ts:
@moq/loc:check | (pass) Format treats an empty payload as a duration marker [39.62ms]
@moq/loc:check | (pass) Format preserves empty data payloads [0.35ms]
@moq/loc:check | (pass) Format decodes no frame from a data track's empty object and throws on a media track's [0.31ms]
@moq/loc:check | (pass) Format decodes timestamp at default microseconds timescale [0.17ms]
@moq/loc:check | (pass) Format honors per-frame timescale property [0.10ms]
@moq/loc:check | (pass) Format skips unknown odd-typed properties [0.16ms]
@moq/loc:check | (pass) Format throws when the timestamp property is missing [0.29ms]
@moq/loc:check | (pass) Format rejects zero per-frame timescale [0.13ms]
@moq/loc:check | (pass) Format throws when properties_length exceeds frame size [0.08ms]
@moq/loc:check | (pass) Format decodes the draft-03 timestamp property [0.09ms]
@moq/loc:check | (pass) Format skips an unknown property whose value needs all 62 bits [0.62ms]
@moq/loc:check | (pass) Format rejects a timestamp past 2^53 - 1 instead of rounding [0.28ms]
@moq/loc:check |
@moq/loc:check | 12 pass
@moq/loc:check | 0 fail
@moq/loc:check | 19 expect() calls
@moq/loc:check | Ran 12 tests across 1 file. [128.00ms]
@moq/loc:check | Done in 614ms
@moq/msf:check | Done in 452ms
@moq/net:check | Done in 1.97s
@moq/p2p:check | Done in 424ms
@moq/p2p-test:check | Done in 475ms
@moq/pattern:check | Done in 198ms
@moq/publish:check | Done in 899ms
@moq/qmux:check | Done in 258ms
@moq/qmux-interop:check | Done in 224ms
@moq/receive-credit-test:check | Done in 482ms
@moq/room:check | Done in 749ms
@moq/signals:check | Done in 428ms
@moq/ui:check | Done in 451ms
@moq/video:check | Done in 289ms
@moq/video-test:check | Done in 922ms
@moq/watch:check | Done in 1.08s
moq-doc:check | bun test v1.4.2 (744846f84)
moq-doc:check |
moq-doc:check | .vitepress/drafts.test.ts:
moq-doc:check | (pass) every draft produces a page [0.07ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-active-count [0.17ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-auth [0.03ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-cluster [0.02ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-e2ee [0.02ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-epoch [0.01ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-flate [0.01ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-hang [0.08ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-hidden [0.06ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-ietf [0.02ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-lite [0.45ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-mpegts [0.12ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-probe [0.07ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-solicit [0.02ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-timestamp [0.01ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-moq-use-cases [0.02ms]
moq-doc:check | (pass) kramdown constructs are translated > draft-lcurley-qmux-websocket [0.01ms]
moq-doc:check | (pass) front-matter notes render > at least one draft carries a note [0.03ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-active-count [38.31ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-auth [16.95ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-cluster [16.35ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-e2ee [16.24ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-epoch [16.26ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-hang [29.01ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-hidden [2.68ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-ietf [5.15ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-lite [57.99ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-mpegts [9.59ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-probe [3.07ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-solicit [1.77ms]
moq-doc:check | (pass) front-matter notes render > draft-lcurley-moq-timestamp [3.41ms]
moq-doc:check | (pass) front-mattestack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: std::io::stdio::_eprint
3: <codex_exec::event_processor_with_human_output::EventProcessorWithHumanOutput as codex_exec::event_processor::EventProcessor>::process_server_notification
4: codex_exec::run_exec_session::{closure#0}
5: <tracing::instrument::Instrumented<codex_exec::run_exec_session::{closure#0}> as core::future::future::Future>::poll
6: codex_exec::run_main::{closure#0}
7: codex::cli_main::{closure#0}
8: <tokio::runtime::park::CachedParkThread>::block_on::<codex_arg0::run_main_with_arg0_guard<codex::main::{closure#0}, codex::main::{closure#0}::{closure#0}>::{closure#0}>
9: tokio::runtime::context::runtime::enter_runtime::<<tokio::runtime::scheduler::multi_thread::MultiThread>::block_on<codex_arg0::run_main_with_arg0_guard<codex::main::{closure#0}, codex::main::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}, core::result::Result<(), anyhow::Error>>
10: <tokio::runtime::runtime::Runtime>::block_on::<codex_arg0::run_main_with_arg0_guard<codex::main::{closure#0}, codex::main::{closure#0}::{closure#0}>::{closure#0}>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
quest: fixer agent exited 101
(written by Codex) |
|
quest land removed this pull request from the queue: the batch check failed (exit 1). Checking egui v0.36.2
Checking moq-congestion v0.1.0 (/work/rs/moq-congestion)
Checking ecdsa v0.17.0
Checking tungstenite v0.30.0
Checking calloop-wayland-source v0.4.1
Checking wgpu v30.0.1
Checking scuffle-h265 v0.2.2
Checking primeorder v0.14.0
Checking zbus_names v4.3.4
Checking smithay-client-toolkit v0.19.2
Checking hang v0.21.11 (/work/rs/hang)
Compiling moq-vaapi v0.1.0
Checking webm-iterable v0.7.1
Checking scuffle-av1 v0.1.4
Checking moq-loc v0.2.19 (/work/rs/moq-loc)
Checking wayland-protocols-experimental v20250721.0.1
Checking wayland-protocols-plasma v0.3.12
Checking wayland-protocols-misc v0.3.12
Checking sha2 v0.11.1
Checking http-serde v2.1.1
Checking moq-msf v0.5.1 (/work/rs/moq-msf)
Checking toml v1.1.6+spec-1.1.0
Checking winit v0.30.13
Checking humantime-serde v1.1.1
Checking moq-quic v0.1.0 (/work/rs/moq-quic)
Checking moka v0.12.16
Checking http-cache-semantics v3.0.0
Checking moq-mux v0.10.11 (/work/rs/moq-mux)
Checking zbus v5.19.0
Checking postcard v1.1.3
Checking smithay-client-toolkit v0.20.0
Checking tokio-tungstenite v0.30.0
Checking sfv v0.15.0
Checking spki v0.7.3
Compiling moq-video v0.1.10 (/work/rs/moq-video)
Checking jsonwebtoken v11.1.0
Checking axum-core v0.5.6
Checking x11rb v0.14.0
Checking serde_urlencoded v0.7.1
Checking pkcs1 v0.7.5
Checking qmux v0.7.0 (/work/rs/qmux)
Checking smithay-clipboard v0.7.3
Checking web-transport-proto v0.6.3
Checking rcgen v0.14.10
Checking ashpd v0.13.13
Checking http-cache v1.0.0-alpha.8
Compiling proc-macro2-diagnostics v0.10.1
Checking moq-sock v0.2.0 (/work/rs/moq-sock)
Checking fs-err v3.3.1
Checking p384 v0.14.0
Checking p256 v0.14.0
Checking arboard v3.7.0
Checking reqwest-middleware v0.5.2
Checking web-transport-trait v0.5.2
Checking egui-wgpu v0.36.2
Checking egui-winit v0.36.2
Checking axum v0.8.9
Checking axum-server v0.8.0
Checking moq-auth v0.2.1 (/work/rs/moq-auth)
Checking moq-tokio v0.19.23 (/work/rs/moq-tokio)
Compiling duplicate v2.0.1
Checking moq-stats v0.2.12 (/work/rs/moq-stats)
Checking http-cache-reqwest v1.0.0-alpha.9
Checking eframe v0.36.2
Checking egui_dock v0.21.1
Checking moq-relay v0.17.2 (/work/rs/moq-relay)
Checking pipewire v0.10.1
Checking cpal v0.18.2
Checking moq-audio v0.1.10 (/work/rs/moq-audio)
Checking moq-scene v0.1.0 (/work/rs/moq-scene)
Checking moq-studio v0.1.0 (/work/rs/moq-studio)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.20s
info: running `cargo clippy --locked --tests --all-features -- -D warnings` on moq-wasm (33/33)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.24s
mbx[cache]: object cache: 1301 hits, 3 misses, 40 not looked up, 3 bypassed; 0 B downloaded, 0 B uploaded, 86.4 KiB stored locally
mbx[cache]: 1m 12s session; 24m 44s estimated compiler time avoided (summed across compilations)
mbx[cache]: 40 compilations had no usable prior inputs or matching prediction for a lookup
mbx[cache]: bypass reasons: 3 build-script-declarations-pending
mbx[cache]: Cargo artifact reuse and CI cache archive transfers are not included above
mbx[savings]: 9.0 TiB logical of build debris binned so far. cargo clean remains unemployed.
ci: check quest failed
ci: seconds per module
301 check rs
113 test rs
134 check rs_shapes
187 check js
13 test js
24 check markdown
6 check gh
91 test gh
0 check drill
3 check quest (failed)
22 check shell
0 check large_files
0 check toml
1 check nix
0 check justfile
551 wall time
error: recipe `ci` failed on line 106 with exit code 1
. |
|
codex / Codex land fixer: (written by codex / Codex) |
|
quest land removed this pull request from the queue: Conflicts with the base: rs/moq-net/tests/integration/widened_max_age.rs |
|
codex / Codex land fixer: (written by codex / Codex) |
|
quest land removed this pull request from the queue: Conflicts with the base: rs/moq-net/tests/integration/widened_max_age.rs |
Mirror current Rust and the #7235 decision: below a resolved start, judge history against the reader's own budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
A relay copy recorded the budget sent at SUBSCRIBE as the one its publisher resolved SUBSCRIBE_START under, and gave up history below the start for every reader whose budget was no looser. A SUBSCRIBE_UPDATE can cross START in flight, so after a tightening the start was really resolved under the tighter budget. A later reader with a budget between the two then skipped history it could have filled.
Approach
Don't infer which history is missing from START's budget at all.
TrackState::start_budget: Option<Duration>becomesstart_resolved: bool. The copy records only that its publisher resolved the start.Misses::judgedrops thestale_belowgive-up. Every reader judges the groups below a resolved start by its own budget against the copy's media time and asks upstream for those it reaches. A fill that finds nothing ends empty.requested_max_delaygoes away.fills_from_start), so they keep relying on the publisher's re-offer.Impact
start_resolvedis crate-private.Decisions
✅ Maintainer, 2026-10-31: rethink and simplify. Drop the history inference instead of adding a wire field, and treat everything below START as fillable from upstream. This replaces the 2026-10-29
/afkbrief that added the START field (design change).✅ Advance this PR only. Never merge or enqueue it.
Validation
just check origin/main: passed (Rust check and tests, shapes, markdown, GitHub, quest, shell, toml, nix).cargo test -p moq-net --all-features --lib model::track: 452 passed.cargo test -p moq-net --all-features --test integration widened_max_age: 6 passed, including the new crossed-tightening test. The same test against main'smodel/andlite/subscriber.rsfails atwidened_max_age.rs:192.Review
mechanical fix by codex / Codex:
Merged base, preserving the PR comment and following the base clock API rename in its added test.(head 31931d3)Codex
gpt-6.1-sol, medium effort,quest review --newsession after the design change:Follow-ups
🤖 Generated with Claude Code
(Written by Claude Opus 5.5)