6.4.4 - subtitle-resolution states the retained determination span
The #250 subtitle-resolution statement can now prove "empty because nothing was ever authored before this point" from a single post-seek line.
Added
-
retainedFrom=: the floor of the determination run the engine retains ACROSS a seek.coveredFromis the last reset's window start, so after a far seek it readstarget - 15and can neither affirm nor refute that determination still reaches back to track start. That left one truth class inexpressible from the line: on a PGS track whose first display set sits minutes in, a seek to an earlier point correctly renders nothing, but adjudicating that as determined emptiness rather than a dead pipeline needs coverage back to the earliest point that could change the answer. The load-time line does carry the bound, under the previousseekGen, and combining across the fence is exactly what the fence exists to forbid.The state was always retained:
reanchorSubtitleOverlaysleaves a drained channel's cues in place across a seek by design and rebuilds only the decoder and the PGS stale-arrival gate. What was missing was the record of it. The drain cursor now carries the retained run as a floor plus a high-water of its determined end, and a reset folds its window into that run instead of overwriting it.[AetherEngine] #250 subtitle-resolution loadGen=3 seekGen=8 stream=4 \ coveredFrom=15.00 retainedFrom=-15.00 resolvedThrough=90.00 \ via=prefetch decodedThrough=none reason=reconstructionTwo constraints shape it. The outgoing run's determined end is banked on the tick that produced it, never reconstructed later: by the next reset tick
seekGenerationhas advanced and the prefetch frontier no longer passes its own fence, so fetching it there would be the cross-generation combination the fence forbids. And the runs join only when the new window opens INSIDE the retained span, so a forward seek past the determined end (a hole the 15 s backscan does not reach over) and a backward seek starting below the floor (two disjoint intervals) both restart the run rather than span the gap. An idle tick decoded nothing and banks nothing, so unobserved frontier growth is never folded in.retainedFromis deliberately unclamped for the same reasoncoveredFromis: on a container withstart_time != 0a clamp to zero would claim coverage below the first PTS. It readsnonewhen a channel has decoded no run yet, and is never later thancoveredFrom.Requested by @cmcpherson274 (#276).
Compatibility
coveredFrom is unchanged in meaning and in fence semantics. The two are separate claims: coveredFrom is seek-fenced, retainedFrom deliberately outlives a seek generation because it is the engine reconciling runs it fenced itself, and it dies with the drain cursor, which every track switch and every session teardown clears, so it is still load-fenced.
The new field is inserted between coveredFrom= and resolvedThrough=. Consumers parsing the line by key are unaffected; a positional parser needs the extra field.
Upgrading
.package(url: "https://github.com/superuser404notfound/AetherEngine", from: "6.4.4")Source-compatible, no public API change. Diagnostic surface only: no behaviour change to subtitle decoding, drain scheduling, or rendering.