| name | create-broll-narrative-essay |
| description | produce a 25-45s lyrical b-roll narrative essay — a VO-driven travel/lifestyle/brand essay over evocative b-roll, structured in two acts joined by a 0.25-0.6s structural-silence pivot. Use when you need a creator-native essay format that builds lyrical resonance through a single recurring visual anchor, opens on intimacy or abstraction (not the destination), and resolves in an informational second act. Maps to the `broll-narrative-essay` archetype in CREATOR_GRAMMAR.md §8. |
create-broll-narrative-essay
Purpose
Produce a 25–45s lyrical b-roll narrative essay — a VO-driven format where evocative b-roll footage carries a two-act script, a single recurring visual anchor provides continuity across many cuts, and a deliberate 0.25–0.6s structural-silence beat divides the acts. The format lives in the broll-narrative-essay archetype (CREATOR_GRAMMAR.md §8): vo+music, static-title-card caption family, two-act structure with structural silence as the act pivot.
Act 1 — lyrical. Intimate, abstract, sensory. Opens on a detail or a feeling, not the destination. Cuts follow VO phrase rhythm. Every visual returns to the recurring anchor at least once.
Act 2 — informational / resolution. Grounds the lyrical opening with a specific claim, context, or invitation. Resolves the tension the first act opened.
Structural-silence pivot. A 0.25–0.6s audio dropout placed at the act boundary — the EDL encodes it as audio_beats[].type = "silence-beat". The silence is the hinge.
Use for: lifestyle brand essays, destination/travel micro-docs, brand origin stories, product-as-lifestyle ads, mini-documentary shortform.
Do not use for: fast-cut product demos (use create-silent-product-demo or create-product-demo-video), talking-head UGC (use ugc-ad/), beat-synced concept loops (use concept-loop archetype).
Inputs
| Input | Required | Notes |
|---|
brief | yes | Brand, product/subject, target audience, platform, mood/tone direction |
script | no | Pre-written two-act VO script (if provided, the molecule skips Phase 1 writing). Must declare act boundaries. |
voice_id | yes | ElevenLabs voice ID from VOICES.md approved list |
visual_anchor | yes | The one recurring subject or compositional motif that threads all cuts (e.g. "the traveler's hands", "a specific ceramic mug", "morning light on a surface"). Prose description. |
broll_sources | no | Paths to existing b-roll clips. If omitted, the molecule sources from Pexels and/or generates via video-generation atoms. |
music_path | no | Path to a pre-selected music track. If omitted, find-music is invoked. |
split_screen_scenes | no | Scene IDs that should render as side-by-side composites (e.g. ["s05", "s09"]). See Decision Rules §3. |
target_duration_s | yes | 25–45 (default: 35) |
aspect | no | "9:16" (default), "1:1", "16:9" |
output_dir | yes | Canonical 5-folder project directory |
Composed Atoms
atoms/voiceover/create-voiceover-elevenlabs — Phase 2: render the approved two-act VO
atoms/source/transcribe-audio-fal — Phase 3: extract word-level timestamps from rendered VO
atoms/music/find-music — Phase 2: select music bed if no track provided
atoms/planning/generate-edit-decision-list — Phase 4: produce edl.json for the broll-narrative-essay archetype — places the act-break silence beat + one payoff-hold
atoms/audio-editing/insert-silence-beat — executed via the EDL's audio_beats[] by render-edl — mutes audio at the act-pivot timestamp
atoms/clip-discovery/find-clips-pexels — Phase 5: source b-roll clips per scene description when no source footage provided
atoms/video-generation/create-video-veo3 — Phase 5: generate scene clips when real footage is unavailable and Tier 2/3 quality is needed
atoms/editing/trim-video-clips — Phase 5: conform existing b-roll to EDL scene durations
atoms/editing/composite-split-screen — Phase 5: render split-screen comparison moments (e.g. map vs. landscape, before/after)
atoms/captions/style-captions — Phase 6: apply static-title-card / platform-default preset to the EDL caption cues
atoms/assembly/render-edl — Phase 6: execute edl.json → master.mp4 with audio mix, silence beats, and burned captions
atoms/review/watch — Phase 7: self-QC — sample frames + transcribe + report
Workflow
State machine: 7 phases. Produces a resumable artifact at each phase boundary.
P1 WRITE SCRIPT P2 VO + MUSIC P3 TRANSCRIBE
brief → two-act → vo.mp3, → words.json
script.md music.mp3 [GATE 1]
↓
P7 SELF-QC ← P6 RENDER EDL ← P5 ACQUIRE B-ROLL
qc-report.md master.mp4 clips/
[GATE 2] ↑
P4 GENERATE EDL
edl.json (visual-anchor
rule + silence beat placed)
Phase 1 — Write the two-act script
If script is provided and declares act boundaries, skip to Phase 2.
Otherwise, write a two-act VO from the brief:
- Act 1 (lyrical, ~40–55% of total duration): Opens on a sensory detail or intimate abstraction. Establishes a feeling, not a fact. Introduces the visual anchor implicitly. Sentences are short and paratactic — fragments are acceptable.
- Act 2 (informational / resolution, ~45–60% of total duration): Shifts register. Grounds the lyric in a claim, context, or invitation. Resolves the emotional tension. May name the brand or product here (not in Act 1).
Mark the act boundary explicitly in the script (--- ACT BREAK --- or equivalent). The silence beat in the EDL will be placed at this boundary.
VO word budget: ~3 words/second of target duration at 1.0× delivery speed. For 35s target, aim for ~105 words total across both acts.
Write to working/script.md. Output the full script and wait for user confirmation before proceeding.
Phase 2 — Render VO and music
VO: Invoke atoms/voiceover/create-voiceover-elevenlabs with the approved voice_id and the locked script. The delivery style for Act 1 should be warmer/slower; for Act 2 slightly more grounded. If the chosen voice allows voice_settings, reduce stability to ~0.35–0.45 for Act 1 lyricism, return to 0.5+ for Act 2. Write rendered VO to working/voice/vo.mp3.
Music: If music_path is provided, copy it to working/music/music.mp3. Otherwise invoke atoms/music/find-music with a brief derived from the script's mood — aim for an instrumental bed that has a natural energy shift near the 40–55% mark (matching the act-break position). Write to working/music/music.mp3.
Phase 3 — Transcribe and extract word timestamps (GATE 1)
Invoke atoms/source/transcribe-audio-fal on working/voice/vo.mp3. Save word-level timestamps to working/whisper/words-flat.json as [{text, start, end}, ...].
Identify the act-break timestamp: locate the VO phrase boundary nearest to the --- ACT BREAK --- marker in the script. Record act_break_s — this is where the EDL's structural-silence beat will be placed.
Present script.md, act_break_s, and vo.mp3 duration to the user. [GATE 1]: Confirm script, voice, and act-break position before proceeding.
Phase 4 — Generate the Edit Decision List
Invoke atoms/planning/generate-edit-decision-list with:
archetype: "broll-narrative-essay"
words_json: working/whisper/words-flat.json
target_duration: <target_duration_s>
source_mode: "generative" (or "conform" if all b-roll is already sourced)
output_path: working/edl.json
Visual-anchor rule (mandatory): in the EDL scene table passed to generate-edit-decision-list, every third clip in Act 1 must carry a notes field of "anchor-return" — it features the same recurring visual anchor. The anchor shot should also appear once in Act 2.
Silence beat placement: confirm the EDL's audio_beats[] contains one entry with type: "silence-beat" placed at act_break_s - 0.10s and dur between 0.25–0.6s. If generate-edit-decision-list does not place it automatically, add it manually to edl.json before proceeding.
Split-screen placement: if split_screen_scenes is non-empty, annotate the specified clips in the EDL with notes: "split-screen". These will be rendered as composites in Phase 5 before final EDL render.
Validate edl.json with scripts/edl_validate.py. Do not proceed with an invalid EDL.
Phase 5 — Acquire and conform b-roll
For each clip in edl.json's timeline[]:
-
Anchor clips (marked "anchor-return" in notes): these are the highest-priority clips; source them first. If the visual anchor is a product, brand asset, or specific environment, use brand-provided footage or generate via atoms/video-generation/create-video-veo3 for photorealism. Trim to EDL duration via atoms/editing/trim-video-clips.
-
General b-roll — tiered sourcing (CREATOR_GRAMMAR §10):
- Tier 1 (free): HTML hyperframe or static styled graphic — use only if the clip is a text-overlay moment, never for evocative b-roll.
- Tier 2 (Pexels or existing source footage): invoke
atoms/clip-discovery/find-clips-pexels with the clip's source.spec.description. Download top 3 candidates, pick the best match to the visual anchor's world. Trim with atoms/editing/trim-video-clips.
- Tier 3 (AI video generation): use
atoms/video-generation/create-video-veo3 only when Pexels candidates are clearly off-world or the clip requires controlled physics/motion.
-
Split-screen clips: for each clip annotated "split-screen" in the EDL, invoke atoms/editing/composite-split-screen with:
clip-a: the primary scene clip (top or left).
clip-b: the comparison clip (map, before-state, alternate context).
layout: "top-bottom" for portrait; "left-right" for landscape or 1:1.
ratio: 0.55 (primary clip gets slightly more frame).
- Save composite to
working/clips/<scene_id>-splitscreen.mp4.
- Update the EDL clip's
source.mode to "file" and source.file to the composite path before rendering.
Write all acquired/generated clips to working/clips/<scene_id>.mp4.
Phase 6 — Render the EDL (GATE 2)
Invoke atoms/assembly/render-edl with:
--edl working/edl.json
--output finals/master.mp4
--project-dir <output_dir>
render-edl will:
- Assemble clips in timeline order as hard cuts.
- Apply the silence beat(s) from
audio_beats[] via the built-in volume filter.
- Mix music bed + VO with
sidechain-20:1 ducking (per audio.ducking in the EDL).
- Burn
static-title-card captions from the EDL's timeline[].captions[].
After render completes, confirm finals/master.mp4 exists, duration matches meta.target_duration ±0.5s, and manifest.json shows status: "pass".
[GATE 2]: Present finals/master.mp4 to the user for approval before self-QC.
Phase 7 — Self-QC
Invoke atoms/review/watch on finals/master.mp4 with the following QC prompt:
"Review this b-roll narrative essay for: (a) visual-anchor continuity — does the recurring anchor appear every ~3 clips in Act 1 and once in Act 2? (b) act-break silence — is there a clear audio dropout at the act pivot? (c) lyrical vs. informational register shift between acts — does Act 2 feel grounded after Act 1's abstraction? (d) caption placement — static title cards appear on appropriate clips, not colliding with action? (e) audio mix — VO clear, music supportive, silence beat punchy? (f) overall pacing — are cuts following VO phrase boundaries, not arbitrary?"
Write findings to working/qc-report.md. Surface any punch list items to the user with proposed fixes. Loop back to the relevant phase if critical issues are found.
Decision Rules
1. Placing the act-break silence beat
The silence beat must land at a VO phrase boundary — never mid-word or mid-breath. The optimal position:
- Immediately after the last word of Act 1 and before the first word of Act 2.
at = <last_word_of_act1.end> + 0.0s (no gap needed before the zero; the silence is the gap).
dur = 0.25–0.6s. Use 0.4s as the default; go up to 0.6s when the act-break is a dramatic register shift, down to 0.25s when the pacing is urgent.
If the music track has a natural energy dip near the act-break position, align the silence beat to that dip — this makes the dropout feel intentional rather than technical.
2. Choosing and maintaining the visual anchor
The visual anchor must be:
- Specific and physical — a hand, a cup, a texture, a recurring sky — not an abstract concept.
- Consistent across clips — same framing family (e.g. always ECU hands, always the same ceramic mug from different angles).
- Established in the first two clips — the audience must recognize it by the third clip so subsequent returns feel like callbacks, not coincidences.
- At home in Act 2 — the anchor must appear at least once in Act 2 to close the circle.
If the user has not specified a visual anchor, propose three options derived from the script's imagery before writing the EDL. Get explicit sign-off on one.
3. When to use split-screen
Use composite-split-screen only when the script's text explicitly contrasts two worlds, timelines, or contexts (e.g. "then vs. now", "the map vs. the place", "before dawn vs. full light"). Do not use it for visual variety alone — the split-screen is a semantic device, not a pacing device. Maximum one or two split-screen moments per video.
4. Generative vs. conform b-roll
Follow CREATOR_GRAMMAR §10 Tier ladder. Prefer Tier 2 (Pexels / real footage) for anchor clips — photorealistic continuity matters most there. Generated (Tier 3) clips are acceptable for atmospheric non-anchor b-roll. Never use generative AI for the anchor clips unless the anchor is explicitly an AI-native subject (e.g. a CGI product).
5. Music energy and the act break
Act 1's music bed should be lighter or more textural; Act 2 can allow slightly more energy or a subtle dynamic lift — matching the register shift in the VO. If the sourced track does not have this shape, use atoms/audio-editing/insert-silence-beat at the act-break to manufacture a hard reset, then let the music continue into Act 2 at a slightly higher level if mixing allows.
Output
Under the project's canonical 5-folder layout:
<output_dir>/
├── HOW_TO_MAKE_THIS_VIDEO.md
├── working/
│ ├── script.md # Phase 1: two-act VO script with act boundary
│ ├── voice/
│ │ └── vo.mp3 # Phase 2: rendered VO
│ ├── music/
│ │ └── music.mp3 # Phase 2: music bed
│ ├── whisper/
│ │ └── words-flat.json # Phase 3: word-level timestamps
│ ├── edl.json # Phase 4: validated Edit Decision List
│ ├── clips/
│ │ ├── <scene_id>.mp4 # Phase 5: individual b-roll clips
│ │ └── <scene_id>-splitscreen.mp4 # Phase 5: split-screen composites
│ └── qc-report.md # Phase 7: self-QC findings
├── finals/
│ └── master.mp4 # Phase 6 deliverable
└── manifest.json # run metadata, phase statuses, gate approvals
manifest.json must include: skill, run_id, created_at, phase_statuses (P1–P7), gate_approvals (G1 brief, G2 master), act_break_s, visual_anchor_description, outputs.master, warnings, errors.
Quality Checks
finals/master.mp4 exists; ffprobe reports both video and audio streams.
- Duration is within ±0.5s of
meta.target_duration.
- Resolution is 1080×1920 (9:16) or the appropriate canvas for
meta.aspect.
edl.json validates cleanly (all nine rules in edl-schema.md §"Validation rules" pass).
- Exactly one
silence-beat in audio_beats[] at approximately act_break_s.
- The silence beat is audible as a clear audio dropout of 0.25–0.6s in the rendered master.
- At least one
"anchor-return" clip appears in Act 1 and one in Act 2.
- No karaoke-pop captions (static-title-card family only, per archetype).
grammar.caption_preset is a recognized preset in caption-style-presets.json.
- Self-QC report (
qc-report.md) exists with a PASS / NEEDS_REVISION verdict.
- Voice ID is from the approved list in
VOICES.md.
Failure Modes
- No act boundary declared in script — the silence beat cannot be placed without a clear act pivot. If the user's script has no declared boundary, ask them to mark one before Phase 4. Do not guess.
- Visual anchor undefined — do not proceed to EDL generation without a confirmed anchor. An unanchored essay will feel like an unrelated clip reel.
- Pexels clips don't match the anchor's world — Pexels sourcing uses keywords, which can return clips visually inconsistent with the anchor. If first-pass candidates are off-world, requery with more specific terms (location, color palette, props); if still failing, escalate to Tier 3 generation for that clip.
- Silence beat placed mid-word —
insert-silence-beat will execute the beat regardless of VO content. Always align at to a phrase boundary from the word-timestamps before finalizing the EDL.
- EDL validation failure — do not deliver an invalid EDL. Fix each reported violation and re-validate before running
render-edl.
- Split-screen duration mismatch —
composite-split-screen output duration = min(dur_clip_a, dur_clip_b). If one clip is shorter than the EDL target, trim or re-source before compositing.
- Music has no natural act-break dip — if the track runs flat through the act pivot, the silence beat still creates the dropout. The music restart may sound abrupt. Consider cross-fading to a quieter section or using a subtle low-pass on Act 1 music to differentiate registers.
- render-edl fails on missing clips — the renderer fails immediately with a list of missing
clips/<id>.mp4 files. Source every clip before invoking render-edl.
- VO duration outside 25–45s target — if the rendered VO exceeds 45s, cut the script; if under 25s, the video will feel sparse. Adjust word count in Phase 1 using the 3-words/second budget.