Repository navigation
member_spans: where each episode member is heard on its mix - #97
Merged
Merged
Conversation
Pairs ordered_member_ids[i] with the timeline span whose index is i (the captions' and picture track's rule) and returns exclusive, ordered placements: the weave's crossfade puts a member's start a fraction of a second before the previous end, so each placement starts where the previous one finished, as cues_for clamps its cues. A member with no span has no placement (None), never one rebuilt from durations. First customer: reelee's commentary takes read (reeleehq/reelee#546). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efuse unpairable timelines Adversarial review of #97: the clamp squeezed a member laid under what follows (layout_placed's 'under') to zero length; spans could pass the mix end; a timeline whose indices are not positions paired members with their neighbours' intervals; a malformed timeline raised. Now: an under member keeps its true span and is marked concurrent, only the sequential lane is made exclusive, intervals are bounded by duration_s, an unpairable or unreadable timeline gives null placements, and the importer refuses a timeline whose indices are not distinct member positions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round-2 review of #97: inferring 'under' from 'a later member starts earlier' missed ties (an under clip at position 0, a zero crossfade) and flagged short sequential members. BeatSpan now carries layout_placed's placement (additive: written only when recorded, so older breakdowns round-trip to the same bytes), build_timeline records it, and member_spans reads it. An older breakdown is read off the layout's own signature: an under member starts exactly at the end of the sequential lane and the next member starts at or before it. Only KeyError/ValueError mean an unknown placement now; the importer reads timeline indices as from_dict does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round-3 review of #97: the lane end and the next start are each rounded, so the older-timeline inference needs a 2.5 ms tolerance (property-tested against layout_placed); a sequential member shorter than its tuck keeps its true span (concurrent) and still advances the lane; a null duration gives an unknown placement again; from_dict accepts only 'sequential' or 'under' as a recorded placement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
braidio.transforms.member_spans(project, episode): each member of anepisode-render/v1, in play order, with where it is heard on the mix (MemberSpan(member_id, position, start_s, end_s, concurrent)).ordered_member_ids[i]↔ the timeline span whoseindexisi, the ruleepisode_script+captions.cues_forand the picture track already rely on.cues_forclamp).underwhat follows, or shorter than its tuck, keeps its true span and is markedconcurrent.duration_s. Unknown placement (None) when there is no span, the timeline is malformed or cannot be rebuilt, or its indices are not member positions; never rebuilt from durations.BeatSpan.placement(additive):build_timelinerecords layout_placed'ssequential/under,to_dictwrites it only when recorded (older breakdowns round-trip to the same bytes),from_dictaccepts only those two values. Older breakdowns are read off the layout's own signature, property-tested againstlayout_placed(exact agreement on 3000 random realistic layouts).First customer: reeleehq/reelee#546 (a spend-free read of commentary takes with text and place on the mix, for reelee-web#356). Follow-up filed: #98.
Checked
tests/test_importing.py: negative control for the clamp, under/tucked/tie cases, bounds, unpairable and malformed timelines, the importer refusal, the property test. 93 pass; timeline, video-transforms and doctests pass.py2mcp-dependent files fail locally (module absent from the local venv).Adversarial review
Three rounds by a fresh Opus reviewer.
underfrom start order missed ties (cold-open under clip, zero crossfade) and flagged short members. Fixed by recordingplacementand reading older timelines off layout_placed's signature.placementinto_dicttouches no plan identity, cache key or fingerprint. Remaining by design: older timelines made of parts shorter than the clip edge are ambiguous without a recorded placement (documented).🤖 Generated with Claude Code