Repository navigation
t27f R4b.1: beat graph -- the reel's three scenes crossfaded at the beat clock's cuts, on whole frames #10603
Copy link
Copy link
Closed
Labels
Description
Sub-issue of epic #10560 (content factory), R4b part 1. It builds on R4a (#10596, PR #10598).
R4a's beat clock says when each of a reel's three beats (open, main, close) is on screen. Nothing yet turns those cuts into video.
How the reference tools do it:
- Remotion's
TransitionSeriestakes per-sequence frame counts and overlapping transitions. - ffmpeg's
xfadetakes an offset in seconds and starts reading the incoming stream at that offset.
Cuts given in milliseconds also do not sit on frames. A crossfade that starts between two frames shifts by up to one frame, and two cuts rounded independently could take a frame from a scene that has exactly MIN_SCENE_FRAMES.
Boundary
- In:
specs/t27f/lesson_reel.t27and its seal.- Each cut gets a crossfade start frame.
maingainsLR_MODE=4, which prints the beat graph: three scene videos (inputs 0, 1, 2: open, main, close) crossfaded at the clock's cuts and trimmed to the reel's 15 s.
- Out:
- Drawing the scenes (R3, t27f factory R3: a renderer per scene archetype and the still anomaly gate (SSIM) #10571 / PR t27f: scene renderers for the 12 archetypes and the still anomaly gate (R3) #10592).
- Laying mode 3's captions and address over the beat video (R4c).
- Rendering every lesson.
User Scenarios
- A frame renderer that has the three scene clips runs one ffmpeg command with the mode 4 graph. It gets a 450-frame reel whose picture changes when the goal starts being spoken and when the address appears.
- A reviewer reads the crossfade start frames for any lesson and voice, without rendering.
Requirements
- R1. The crossfade for cut c starts at frame
floor((c - 250) * BASE_FPS / 1000)and lastsTRANSITION_FRAMES. - R2. On every voice of R4a's grid where the clock gives every beat a scene, every beat is alone for at least
MIN_SCENE_FRAMESwhole frames once both cuts are on frames. - R3. The xfade offset printed for a start frame f is
beat_frame_ms(f). It selects frame f and no earlier one:beat_frame_ms(f) * BASE_FPSlies in((f - 1) * 1000, f * 1000]. - R4. Mode 4 refuses a voice that does not fit, exactly as mode 3 does.
- R5. Measured on the Railway lab with ffmpeg: the graph run on three solid-colour 15 s inputs gives 450 frames. The frame just before each crossfade is still the outgoing colour, and the frame just after it is the incoming colour.
Success Criteria
t27c test-report specs/t27f/lesson_reel.t27passes on the lab with 0 vacuous tests.- Seal saved and verified; the ledger row is unchanged;
max_not_passis unchanged. - The PR records the ffmpeg measurement: frame count, and the pixel colour at the frames around each cut.
Requirements
- FR-001: The crossfade for cut c MUST start at frame
floor((c - 250) * BASE_FPS / 1000)and MUST lastTRANSITION_FRAMES. - FR-002: On every voice of R4a's grid where the clock gives every beat a scene, every beat MUST be alone for at least
MIN_SCENE_FRAMESwhole frames once both cuts are on frames. - FR-003: The xfade offset printed for a start frame f MUST be
beat_frame_ms(f). It MUST select frame f and no earlier one:beat_frame_ms(f) * BASE_FPSMUST lie in((f - 1) * 1000, f * 1000]. - FR-004: Mode 4 MUST refuse a voice that does not fit, exactly as mode 3 does.
- FR-005: Measured on the Railway lab with ffmpeg, the graph run on three solid-colour 15 s inputs MUST give 450 frames. The frame just before each crossfade MUST still be the outgoing colour, and the frame just after it MUST be the incoming colour.
Reactions are currently unavailable
Activity
t27f skill: cut video on a frame and check it by counting solid-colou…
github-actions commentedon Oct 18, 2026
Closed by the issue-shape gate (specs/policy/issue_shape.t27, #7498): an issue must have the template's sections. Edit the body; an edit that passes reopens it.
FR-001: ... MUST ...t27f: R4d -- mode 5 overlays live inside one scene, none on a beat cr…
t27f: R4f -- mode 5 holds the address for REEL_CTA_MIN_MS, cut 1 capp…
t27f: R4e -- mode 5 cards stay inside one scene, token_floor_mux take…
gHashTag commentedon Oct 19, 2026
Reopened by the self-heal of #11007. The issue-shape gate closed this issue with a queued run that judged an older body from its event payload; the current body passes
gen/c/policy/issue_shape.c, and the gate's own contract is that a passing body stays open. If the work is in fact finished or obsolete, close it as completed.gHashTag commentedon Oct 19, 2026
Landed on master by #10627 (merged 2026-10-18, d61e981), which carried this work after its own PR was closed. Closing as done. Tracked in mega epic #11038.
🤖 Generated with Claude Code