0025 — Locked/reviewed assets: approved, reproducible reels¶
Status: DRAFT
Date: 2026-06-29
Source: REPORT-keryx-in-anger-afmpeg-reel.md (request J).
Related: 0022 (voice configurability), 0023 (take workflow).
1. Goal¶
The durable fix for pronunciation on multilingual_v2 turned out to be human-reviewed,
committed vo/NN.mp3 clips rather than any runtime cleverness — take variance can
re-mangle a respelling on any regeneration. keryx should make "this line's audio is
approved — never re-roll it" an explicit, recorded state, so a build is reproducible
from the committed clips.
2. What already exists (this is thinner than it looks)¶
Verified 2026-06-29:
reel make'sbuildPlan(plan.go) already skips lines that have a selection (takes.HasVOSelected) — so a promotedvo/NN.mp3is not re-rolled on a re-run;reel makeis resume-idempotent.reel pruneclears onlytakes/+.cache/, never the selectedvo/NN.mp3.
So a selected clip is already fairly safe. What's missing is an explicit "approved"
state distinct from "a selection happens to exist", plus guards on the paths that do
overwrite a selection (voice pick, a future voice gen --best/--force), and a
reproducibility signal the human can trust.
3. Design¶
3.1 An explicit approved state¶
A selected asset can be locked (= reviewed/approved/frozen), recorded so tooling treats it as immutable. Locking applies uniformly across asset kinds — a VO line, a card image, the music bed, the cover (resolved §6 D2) — keyed by kind + index.
Storage (resolved §6 D1): a structured block in workspace.yaml, e.g.
locked:
vo: [1, 3, 5] # storyboard line indices
cards: [2] # card indices
music: true # the single bed
cover: true
Central, auditable, survives prune, and keeps review-state out of the creative
storyboard.json. The workspace.Meta gains a Locked field.
3.2 Commands + guards¶
keryx reel lock <kind> <index>/keryx reel unlock <kind> <index>toggles the state (kind∈vo|card|music|cover; index omitted for the singleton music/cover). Avoice pick --lock/--lockon the pick paths is a convenience that picks-then-locks.- A locked asset refuses destructive ops without
--force:voice pick/cards pick/ re-roll / a future--bestwarn + skip (so a bulk re-roll can't silently clobber an approved asset).reel makecontinues to skip selected items (it already does) and never offers to regenerate a locked one. reel prunealready spares selections; locking additionally records the provenance/ intent durably.
3.3 Reproducibility signal¶
reel plan(0024) andreel buildreport how many selected assets are locked vs merely selected — a reel whose every asset is locked is "reproducible from committed inputs". Surfaced in--output jsonfor CI.
3.4 Scope¶
Locking applies to all selected asset kinds (VO, cards, music, cover) under one uniform model (resolved §6 D2) — VO is the highest-variance and the report's concern, but the same approve-and-freeze intent applies to a hand-picked card or bed.
4. Requirements¶
- R-GEN-44 (MUST) A selected asset (VO line, card, music, cover) can be locked
(approved) and unlocked, recorded durably in
workspace.yaml(Meta.Locked). - R-GEN-45 (MUST) A locked asset is not overwritten by
voice pick/cards pick/ take re-roll / any regenerate-the-selection path without an explicit--force;reel makecontinues to skip it. - R-GEN-46 (SHOULD)
reel plan/reel buildreport locked-vs-selected counts so a fully-locked reel is known reproducible from committed inputs. - R-GEN-47 (SHOULD)
reel prunenever disturbs a locked selection or its recorded state (it already spares selections).
5. Testing (TDD)¶
voice lock/unlockpersists + round-trips the state (MemMapFs).- A locked line:
voice pick/ re-roll refuses without--force, succeeds with it; an unlocked line is unaffected. reel makeskips a locked line (and still skips a merely-selected one).reel planJSON reports the locked count.
6. Resolved decisions¶
Reviewed with Matt 2026-06-29:
- D1 (was Q1) — storage: a
lockedblock inworkspace.yaml(Meta.Locked) — central, auditable, survives prune, decoupled from the creative storyboard. - D2 (was Q2) — scope: all selected asset kinds (VO, cards, music, cover) under one uniform lock model, not VO-only.
- D3 (was Q3) — explicit lock is the point: "a selection exists" (already
resume-skipped by
reel make) does not capture "a human approved this"; the explicit, auditable approved state is the feature.
7. Open question (minor)¶
- Q4 — granularity. Per-asset lock only, or also a whole-reel
reel lock --all"freeze" that locks every current selection at once? Recommendation: per-asset is the primitive; add--allas sugar if wanted.