| name | create-founder-led-video-ad |
| description | create a short-form vertical video ad from a founder talking-head recording. applies the creator-talking-head archetype — jump-cut breath removal, hook-first reorder, b-roll inserts over VO, karaoke captions — using the EDL editorial pipeline (generate-edit-decision-list → render-edl). use when a founder take exists and needs to be re-edited into a creator-native ad. |
create-founder-led-video-ad
Purpose
Turn a raw founder talking-head recording into a creator-native short-form video ad. The
archetype is creator-talking-head (CREATOR_GRAMMAR.md §8): speech-only audio, karaoke-pop
captions, jump-cut breath removal on every pause above the gap threshold, and optional b-roll
inserts over continuous VO.
The edit/assembly path is the EDL editorial pipeline:
transcribe-audio-fal — generate word-timestamps from the recording.
create-jump-cuts — remove every breath/pause gap above 0.35 s (the defining creator-native edit).
generate-edit-decision-list (conform mode) — plan the full cut rhythm: reorder so the
strongest claim is the hook, place b-roll-insert cues over VO, mark the payoff-hold clip,
and write the validated edl.json.
render-edl — assemble the master video from the EDL, burn karaoke captions, write manifest.
add-captions-klap (optional override) — use Klap instead of render-edl's ASS captions when
brand caption style requires Klap's animated treatment.
- Human review +
/watch:watch self-QC.
The goal is to make a founder's raw take feel like a trusted creator made it — tight delivery,
hook-first structure, captions as the visual spine, ending that may cut mid-sentence.
Inputs
| Input | Required | Notes |
|---|
source_video | yes | path to the raw founder talking-head recording (.mp4, .mov, or .m4v) |
target_duration_s | yes | target clip length in seconds (typical: 20–60 s) |
brand_brief | yes | brand name, product claim, audience, platform (default: IG Reels / TikTok 9:16) |
b_roll_clips | no | list of additional clip paths (screen recordings, product footage) to insert as b-roll over VO |
gap_threshold_s | no | pause removal threshold (default 0.35 s; raise for deliberately slow delivery) |
caption_preset | no | caption preset ID from caption-style-presets.json (default platform-default) |
use_klap_captions | no | boolean; if true, run add-captions-klap instead of render-edl's built-in ASS captions |
output_dir | yes | directory for all outputs and the run manifest |
Composed Atoms
skills/atoms/voiceover/transcribe-audio-fal — generate word-timestamps JSON from the recording
skills/atoms/editing/create-jump-cuts — remove breath/pause gaps to produce a tighter re-encoded take
skills/atoms/planning/generate-edit-decision-list — produce edl.json in conform mode for the creator-talking-head archetype
skills/atoms/assembly/render-edl — execute the EDL into master.mp4 (video + karaoke captions + audio)
skills/atoms/captions/add-captions-klap — optional: replace ASS captions with Klap animated captions
Workflow
Phase 1 — Prepare inputs
- Confirm
source_video exists on disk. If the file is missing, stop and report.
- Confirm
ffmpeg and ffprobe are installed (ffmpeg -version). If missing, stop and report.
- Confirm
output_dir exists or create it.
Phase 2 — Transcribe
Run transcribe-audio-fal on source_video to produce working/words.json
(word-timestamps in [{"text", "start", "end"}] shape).
If transcription fails, stop — the word-timestamps are required for every downstream step.
Phase 3 — Jump-cut breath removal
Run create-jump-cuts using the word-timestamps to remove every inter-word and inter-sentence
gap above gap_threshold_s (default 0.35 s):
python3 skills/atoms/editing/create-jump-cuts/scripts/jump_cut.py \
--source <source_video> \
--words <output_dir>/working/words.json \
--output <output_dir>/working/tight-take.mp4 \
--gap-threshold <gap_threshold_s> \
--crf 18
Review manifest.json from this step: confirm total_removed_seconds > 0. If the take has no
pauses above threshold, the tight take equals the source — that is fine, proceed.
Caution: if gap_threshold_s is unusually low (< 0.20 s) on a slow-paced intentional delivery,
jump cuts will over-cut the speaker's cadence. Use the default (0.35 s) unless the brief
explicitly calls for a faster chop.
Phase 4 — Generate the EDL (conform mode)
Run generate-edit-decision-list in conform mode with the creator-talking-head archetype.
Pass the word-timestamps from Phase 2 (aligned to the tight take's timeline after Phase 3).
Key behaviors the EDL generator applies:
- Hook-first reorder — identifies the strongest benefit-forward sentence in the transcript
and moves it to the first 0–15% of the target duration as the hook clip.
- Jump-cut boundaries — each contiguous speech run in the tight take becomes a clip with
transition_in: "jump-cut".
- B-roll inserts — if
b_roll_clips are provided, inserts them as b-roll-insert cuts
over continuous VO at natural phrase boundaries.
- Payoff-hold — marks the strongest visual proof moment as
role: "payoff-hold" (~2× mean
shot length, per archetype parameters in archetypes.json).
- Karaoke captions — places per-word caption cues from the word-timestamps, using
caption_preset (default platform-default).
python3 skills/atoms/planning/generate-edit-decision-list/scripts/edl_pacing.py \
--archetype creator-talking-head \
--target-duration <target_duration_s>
Validate: run edl_validate.py on working/edl.json. All nine schema validation rules must
pass before proceeding to render.
Phase 5 — Render the master
Run render-edl on the validated EDL:
python3 skills/atoms/assembly/render-edl/scripts/render_edl.py \
--edl <output_dir>/working/edl.json \
--output <output_dir>/finals/master.mp4 \
--crf 18
render-edl will:
- Trim conform clips from
tight-take.mp4 (and b-roll source files) per source.in/source.out.
- Concatenate as hard cuts.
- Burn karaoke-pop ASS captions (unless
use_klap_captions is true — see Phase 6).
- Write
manifest.json to finals/.
Phase 6 — Captions (conditional)
Default (use render-edl built-in ASS): no extra step needed; captions are burned in Phase 5.
Klap override (use_klap_captions: true): run add-captions-klap on the master produced in
Phase 5, replacing the ASS captions with Klap's animated treatment. Use this when the brand's
existing ads use Klap-style animated captions and matching that treatment is required.
Phase 7 — Self-QC and human review
- Run
/watch:watch (or equivalent frame-extraction + transcribe) on finals/master.mp4. Do
not declare done from a still frame — verify captions, cut rhythm, and hook placement by
watching the video.
- Confirm:
- The hook (first ~15% of the video) contains the strongest product claim.
- Breath/pause gaps are removed; delivery feels tight.
- If b-roll was inserted, audio is continuous (L-cut) under the inserts.
- No caption/hyperframe text collision.
- Duration is within ±0.5 s of
target_duration_s.
- Write
verification.md to output_dir.
Decision Rules
| Decision | Rule |
|---|
| Gap threshold | Default 0.35 s. Raise to 0.5 s if the founder's delivery is intentionally slow or conversational; do NOT over-cut measured emphasis. |
| Hook-first reorder | Always reorder in conform mode unless the founder's opening line is already the strongest claim (confirm by reading the transcript before running the EDL generator). |
| B-roll inserts | Insert b-roll clips when b_roll_clips is non-empty AND a clip covers a factual claim that could be visualized. Place at phrase boundaries, never mid-sentence. |
| Karaoke vs. Klap captions | Use render-edl's built-in ASS karaoke by default. Switch to add-captions-klap only when the brand's existing ads demonstrably use Klap captions and matching that style is required. Klap runs last — never before render. |
| EDL conform vs. generative | Always use conform mode for founder talking-head. Generative mode is for new scene creation, not re-editing existing footage. |
| Payoff-hold | Even though payoff_hold.required: false for this archetype, identify and mark the strongest visual/claim moment as payoff-hold. The pacing curve needs an anchor. |
| Scaffolded atoms | If any composed atom is not yet implemented (no script on disk), stop and report exactly which atom is missing rather than silently substituting. |
Output
output_dir/finals/master.mp4 — finished 9:16 video with captions burned and audio intact.
output_dir/finals/manifest.json — render metadata: skill, run_id, edl_path, clips_rendered, pacing_curve, status, warnings, errors.
output_dir/working/edl.json — the validated Edit Decision List.
output_dir/working/tight-take.mp4 — intermediate jump-cut output.
output_dir/working/words.json — word-timestamps from transcription.
output_dir/verification.md — self-QC results and human review notes.
Quality Checks
master.mp4 exists, is non-zero, and ffprobe reports both video and audio streams.
- Duration of
master.mp4 is within ±0.5 s of target_duration_s.
manifest.json reports status: pass.
edl.json passes all nine validation rules (validator exits 0).
- The first clip in the EDL has
role: "hook" and contains the strongest claim.
pacing_curve.payoff_hold_ratio is between 2.0 and 4.0.
- Karaoke captions are present and cover every spoken word.
- No caption text appears over a b-roll insert that carries its own on-screen text.
verification.md exists and documents the watch-through result.
Failure Modes
- Source video missing or unreadable — stop immediately; report the path.
- Transcription fails — no word-timestamps means no jump-cut segmentation or EDL caption cues. Check
FAL_API_KEY / provider credentials; do not proceed without a valid words.json.
- No pauses detected by create-jump-cuts — not an error;
tight-take.mp4 equals source_video. Note in verification.md that no gaps were removed.
- EDL validator exits non-zero — fix all reported errors before running
render-edl. Common issues: non-contiguous timeline, missing payoff-hold clip, last clip target_out > target_duration + 0.5 s.
- B-roll clip path does not exist — skip the missing b-roll and log a warning in the manifest. Do not fail the whole render.
- No strongest claim identifiable — keep original order and log a warning in
planning-notes.md; do not silently reorder.
ffmpeg not installed — both create-jump-cuts and render-edl require ffmpeg. Install via brew install ffmpeg.
- render-edl missing generate-mode clips — not applicable in conform mode. If the EDL was accidentally set to generative mode, fix
meta.source_mode to "conform".
- Caption preset not found —
render-edl falls back to platform-default and warns. Explicitly set a valid preset from caption-style-presets.json to avoid the fallback.