Skip to content

0024 — reel plan: VO-driven timing + pre-build sanity

Status: DRAFT Date: 2026-06-29 Source: REPORT-keryx-in-anger-afmpeg-reel.md (request G, pinch point #5). Related: 0023 (take workflow), the reelcmd.ReelTimingFromVO helper (keryx !76).

1. Goal

There is no way to see the VO-driven total or per-card timing before a build. The build log shows only an inaccurate fallback duration (the report saw 69s logged for a ~90s reel), so sizing the music bed meant summing ffprobe durations across vo/*.mp3 in python. Expose the real timing as a command.

2. What already exists

reelcmd.ReelTimingFromVO (extracted in keryx !76) computes per-card durations + the assembled reel.Timeline (Starts, VODelaysMS, XFadeOffsets, Total) by probing the promoted vo/NN.mp3 clips — the same maths reel build and music gen --takes use. This spec surfaces it; the computation already exists and is unit-tested.

3. Design

A read-only keryx reel plan --workspace <slug> command (no generation, no render):

  1. Resolves the render backend (for Probe) exactly as build does, probes the promoted VO, and runs ReelTimingFromVO.
  2. Reports, per card: index, on-screen dur, start, vo_delay, and the source of the duration (VO clip vs. storyboard dur fallback).
  3. Reports the VO-driven total and the implied music-bed length (what music gen --takes would request) so the bed can be sized confidently.
  4. Pre-build sanity (the bit that turns it from a duration printout into a pre-flight): flags lines with no promoted VO (→ silent fallback or "takes generated, none selected"), overlay cards missing media, a missing cover, and whether a music bed is present.
  5. Text (human table) + --output json (machine-readable for the studio / CI).

It degrades gracefully: with no VO promoted it reports the silent-render durations (from storyboard dur) and says so, rather than erroring.

4. Requirements

  • R-GEN-40 (MUST) reel plan --workspace <slug> prints the VO-driven total and per-card timing (dur/start/vo_delay) without generating or rendering anything.
  • R-GEN-41 (MUST) The total matches what reel build would assemble (shared ReelTimingFromVO); the reported bed length matches what music gen --takes requests.
  • R-GEN-42 (SHOULD) reel plan flags pre-build gaps: lines missing VO, unpromoted VO takes, overlay cards missing media, missing cover, absent music bed.
  • R-GEN-43 (SHOULD) --output json emits the timing + gaps for the studio/CI.

5. Testing (TDD)

  • Given promoted VO (fake renderer probe), reel plan reports the same total as ReelTimingFromVO / build; per-card start/vo_delay match reel.BuildTimeline.
  • No-VO workspace → silent-fallback durations reported + flagged (no error).
  • Gap flags: a missing-media overlay card and an unpromoted-takes line are surfaced.
  • JSON shape stable (golden).

6. Resolved decisions

Reviewed with Matt 2026-06-29:

  • D1 (was Q1) — name: reel plan (pre-flight framing, pairs with reel make).
  • D2 (was Q2) — breadth: timing + asset-gap flags (§3.4) — the gap pre-flight is what makes it worth running before build, and the data is already at hand (R-GEN-42).
  • D3 (was Q3) — probe backend: mirror buildplan resolves providers.render and probes through it (a default-ffmpeg setup needs the binary; an afmpeg setup probes in-memory, zero-config since !75). Documented, not configurable separately.