Repository navigation
fix(mux)!: stream fMP4 media payloads and bound held metadata - #7232
Conversation
Quest-Claim: ad6303096294c50d
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
|
Design change: Adopt the maintainer-confirmed refusal of backwards per-track sample byte ranges before publishing fragment payload. The streaming import path retains forward gaps and cross-track interleaving; complete-frame CMAF decoding keeps its existing random-access behavior. Metadata children will parse incrementally without a blanket byte cap, including variable-sized leaves. The draft now contains an unfinished streaming implementation checkpoint. Whole metadata bodies and subtitle samples still accumulate, so MUX-2 remains unresolved. Build admission stalled verification after one compile found private generic bounds, which were corrected but have not been verified. The quest and PR body retain the exact remaining work. (Written by GPT-6.1 Sol) |
…ilures Defer seek and discontinuity until a publishing fragment's last sample, discard the rest of a refused fragment's mdat after aborting its open frames, finish every track when EOF truncates a sample, release the catalog reservation only once a fragment anchors, and size the passthrough mdat header from its real encoding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tadata bound question Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # rs/moq-mux/src/container/fmp4/import.rs
A moov or moof body, and each text sample, must be held whole before it parses or rewrites, so a huge declaration retained every later HLS segment. Refuse one declaring more than MAX_HELD_BYTES (32 MiB, the transport's per-group MAX_CACHE_BYTES) at its header, before buffering any of it. A moof declaring more than MAX_FRAGMENT_SAMPLES samples is refused too, since a trun without per-sample fields declares billions of samples in a few bytes and planning resolves each one. A refused box now discards the rest of its body, including the part in the refusing call, so framing resumes at the next box. A failed moov or moof parse no longer leaves its body in the header buffer. This finishes quest/m1/security-audit/fmp4-stream-mdat.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Design change: bound held input at the header (maintainer decision, 2026-10-31, option 1 of the open question). The importer now refuses a One consequence of the bound, made as an implementation choice for review: a The quest is complete with this change, so its file is deleted. The PR body records the decision. (Written by Claude Opus 5.5) |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: ba5dcee
No actionable bugs found. Streaming media into output-owned frames while bounding whole metadata/text is a justified, simpler alternative to an incremental metadata parser; the sample-count bound also covers field-less trun expansion. Checked framing and refusal recovery, sample ordering/interleaving, passthrough offsets, deferred controls, truncation, and producer accounting, with an independent sample/passthrough review.
The documented parsed-state amplification and recovery restriction after refusals remain limitations. Static review only: I did not run tests or benchmarks or independently verify the reported performance results.
(Written by OpenAI)
There was a problem hiding this comment.
ℹ️ No critical issues. One stale comment from the changed bounding scheme, inline.
Reviewed changes
- Top-level framing is now incremental. Headers are read 8 bytes (16 for largesize) at a time, and a new
Bodystate (Skip/Metadata/Media) drains each box as bytes arrive instead of waiting for a whole atom. - Media streams into frame writers.
begin_mdatplans every sample range up front;write_mdatthen routes payload bytes into per-trackmoq_net::frame::Producers opened bystart_sample/Passthrough::startand closed byfinish_sample/complete. Passthrough fragments are now a moof+mdat-header prefix with the payload streamed behind it. - Held input is bounded.
begin_metadatarefuses amoov/moofbody overMAX_HELD_BYTES(32 MiB) at its header,end_metadatarefuses amoofoverMAX_FRAGMENT_SAMPLES(2^21), andtext::Track::preparerefuses a text sample over the byte bound before staging.Resolver::streaming()adds a per-track forward byte-range check. - Controls and failures are ordered.
seek()/discontinuity()defer until the publishing fragment completes; a refused fragment aborts its open frames and discards the rest of itsmdat;finish()aborts a truncated fragment and returnsUnexpectedEof. - Supporting changes.
Producer::writeis split into a sharedprepareplus the streaming sample methods; newErrorvariants andMAX_*consts; docs/quest updated; benches parameterized by chunk size; hostile-input tests added.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
|
No actionable comments were generated in the recent review.
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
The delta since the prior pullfrog review is the merge of main into the branch.
- Streamed samples move onto
main's producer API. The importer now opens each unwrapped sample throughcontainer::Producer::open/commitand writes into aStreamedhandle; this PR's Legacy-onlystart_sample/finish_samplepair and theprepare(&frame)split are dropped, andproducer.rsis nowmain's file. import.rsholds aWriterenum. APendingTrackkeeps either a passthrough fragment'smoq_net::frame::Produceror one sample'sStreamed, withopen_samplereplacingstart_sampleandunreachable!guards matching each writer kind on commit and abort.- Doc and quest bookkeeping follow
main. The MATROSKA/WebM row, quest README entries, and the deleted audit quests come from the merge.
The migration is behavior-preserving: open computes the same Legacy prefix through container::prefix(timestamp), prepare(timestamp, keyframe) is identical to the prior prepare(&frame), and commit's written(...) measures the same payload size the old finish_sample did. The abort paths (Mdat::abort, Import::abort, Drop) abort the Streamed/fragment writer exactly as before.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
|
quest land removed this pull request from the queue: the batch check failed (exit 101). @moq/net:test | subscribe start: id=0 broadcast=room track=video
@moq/net:test | track info: broadcast=room track=video
@moq/net:test | subscribe ok: id=0 broadcast=room track=video
@moq/net:test | publish ok: broadcast=room track=video
@moq/net:test | publish done: broadcast=room track=video
@moq/net:test | subscribe close: id=0 broadcast=room track=video
@moq/net:test | publish ok: broadcast=room track=video
@moq/net:test | publish done: broadcast=room track=video
@moq/net:test | publish ok: broadcast=room track=video
@moq/net:test | publish done: broadcast=room track=video
@moq/net:test | publish ok: broadcast=room track=video
@moq/net:test | publish done: broadcast=room track=video
@moq/net:test | fetch done: broadcast=room track=video group=0
@moq/net:test | https://localhost/test negotiated ALPN: moq-lite-07-wip
@moq/net:test | announced: prefix=
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=room active=true epoch=undefined
@moq/net:test | announced: broadcast=room active=true epoch=undefined
@moq/net:test | announce: broadcast=room active=false
@moq/net:test | announced: broadcast=room active=false
@moq/net:test | broadcast discovery failed; broadcasts resolve on request only. undefined
@moq/net:test | publish ok: broadcast=room track=video
@moq/net:test | publish done: broadcast=room track=video
@moq/net:test | subscribe start: id=0 broadcast=room track=video
@moq/net:test | subscribe ok: id=0 broadcast=room track=video
@moq/net:test | subscribe close: id=0 broadcast=room track=video
@moq/net:test | subscribe start: id=0 broadcast=room track=video
@moq/net:test | subscribe ok: id=0 broadcast=room track=video
@moq/net:test | subscribe close: id=0 broadcast=room track=video
@moq/net:test |
@moq/net:test | src/lite/malformed.test.ts:
@moq/net:test | probe stream error warn: unexpected end of stream
@moq/net:test | at #fillTo (/work/js/net/src/stream.ts:340:11)
@moq/net:test | at async decode (/work/js/net/src/stream.ts:396:15)
@moq/net:test |
@moq/net:test | probe stream error warn: unexpected end of stream
@moq/net:test | at #fillTo (/work/js/net/src/stream.ts:340:11)
@moq/net:test | at async decode (/work/js/net/src/stream.ts:396:15)
@moq/net:test |
@moq/net:test | probe stream error warn: unexpected end of stream
@moq/net:test | at #fillTo (/work/js/net/src/stream.ts:340:11)
@moq/net:test | at async decode (/work/js/net/src/stream.ts:396:15)
@moq/net:test |
@moq/net:test |
@moq/net:test | src/lite/publisher.test.ts:
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=static active=true
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=static active=true epoch=undefined
@moq/net:test | announce: prefix=
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=cam active=true epoch=undefined
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=cam active=true epoch=undefined
@moq/net:test | announce: broadcast=cam update=true
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=cam active=true epoch=undefined
@moq/net:test | announce: broadcast=cam active=false
@moq/net:test | announce: broadcast=cam active=true epoch=undefined
@moq/net:test | announce: prefix=
@moq/net:test | announce: broadcast=cam active=true epoch=undefined
@moq/net:test | announce: broadcast=cam restart=true epoch=undefined
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish error: broadcast=test track=video error=remote error: 1
@moq/net:test | datagram send stopped: sub=0 error=remote error: 1
@moq/net:test | publish ok: broadcast=test track=video
error: recipe `test-changed` failed on line 54 with exit code 143
ci: test rs failed
ci: seconds per module
263 check py
26 test py (cancelled)
72 check rs
217 test rs (failed)
230 check js
59 test js (cancelled)
289 wall time
error: recipe `ci` failed on line 107 with exit code 101
. |
|
codex / Codex land fixer: (written by codex / Codex) |
|
quest land removed this pull request from the queue: the batch check failed (exit 100). @moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | publish done: broadcast=test track=video
@moq/net:test | publish ok: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
@moq/net:test | subscribe update: broadcast=test track=video
error: recipe `test-changed` failed on line 54 with exit code 143
ci: test rs failed
ci: seconds per module
49 check rs
225 test rs (failed)
213 check js
61 test js (cancelled)
0 check drill
2 check quest
17 check shell
0 check large_files
0 check toml
1 check nix
0 check justfile
274 wall time
error: recipe `ci` failed on line 107 with exit code 100
. |
|
codex / Codex land fixer: (written by codex / Codex) |
Rewrite the fMP4 follow-up to its remaining refused-box and benchmark work now that #7232 streams through open/commit, repoint the deleted clock-test-process link at #7243, refresh line references, and fix the CodeRabbit findings on unroutable, into_any callers, auth compatibility, dialable schemes, e2ee seal/open limits, and trun amplification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Narrow the io_uring group to one invocation and check membership with show-config, correct the relay CPU range to 18-56%, count revalidate in the session index, describe DeclaredClock's slot-based decode times, scope the fMP4 text-sample exception, attach gdb to the parked bench, refuse unlocked repairs and recordings, report datagram expiry and on-time delivery, define wildcard members' literal prefix, spell out the opaque NVDEC path, and record #7232 as merged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve the modify/delete conflict on quest/m1/security-audit/fmp4-stream-mdat.md by taking main's deletion (#7232 finished it; this branch only dropped its media-fuzz link). Align quests with main: - fuzz-findings/README.md: drop Related links to the security-audit MKV and fMP4 streaming quests, both finished on main. - mkv-block-header.md: #7234 replaced webm-iterable's block parsing with moq-mux's own header reader, so the 4-byte mkv reproducer now fails with InvalidSimpleBlock. Commit it under fuzz/regressions/mkv/ and delete the quest. - mkv-truncated-finish.md, import-metadata-policy.md, sps-fuzz-h264-reader.md: stop linking media-fuzz.md, which this PR finishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Problem
An fMP4 box claiming a huge body retained later input across HLS segments (MUX-2 from the 2026-10-27 audit). Whole-box decoding waited for every byte a header declared, so one bogus
mdat,free,moov, ormoofheader could accumulate every later segment. This PR finishesquest/m1/security-audit/fmp4-stream-mdat.md.Approach
moovormoofbody, or one text sample, has to be complete before it parses or is rewritten. One declaring more thanfmp4::MAX_HELD_BYTES(32 MiB, the transport's per-groupMAX_CACHE_BYTES) is refused before any of it is buffered. Media samples have no such bound.trunwithout per-sample fields declares its count in four bytes, and planning resolves every sample. Amoofdeclaring more thanfmp4::MAX_FRAGMENT_SAMPLES(2^21) samples is therefore refused when it parses. That is as many 16-byte entries as fit in the byte bound.mdatheader left the importer parsing thatmdat's payload as boxes. A failedmoov/moofparse also left its body in the header buffer.seek()anddiscontinuity()wait for its last sample, so neither can close or replace a group under an unfinished sample.UnexpectedEof.main. Passthrough headers take theirmdatheader size from the real encoding (16-byte largesize past 4 GiB) and check that eachdata_offsetfitsi32.Decisions
✅ No byte cap on media; stream each sample into its frame (maintainer, 2026-10-27). A fragment can hold several GOPs.
✅ Refuse backwards per-track byte ranges before publishing fragment payload (maintainer, 2026-10-29). A sequential group writer cannot support those layouts without retaining earlier payload.
How should metadata and staged text samples be bounded? (maintainer, 2026-10-31)
moov/moofor text sample over a fixed 32 MiB before buffering any of it. Drop incremental metadata parsing.This reverses the 2026-10-28 AFK choice (incremental metadata parsing, no cap), but only for held metadata and text. Implementation showed incremental parsing could not bound what it keeps. A valid
trunor a large text sample would still retain later segments. See theDesign change:comment.✅ Refuse a
moofdeclaring more thanfmp4::MAX_FRAGMENT_SAMPLES(2^21) samples, alongside the 32 MiBMAX_HELD_BYTESbound (maintainer, 2026-10-31, accepted at/quest-merge). It closes the field-lesstrungap that the byte bound leaves; real fragments carry hundreds to thousands of samples.Choices made without asking, listed for review:
seek()/discontinuity()are deferred to the end of a publishing fragment, rather than refused or abandoning it. HLS issues controls between segments, and the old whole-mdatimport never split a fragment across one.pub consts, so callers can see the limit they hit.Coordination with moq-dev/moq#7234 (MKV streaming): fix(mux)!: stream MKV blocks and discard ignored elements in one pass #7234 landed first, so the merge of
mainmoves the streamed unwrapped samples onto itscontainer::Producer::open/commitand drops this PR's Legacy-onlystart_sample/finish_sampleand itspreparesplit;producer.rsis nowmain's. Passthrough fragments keep their own frame writer, held beside a sample'sStreamedin oneWriterenum.Impact
fmp4::MAX_HELD_BYTES,fmp4::MAX_FRAGMENT_SAMPLES, and the error variantsBackwardsDataOffset,MetadataTooLarge,TextSampleTooLarge, andTooManySamplesto the#[non_exhaustive]fmp4::Error. No signature changes.moov,moof, or text sample over 32 MiB, or amoofover 2^21 samples, is refused.Import::finishnow finishes every track before returningUnexpectedEoffor a truncated sample; onmainit silently dropped a partial atom. Complete-frame CMAF decoding keeps its random-access behavior.doc/lib/rs/moq-mux.mdnotes the forward-order requirement and the bound.Alternatives
Incremental metadata parsing (2026-10-28 plan) was dropped; see the decision above. A blanket byte cap on media was rejected (2026-10-27). Upstream mp4-atom 0.17 exposes incremental headers, but its body readers buffer whole bodies. The output cache pool cannot bound held metadata, because it evicts cached groups rather than refusing writes.
Validation
oversized_metadata_is_refused_at_its_header:moovandmoofdeclaring 32 MiB + 1 and 2^62 bytes are refused at the header's last byte. 256 later 1 KiB segments are discarded with nothing held.metadata_at_the_bound_holds_only_what_arrived: amoofdeclaring exactly 32 MiB holds only the 1 KiB that arrived.huge_trun_sample_counts_are_refused: field-lesstruns declaringu32::MAX, 2^21 + 1 across two runs, and 4 xu32::MAXsamples (under 256 bytes of input each) are refused. The followingmdatis discarded and the next fragment imports. 2^21 exactly is accepted.oversized_text_sample_is_refused_before_staging: a WebVTT sample of 32 MiB + 1 is refused at themdatheader, before any payload. Its mdat is discarded, and the next cue imports.backwards_ranges_fail_before_publishingnow also checks that framing resumes after the refusedmdat.mdatwith output-owned samples and cache accounting, ignored boxes across cuts, deferred controls, truncation at EOF, and refused-fragment recovery. The ignored-box test from 95ec598361 fails on the pre-fix source and passes here.fieldless_runs_do_not_stall_the_segment_scan(from main) now expectsTooManySamples, since such amoofis refused before the scan.cargo nextest -p moq-mux fmp4 producer: 359 passed. Clippy-D warningsis clean.quest gate just ci origin/mainon ba5dcee: passed (rs 4281 tests, rs_shapes, js, markdown, gh, drill, quest, shell, toml, nix, justfile).cargo bench -p moq-mux --bench containers -- cmaf, run againstmain(same bench file, saved baseline), load average 3-4. The 72cmaf-interleaved-*cases stay within about 2% at 1-byte, 1 KiB, and whole-input chunks, except the 4-track 16-run 4096-byte whole-input cases:The 4-track
cmaf-import-*/cmaf-unwrap-*cases are bimodal on this host. They swing ±40% between runs of the same source, in both directions. The-framesand-bytesgroups run identical workloads, yet disagreed with each other in the first run. The single-track cases stay within a few percent. I see no consistent regression; the interleaved whole-input import case is the one to watch.quest gate just check origin/mainon d525dd8: passed.main(5dbdb5a):cargo nextest run -p moq-mux1922 passed;quest gate just check origin/mainpassed.quest check: passed.moq-relay::integration stack::debug_relay_load_and_run_fit_windows_stackoverflowed its 1 MiB stack, and the fixer attributed that to moq-dev/moq#7467 too.moq-relaydoes not depend onmoq-mux(cargo tree -p moq-relay -i moq-muxmatches no package), and the test passes on this head.mainagain (3ae1738):quest gate just ci origin/mainwithCHECK_MODULES=rspassed (rs 4385 tests). The full changed-scopequest gate just ci origin/mainpassed every module except one rs test,moq-transcode tests::ended_demand_opens_no_new_live_group. It hit a 10 s timeout under a paused clock while the suite was loaded. That test passed in the rs-only run and in 40 of 40 isolated runs.moq-transcodenever reaches the fMP4 importer; this is a load flake, listed under Follow-ups.Review
gpt-6-astramedium (quest review --deep, new session), head 3ae1738 (merge ofmainat 802cadc; latermaincommits touch none of this PR's paths), 2 rounds:moofplan bound is the maintainer's recorded decision, re-picked at/quest-merge, and the 2026-10-31 design change dropped incremental resolution. It stays a follow-up below.gpt-6-astramedium (quest review --deep), head 5dbdb5a (the merge ofmainwith the open/commit move), 2 rounds:trunof 2^21 samples plans every sample before its payload arrives). The 2^21 per-moofplan bound is the maintainer's recorded decision above, sized to what a legal 32 MiB explicitmoofalready plans; incremental resolution is the direction the 2026-10-31 design change dropped. The amplification stays a follow-up below.gpt-6-astramedium (quest review --deep), head d525dd8: 0 findings.starts_segmentdoc comment still creditingmdat_lenwith the scan bound; fixed in d525dd8 by naming theMAX_FRAGMENT_SAMPLESrefusal inend_metadata. The OpenAI review reported no actionable bugs.gpt-6-astramedium (quest review --deep --new, new session after the design change), head ba5dcee: 0 findings.Follow-ups
quest/m1/security-audit/fmp4-open-commit.md(added by moq-dev/moq#7468, not yet onmain): its open/commit bullet is done here; the refused-box and benchmark bullets remain.moov/moofdecodes into larger in-memory structures (TrunEntryis 40 bytes per 4-16 input bytes). It is bounded but not tight; Media fuzz would measure it.moq-transcode tests::ended_demand_opens_no_new_live_group: astart_pausedtest whose live path waits on real encode threads, so the paused clock can auto-advance past its 10 s timeout under load. No quest tracks it yet.🤖 Generated with Claude Code
(Written by GPT-6.1 Sol and Claude Opus 5.5)