Repository navigation
Conversation
Quest-Claim: 92cdb4d94a202162
Backs out #8699. A failover mid-frame refetches the frame whole and skips the bytes already read, as before. Frames are capped at 32 MiB, so the byte offset saved at most one frame's prefix per failover, on one hop, and only for chunk readers. The draft, Rust, and JS drop the field together; lite-07 is unpublished. The 5 MiB failover integration test stays as half_read_frame.rs and now asserts the new route resends the whole frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
marked this pull request as ready for review
November 15, 2026 14:24
Contributor
|
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 38 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. |
Contributor
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This review covers the full backout of #8699's FETCH Start Byte across the drafts, moq-net, @moq/net, and the quest files.
- Wire and drafts: lite-07-wip FETCH drops
Start Bytein both the encoder and decoder, in Rust and JS. The lite draft loses the field, its Positions sentence, and its changelog line. The ietf draft loses its non-zero Start Byte ban. - Group model:
group::Bounds::byteand the wholeLeadpath are gone (create_lead,lead_at,Consumer::at,poll_next_frame_at, the lead's billing and shedding intail/trim).boundgoes back to a plainstart_at. - Failover read:
frame::Consumer'sRecoverasks for the frame by index alone, reads the replacement withpoll_next_frame, and keeps its ownread_idxagainst the new whole-framesource. Withoutbase, the offset logic inpoll_read_chunk/poll_read_allgoes back to plainread_idx. - Fill and fetch plumbing: the byte is removed from
Ask,Pending,Inner,GroupFill,Fetching, andgroup::Fetch. Fill merging compares frames only. - Publisher and subscriber serving: the Rust fetch serve goes back to
with_range(start_frame..)with theindex() != start_frame→Laggedguard, andbuffer_frame_infoalways announcessize.FrameIngest::dispatchno longer routes to a lead. JS#runFetchGroupwrites whole frames throughsendPayload. - Regression test:
half_read_frame.rs(formerlybyte_holes.rs) now checks that the reader gets the 5 MiB frame byte-for-byte and thatBresends the whole frame. - Quests:
fetch-start-byte.mdis deleted,byte-holes.mdrecords the backout and a maintainerWaitingitem, and the links inlite07-finalize.mdandyield-relay-links.mdare updated.
A repo-wide search found no leftover start-byte or Lead references in the code, drafts, doc/, or the TLA+ models.
claude-opus-5-5 | 𝕏
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Finishes quest/m2/fetch-start-byte.md and deletes it.
Summary
Backs out moq-dev/moq#8699, as the maintainer picked on moq-dev/moq#8764. lite-07-wip FETCH no longer carries
Start Byte. A frame read partway when its route fails is refetched whole from the next route, and the reader skips the bytes it already read (frame::Consumer'sRecover), as before #8699.Frames are capped at 32 MiB (
MAX_CACHE_BYTES), whole-frame reads asked byte 0 anyway, and only chunk readers saved at most one frame's prefix on one hop per failover. That did not pay for aLeadin the group model, the start-byte plumbing through the fill, subscriber, and publisher in Rust and JS, and a field frozen in lite-07.Removed:
Start Bytein the lite draft's FETCH, its Positions sentence, and its changelog line; the ietf draft's ban on a non-zero Start Byte for a track with a Version, and its changelog line.moq-net):lite::Fetch::start_byte,Version::has_byte_start,group::Bounds::byte, theLead(create_lead,lead_at,group::Consumer::at,poll_next_frame_at), the fill's byte (Ask::byte,Pending::byte,GroupFill::byte_start),frame::Consumer::base, and the publisher's serving from a byte.@moq/net):Fetch.startByte,hasByteStart,sendPayloadFrom, and the publisher's serving from a byte.The revert of the squashed #8699 commit conflicted only where later PRs renamed
sequencetokeyor touched the same tests; those were resolved to the current names.Quests: Byte holes records the backout, lists restoring the slice in what remains, and waits on the maintainer naming a consumer of frames over 32 MiB, as this quest's Plan required. Lite-07 finalize drops its link, and Yield on relay links no longer points at Start Byte as its example.
Choices made without asking
rs/moq-net/tests/integration/half_read_frame.rs(it wasbyte_holes.rs). It now asserts the reader gets the whole frame correctly and the new route resends the whole frame, so refetch-and-skip keeps an over-the-wire regression.resumehalf-read tests. The existingresumetest where the replacement holds the frame whole and the reader continues withcdcovers refetch-and-skip at the model level.Maintainer:Waitingitem (name a consumer of frames over 32 MiB) rather than prose, so it surfaces inquest waiting.Public API and wire impact
@moq/net'sFetchlosesstartByte(a lite message class, not used outside the package). Rust's surface was crate-private.Start Byte, breaking for lite-07-wip peers built since feat(moq-net,net)!: lite-07 FETCH Start Byte continues a half-read frame by byte #8699; Rust and JS change together. Published versions are unchanged. No migration: lite-07 is unpublished.Validation
half_read_frame::a_half_read_frame_refetches_whole_and_skips_what_was_read: relaysP -> A, B -> Eover lite-07-wip.Ereads 2 MiB of a 5 MiB frame throughA,A's session dies, andEreads the rest throughBbyte-for-byte.B's session sent between the frame's full size and 1 KiB more, so the frame was refetched whole and the read part skipped.cargo test -p moq-net --all-features: all pass (3375 unit, 602 integration).cargo clippy -p moq-net --all-features --all-targets -D warningsand the--no-default-features --libbuild: clean.just check: passes (Rust lint across the workspace, JS, drafts, markdown, quest).just test interop --all: 211 passed, 0 failed.Caused by
Start Byteand aLeadfor a saving the 32 MiB frame cap makes marginal (found by reviewer: the feature review)Follow-ups
None new. Restoring the slice stays in Byte holes.
Models
Size: S
Implementer: Claude Code, claude-opus-5-5, unknown effort (arm A)
(Written by Claude Opus 5.5)
🤖 Generated with Claude Code
Review
Rewritten by
quest reviewafter each round.Head: 853a4a1
Base: origin/main at 505a86f
Risk: medium,
the base has no RISK.md to name what is always high or customer-facing, so every change is mediumClassified: medium by default
Reviewer: Codex, gpt-6.1-sol, medium effort
Session:
01a1df97-1c5b-7573-8955-40c36b2ca597, round 1Score: 9/10,
The removal consistently updates Rust, JavaScript, and the draft while preserving recovery for partially read frames; source inspection found no actionable defects, but builds and tests were not run as instructed.Rounds: 1; first round 0; findings 0: fixed 0, refuted 0, open 0
Findings: none