Repository navigation
quest: plan resume reorder, JSON window timestamps, and move TS duration fidelity to m0 #5253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # [S] TS compliance duration-fidelity captures the whole source | ||
|
|
||
| ## Goal | ||
|
|
||
| Interop's TS-compliance `duration-fidelity` check (`test/ts/run.sh`) captures | ||
| the whole round-tripped stream, not a fraction of it, fixed at its cause. | ||
|
|
||
| ## Plan | ||
|
|
||
| Moved to m0 on 2026-10-10: it now fails on every Interop run, main | ||
| included (`c0c0bb33`, 3.2 s of 20.1 s, and each head of #5099), so it reads | ||
| as a regression, not a flake. A red Interop on main hides real regressions | ||
| in every PR. Start by finding the last green Interop run on main and the | ||
| first red one, and bisect between them. #5217's isolated local run captured | ||
| the whole source (20.47 s of 20.06 s), so look at what differs on the CI | ||
| runner. | ||
|
|
||
| First seen 2026-10-10 on #5158's second Interop run: the export captured 3.3 s of a | ||
| 20.1 s source, and the check failed; it also failed once on #5140 and passed | ||
| on rerun. Find whether the export ends early (an announce `End`, linger, or | ||
| a catalog finish arriving before the media), starts late, or the capture is | ||
| cut off by the harness. Fix that at its source, with a regression that fails | ||
| without it. No longer timeout and no lower duration threshold. | ||
|
|
||
| #5147 (export ts follows announcements, merged 2026-10-10) changed how an | ||
| export ends, so check it first. Never raise a timeout or add a retry (the | ||
| test-flakes-2 rules still apply). | ||
|
|
||
| Public API: none expected. Wire: none expected. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # [S] JSON window consumers return each event's timestamp | ||
|
|
||
| ## Goal | ||
|
|
||
| The moq-json and `@moq/json` window consumers return each event with a | ||
| timestamp. In JS all three data consumers then return `Timed<T>`; the Rust | ||
| snapshot and stream consumers follow in | ||
| [Data consumer timestamps](/quest/m1/data-consumer-timestamps.md). | ||
|
|
||
| ## Plan | ||
|
|
||
| Follow-up from #5099, which gave `@moq/json` and `@moq/flate` snapshot and | ||
| stream consumers `Timed<T>`. The window consumer (`window::Consumer::next` in | ||
| `rs/moq-json` and `js/json`) still yields a bare `Event<T>`. | ||
|
|
||
| - Decided (2026-10-10): `next()` returns `Timed<Event<T>>`. `at` is the | ||
| timestamp of the frame that carried the event, and `None` when untimed. A | ||
| record restated by a group header gets the header frame's time; document that | ||
| on the type. There is no per-record time on the wire, so no wire change. | ||
| - Decided: Rust and JS together, same names and shape. Update moq-ffi and the | ||
| bindings if they expose the window consumer (see the Cross-Package Sync table). | ||
| - Update in-repo readers (`js/hang` timeline, `js/room` chat) and add a line to | ||
| the Unreleased section of `doc/setup/upgrade.md`. No new doc page. | ||
| - Land before the next `@moq/json` release, so its break ships together with | ||
| #5099's. Not blocked on the Rust snapshot and stream quest: both Rust breaks | ||
| use the same `moq_net::Timed` and ship in the next moq-json release together. | ||
|
|
||
| Public API: breaking (Rust and JS). Wire: none. | ||
|
|
||
| ## Related | ||
|
|
||
| - [Data consumer timestamps](/quest/m1/data-consumer-timestamps.md) - the Rust snapshot and stream side of the same change | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # [M] A track judges a passed group from its arrivals, not its newest sequence | ||
|
|
||
| ## Goal | ||
|
|
||
| When a route fails over, a group whose stream header arrives after its | ||
| successor's still continues on the new route. Only a group the publisher | ||
| dropped, or one whose gap outlived its grace, ends with an error. Held fetches | ||
| over a pre-lite-05 upstream (#5209) and route resume use the same rule. | ||
|
|
||
| ## Plan | ||
|
|
||
| Found by Codex on #5209 (2026-10-10). `track::Consumer::poll_group(seq)` | ||
| answers that the feed went past `seq` as soon as any newer group arrived | ||
| (`max_sequence > seq`). Each group is its own QUIC stream, so N+1's header can | ||
| beat N's. Resume (`rs/moq-net/src/model/resume.rs`, the refusal verdict) then | ||
| fails an in-flight group it could have continued. | ||
|
|
||
| - Decided: build on [Tail arrivals](/quest/m1/tail-arrivals.md), the per-track | ||
| record of live arrivals in the model, and make `poll_group`'s "passed" verdict | ||
| read it. A gap stays open for the subscription's grace, as `tail::Tail` does | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '1,80p' quest/m1/tail-arrivals.md
rg -n -C 6 'poll_group|grace|arrival|refusal|resume' \
rs/moq-net/src/model/track.rs \
rs/moq-net/src/model/resume.rs \
rs/moq-netRepository: moq-dev/moq Length of output: 45665 🏁 Script executed: set -euo pipefail
printf '%s\n' '--- quest/m1/resume-reorder.md ---'
nl -ba quest/m1/resume-reorder.md | sed -n '1,120p'
printf '%s\n' '--- quest/m1/tail-arrivals.md ---'
nl -ba quest/m1/tail-arrivals.md | sed -n '1,80p'
printf '%s\n' '--- base-to-head diff for the reviewed file ---'
git diff --no-ext-diff --unified=20 634ffe0e1ac471d25cbba18dfdea7b8749075dac..51d87556ab7e54d73f838a73b5bf4443cf2c3ca1 -- quest/m1/resume-reorder.mdRepository: moq-dev/moq Length of output: 5291 Resolve the expired-arrival case before depending on this verdict.
🤖 Prompt for AI Agents |
||
| in the lite subscriber today. | ||
| - Decided: #5209's held fetches move off their local `Tail` read onto this | ||
| verdict, so one rule remains. | ||
| - The delivery budget alone was rejected: relay tracks from lite-01..04 | ||
| upstreams are untimed, so nothing on them is ever stale. | ||
| - Tests use mocked time: a failover mid-group where N+1's header arrives before | ||
| N's continues N, and a truly dropped group still fails once its gap folds. | ||
|
|
||
| Public API: behavior only. Wire: none. | ||
|
|
||
| ## Required | ||
|
|
||
| - [Tail arrivals](/quest/m1/tail-arrivals.md) - the per-track arrival record this verdict reads | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving Data consumer timestamps under
Relatedallows this quest to be dispatched and completed independently, but the current Rust snapshot and stream consumers still return bareTfromnext/poll_next; onlydata-consumer-timestamps.mdplans to change them. In that ordering, this quest cannot achieve its stated goal that all three Rust consumers returnTimed<T>and may land a second, uncoordinated Rust API break. Make that quest required or fold its Rust work into this one.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partly agree. The goal overstated it: Rust snapshot and stream consumers still return bare
T. 51d8755 rewords the goal so only JS gets all three; the Rust snapshot and stream side stays with Data consumer timestamps.I'm not adding it as Required. That quest is [M] and spans moq-mux, moq-ffi, and every binding. Blocking on it would keep the JS window break out of the next
@moq/jsonrelease, and landing with that release is decided. Both Rust breaks use the samemoq_net::Timedand sit onmainuntil the next moq-json release, so they still ship together. The plan now says so.(Written by Claude Opus 5.5)