The #74 review pass surfaced items that are real but out of scope for the epic. Parking them here with the evidence so they don't evaporate.
1. Held-tail mapping divergence (editor vs catalog) — MEDIUM. In the held-tail region the editor steering paths clamp localFrame to clip.duration - 1 (DecodeSystem.cpp ~:283, AudioSystem.cpp ~:338) while the catalog math (mapToMediaFrameFromCatalogEx, used by the presenter AND the stall fallback) clamps to realEnd - 1 / the phase tail-hold frame. For a Normal clip whose extension is capped at source-out short of the fade window (extendedDuration > duration but < duration+fadeFrames), the two mappings differ by the extension length. Consequences: (a) each stall handoff in that region can trip the audio discontinuity detector (systematic offset >> slack → ring-clear dropout) and force-seek video; (b) pre-existing: the editor steers the decoder toward a different held frame than the presenter requests. Likely right fix: the editor's held-tail clamp should match the catalog (realEnd - 1) — needs its own test around partially-extended fade breaks.
2. Window-gate predicate is quadruplicated — MEDIUM (maintenance). The inAuthored/inExtension/inTail/inTailHeld block now exists in DecodeSystem::update, DecodeSystem::tickFromSnapshot, AudioSystem::update, AudioSystem::tickFromSnapshot, held in sync by comments. This block churned 3× on 2026-05-23 alone. Extract one free function (e.g. computeClipActiveWindow(...) next to computeExtendedDuration in Clip.hpp) returning the four bools; same for the continuation predicate (also written 3×). The registry-side frame-mapping in both update()s is likewise a hand-mirrored sibling of mapToMediaFrameFromCatalogEx — candidates for one shared core.
3. Show-thread worker-map lock traffic — LOW until measured. PlaybackPresenter::present now takes DecodeSystem's m_workersMutex once per active clip per frame (was a lock-free raw read pre-#74, which was the NEW-11 race). If the pending stress_8screen_progressive capture (blocked on GPU-hung reboot, see #74 thread) shows contention: batch to one lock per present() via a snapshotWorkers() accessor, and batch tickFromSnapshot's per-entry findWorker the same way. Editor-side update() could also use unlocked reads (editor is the sole mutator) via a documented private accessor.
4. Minor, listed for completeness: lastExpectedSample/lastExpectedSampleNs are two relaxed stores (a preemption-unlucky overlap can tear the pair and mis-fire one audio seek — bounded, rare after the pre-update heartbeat re-stamp); SleepMs remains a misleadingly-named non-blocking wait (one caller left: screen_no_double_allocation.json — migrate + delete or rename); audio workers on clips with failed VideoTexture slot allocation are invisible to the stall fallback (documented accepted gap for the transient case; becomes real if audio-only clips land).
The #74 review pass surfaced items that are real but out of scope for the epic. Parking them here with the evidence so they don't evaporate.
1. Held-tail mapping divergence (editor vs catalog) — MEDIUM. In the held-tail region the editor steering paths clamp
localFrametoclip.duration - 1(DecodeSystem.cpp ~:283, AudioSystem.cpp ~:338) while the catalog math (mapToMediaFrameFromCatalogEx, used by the presenter AND the stall fallback) clamps torealEnd - 1/ the phase tail-hold frame. For a Normal clip whose extension is capped at source-out short of the fade window (extendedDuration > durationbut < duration+fadeFrames), the two mappings differ by the extension length. Consequences: (a) each stall handoff in that region can trip the audio discontinuity detector (systematic offset >> slack → ring-clear dropout) and force-seek video; (b) pre-existing: the editor steers the decoder toward a different held frame than the presenter requests. Likely right fix: the editor's held-tail clamp should match the catalog (realEnd - 1) — needs its own test around partially-extended fade breaks.2. Window-gate predicate is quadruplicated — MEDIUM (maintenance). The inAuthored/inExtension/inTail/inTailHeld block now exists in DecodeSystem::update, DecodeSystem::tickFromSnapshot, AudioSystem::update, AudioSystem::tickFromSnapshot, held in sync by comments. This block churned 3× on 2026-05-23 alone. Extract one free function (e.g.
computeClipActiveWindow(...)next tocomputeExtendedDurationin Clip.hpp) returning the four bools; same for the continuation predicate (also written 3×). The registry-side frame-mapping in both update()s is likewise a hand-mirrored sibling ofmapToMediaFrameFromCatalogEx— candidates for one shared core.3. Show-thread worker-map lock traffic — LOW until measured. PlaybackPresenter::present now takes DecodeSystem's m_workersMutex once per active clip per frame (was a lock-free raw read pre-#74, which was the NEW-11 race). If the pending stress_8screen_progressive capture (blocked on GPU-hung reboot, see #74 thread) shows contention: batch to one lock per present() via a
snapshotWorkers()accessor, and batch tickFromSnapshot's per-entry findWorker the same way. Editor-side update() could also use unlocked reads (editor is the sole mutator) via a documented private accessor.4. Minor, listed for completeness:
lastExpectedSample/lastExpectedSampleNsare two relaxed stores (a preemption-unlucky overlap can tear the pair and mis-fire one audio seek — bounded, rare after the pre-update heartbeat re-stamp);SleepMsremains a misleadingly-named non-blocking wait (one caller left: screen_no_double_allocation.json — migrate + delete or rename); audio workers on clips with failed VideoTexture slot allocation are invisible to the stall fallback (documented accepted gap for the transient case; becomes real if audio-only clips land).