diff --git a/quest/m1/README.md b/quest/m1/README.md index e3489cf3128..969954a1f8c 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -133,6 +133,7 @@ removed). - [Announcement takeover](/quest/m1/announce-takeover.md) - a new independent route explicitly continues instances served through its predecessor, with shared Rust/JS semantics and lite-07 wire - [Subscribe ranges](/quest/m1/subscribe-ranges/README.md) - a lite-07 SUBSCRIBE asks for past and live ranges with absolute or relative ends, in either order, and replaces FETCH; merged ranges never starve a subscriber; relays fill misses by range, including over moq-transport - [Drop set](/quest/m1/drop-set.md) - each cursor judges missing groups against its own budget, so a narrow reader drops promptly and a widening re-offers groups already reported dropped on lite-07 +- [Aborted copies don't hold an end open](/quest/m1/settled-abort.md) - a track's declared end settles when a fetched copy finishes a group whose live copy was cut or evicted - [Broadcast archives](/quest/m1/archive/README.md) - ANNOUNCE, TRACKS, and a SUBSCRIBE per track record every track under a prefix to any object_store, a host serves a stored broadcast back, and the catalog drops its archive pointer for a per-rendition `hls` field - [HLS recorder target](/quest/m1/hls-record-target.md) - the moq-cli HLS recorder takes its target duration from the declared `hls` duration - [Compressed tracks](/quest/m1/compress/README.md) - a track flagged `compress` is DEFLATEd per group by moq-net, forwarded compressed, and inflated once on the relay for peers that cannot signal it; `catalog.json.z` and moq-flate go away diff --git a/quest/m1/drop-set.md b/quest/m1/drop-set.md index 7f3a20b270e..32792531040 100644 --- a/quest/m1/drop-set.md +++ b/quest/m1/drop-set.md @@ -248,6 +248,15 @@ Test on mock time through a relay: [moq-dev/moq#6171](https://github.com/moq-dev/moq/pull/6171), decided 2026-10-23). +- A group the publisher cut while a fetched copy still serves its end is + delivered and never also reported dropped. Today `DropCursor::cut` + (`rs/moq-net/src/model/track.rs`) reports any visible slot's + `cut_error()`, so the arrival walk can hand out the fetched copy and report + the group dropped too; `Slot::cut()` already returns nothing while a copy + serves the end. Found by + [moq-dev/moq#7053](https://github.com/moq-dev/moq/pull/7053) (added + 2026-10-28). + Mirror each case in `js/net`. Public API: none. Wire: lite-07 SUBSCRIBE_DROP (unpublished) gains `Max Age` diff --git a/quest/m1/settled-abort.md b/quest/m1/settled-abort.md new file mode 100644 index 00000000000..5446116c846 --- /dev/null +++ b/quest/m1/settled-abort.md @@ -0,0 +1,29 @@ +# [S] An aborted live copy doesn't hold a track's end open + +## Goal + +A track whose live copy of a group was cut or evicted, while a fetched copy +still serves that group to its end, settles its declared end when the fetched +copy finishes, and a later abort of the live copy never turns that clean end +into an error. + +## Plan + +Found while landing [moq-dev/moq#7053](https://github.com/moq-dev/moq/pull/7053) +(planned 2026-10-28). `TrackState::is_settled` (`rs/moq-net/src/model/`) +checks only each slot's own `slot.group`. When that group was aborted but a +fetched copy covers it, the end stays unsettled, and a later abort makes the +clean end an error. + +Recommended (confirm in the PR): an aborted live copy counts as nothing in +flight, so `is_settled` judges the slot by whichever copy serves its end, the +same meaning `Handle::is_settled` and `Slot::cut()` already use. Write the +failing case first: cut or evict a slot's live group while a fetched copy +serves it, finish the copy, and check the track's end settles cleanly. Mirror +it in `js/net` if its track end has the same check. + +Public API: none. Wire: none. + +## Related + +- [Drop set](/quest/m1/drop-set.md) - reworks the cut and drop records next to this check