| name | recut-video-to-creator-grammar |
| description | re-edit an existing video (a pipeline output, a flat talking-head take, or any external clip) so it follows CREATOR_GRAMMAR.md — reorder hook-first, jump-cut the breaths, snap cuts to beats, restyle captions, add silence beats and SFX. This is the conform-mode counterpart to the build-from-scratch archetype molecules: it produces a new EDL in conform source mode and renders it without generating any new footage. Use when you have an existing video and want creator-native pacing. |
recut-video-to-creator-grammar
Purpose
Take an existing video — a raw talking-head take, a finished pipeline output, a flat UGC clip, or any external short-form creative — and re-edit it to follow the full creator grammar defined in CREATOR_GRAMMAR.md:
- Hook-first reorder: the strongest claim is moved to position 0.
- Pacing curve: cuts front-load, hold on the payoff, then decelerate.
- Jump-cut breath removal: inter-word and inter-sentence gaps > 0.35s are deleted.
- Beat-synced cuts: when a beat grid is available, cut points snap to bar boundaries.
- Silence beats: one deliberate audio dropout before the payoff-hold.
- Caption restyle: captions are rebuilt to a named preset from the creator-grammar library.
- SFX: whoosh/tap events on feature-flash cuts.
The molecule works entirely in conform mode: the EDL's timeline clips reference time-ranges of the source video. No new footage is generated (Tier-1 reproducibility per CREATOR_GRAMMAR.md §10). When a proof shot is genuinely absent from the source, the molecule may insert exactly one generated b-roll clip (meta.source_mode: "hybrid") — but this is the exception, not the default.
This is the sibling skill to create-shortform-cuts-from-video. Where that skill produces multiple standalone cuts by choosing different arc combinations, this skill produces one tight re-edit of the same source material that conforms to creator grammar end-to-end.
Inputs
| Input | Required | Notes |
|---|
source_video | yes | Path to the source video file (mp4, mov, webm, m4v). The video to be re-edited. |
target_archetype | no | One of the 8 archetype IDs from generate-edit-decision-list/references/archetypes.json. If omitted, the molecule picks the best-fit archetype from the grammar profile. |
target_duration | no | Target runtime in seconds for the re-edited master. If omitted, defaults to the source duration trimmed by breath removal. |
reference_video | no | Path to a reference video whose grammar you want to copy (e.g. a winning competitor ad). If supplied, the molecule analyzes it alongside the source and uses its archetype + pacing as the target. |
caption_preset | no | Override the archetype default caption preset. Must be a known preset ID in style-captions/references/caption-style-presets.json. |
beat_grid | no | Path to a beat-grid.json (from extract-beat-grid). Required only for archetypes with beat_sync: true. If omitted and the archetype wants beat sync, the molecule proceeds without it (with a warning). |
output_dir | yes | Directory to write all outputs. Created if absent. |
Composed Atoms
atoms/planning/analyze-reference-grammar — measure the source video's current grammar profile (cuts, pacing curve, audio mode, archetype match). When a reference video is supplied, analyze it too to extract the target grammar.
atoms/source/transcribe-audio-fal — produce word-level timestamps (words.json) from the source audio; used by the EDL generator for jump-cut planning and caption cue placement.
atoms/planning/generate-edit-decision-list — in conform mode (source_mode: "conform"), produces the re-edit EDL: clip time-ranges from the source, hook reorder, breath gaps removed, payoff-hold marked, beat-snapped cuts, caption cues, silence beats, and SFX annotations.
atoms/editing/create-jump-cuts — breath/pause removal on the source when a fast preview of the jump-cut result is needed before the full EDL render, or as a fallback when the EDL path is not available.
atoms/assembly/render-edl — execute the conformed EDL into the new master.mp4.
atoms/captions/style-captions — restyle captions to the target preset after rendering; used when the rendered EDL's ASS output needs a post-render style pass.
atoms/review/compare-with-reference-video — side-by-side comparison of the source and the recut master so grammar improvements are visible.
atoms/review/review-video-pacing-rhythm — verify the recut master's pacing curve matches the target archetype's parameters.
atoms/review/watch — frame-extraction + transcript QC pass on the final master before delivery (mandatory per VIDEO_GEN_RULES.md rule 3).
Workflow
Step 1 — Ingest and grammar-profile the source
Run analyze-reference-grammar on the source video:
python3 skills/atoms/planning/analyze-reference-grammar/scripts/analyze_grammar.py \
--source <source_video> --output-dir <output_dir>/analysis/source/
Read back grammar-profile.json. Note: audio_mode, archetype_match.id, archetype_match.confidence, cut_count, mean_shot_len, payoff_hold, and cuts_per_10s.
If a reference_video was supplied, run analyze-reference-grammar on it too:
python3 skills/atoms/planning/analyze-reference-grammar/scripts/analyze_grammar.py \
--source <reference_video> --output-dir <output_dir>/analysis/reference/
Write both profiles to <output_dir>/analysis/.
Burned-in caption detection (critical — see Decision Rules). Inspect the source grammar profile's visual characteristics. The analyze-reference-grammar atom flags burned-in subtitles in its manifest under warnings[]. Also run a spot-check: extract 3 frames at cuts[2], the midpoint, and cuts[-2] and inspect for static text in the caption-safe band. Log whether burned-in captions are detected.
Step 2 — Pick the target archetype
Select target_archetype using this priority order:
- Explicit user input (
target_archetype parameter).
- Reference video's
archetype_match.id (if reference supplied and confidence ≥ 0.6).
- Source video's
archetype_match.id (the grammar profile's best-fit archetype).
- Fallback:
creator-talking-head (the most permissive conform archetype — speech-only, karaoke-pop captions, jump-cut defaults).
Log the selected archetype and the reason it was chosen.
Skip-recut check. Load archetypes.json and compare the source profile against the target archetype's parameters. If the source's cuts_per_10s mean is within ±15% of the archetype's cuts_per_10s.body target, the payoff hold is already present (payoff_hold.detected: true with ratio ≥ 2.0), and the audio mode matches — report to the user that the source already approximates the target grammar and recommend skipping the recut. Do not proceed unless the user confirms.
Step 3 — Transcribe for word timestamps
Run transcribe-audio-fal on the source to produce word-level timestamps. This is required for:
- Jump-cut planning (gap detection for breath removal).
- Karaoke-pop caption cue placement.
- Identifying the strongest claim for hook reorder.
python3 skills/atoms/source/transcribe-audio-fal/scripts/transcribe.py \
--source <source_video> --output-dir <output_dir>/transcription/
Output: <output_dir>/transcription/words.json — [{text, start, end}, ...].
If the source is music-only (no speech detected in Step 1), skip transcription and note that caption cues will use static-title-card family only.
Step 4 — Generate the conform EDL
Run generate-edit-decision-list in conform mode:
python3 skills/atoms/planning/generate-edit-decision-list/scripts/edl_pacing.py \
--archetype <target_archetype> --target-duration <target_duration>
Then invoke the EDL generator with:
source_mode: "conform"
source_files: [<source_video>]
words_json: <output_dir>/transcription/words.json
archetype: <target_archetype>
target_duration: <target_duration>
beat_grid: <beat_grid> (if provided)
output_path: <output_dir>/edl.json
The generator will:
- Identify the strongest claim in the transcript (most direct, benefit-forward sentence) and place it as clip
c01 at target_in: 0.0.
- Remove all inter-word / inter-sentence gaps > 0.35s by splitting into contiguous speech runs, each tagged
transition_in: "jump-cut".
- Mark one clip
role: "payoff-hold" in the 60–85% window.
- Place one silence beat before the payoff-hold.
- If
beat_grid is provided and the archetype has beat_sync: true, snap cut points to bar boundaries within ±150ms.
- Place karaoke-pop caption cues (or static-title-card cues for music-only archetypes) from the word timestamps.
- Add whoosh/tap SFX on feature-flash cuts.
Validate the EDL:
python3 skills/atoms/planning/generate-edit-decision-list/scripts/edl_validate.py \
<output_dir>/edl.json
Do not proceed if validation fails. Fix each reported error and re-validate.
Step 5 — Render the recut master
Run render-edl on the validated conform EDL:
python3 skills/atoms/assembly/render-edl/scripts/render_edl.py \
--edl <output_dir>/edl.json \
--output <output_dir>/master-recut.mp4 \
--project-dir <project_dir>
render-edl trims each source.file range, applies speed and motion, concatenates with hard cuts, mixes the audio bed (adding silence beats and SFX), and burns ASS captions using the chosen preset.
Step 6 — Review the recut
Run all three review steps:
compare-with-reference-video — source vs. recut, to verify grammar improvements are visible. If a reference video was supplied, compare the recut against it instead.
review-video-pacing-rhythm — check that cuts_per_10s, payoff_hold_ratio, and segment boundaries match the target archetype's parameters.
atoms/review/watch — mandatory self-QC: frame extraction + transcript + punch list. This is the non-negotiable final gate per VIDEO_GEN_RULES.md rule 3.
Write a qc-report.md to <output_dir>/ with: per-cut grammar improvements, pacing curve comparison (source vs. recut), any issues found by /watch, and a PASS / NEEDS_REVISION verdict.
If the QC report is NEEDS_REVISION, fix the EDL (adjust clip boundaries, reorder clips, change the payoff-hold selection) and re-render. Log the iteration in qc-report.md.
Step 7 — Deliver
Write final outputs under the project's canonical 5-folder layout (see PROJECT_STRUCTURE.md). Copy master-recut.mp4 to finals/. Update storyboard.html with a "Recut — creator grammar" section showing the recut player and a before/after pacing curve comparison.
Decision Rules
Burned-in caption caveat (critical)
If the source video has burned-in captions and the re-edit is non-contiguous (clips from the source are reordered), the stale caption text remains permanently attached to the pixel-level image for those frames. This creates:
- Wrong captions displayed during a different sentence (reorder desync).
- Duplicate text when fresh ASS captions are burned on top.
Before proceeding with a non-contiguous reorder, confirm whether the source has burned-in captions.
- If burned-in captions are detected and the reorder is non-contiguous:
- (a) Crop / letterbox — add a black bar over the caption-safe band (bottom ~15% of frame). This hides the old captions; re-burn fresh ASS captions inside the safe area above the bar. Acceptable for talking-head formats where the subject is mid-frame.
- (b) Contiguous-only mode — disable reordering; only apply breath removal (jump cuts) and pacing adjustments that keep clips in source order. Fresh captions can then be re-burned cleanly.
- (c) Source a pre-caption master — if the project folder exists and a pre-Klap master is available, use that as the source instead.
- Never silently remix over burned-in captions without disclosing the issue to the user.
- If burned-in captions are not detected, proceed normally.
Conform is the default; hybrid is the exception
Do not insert generated clips unless a proof shot is genuinely absent from the source and the archetype specifically requires one (e.g. the vo-product-demo archetype expects a product-in-use hero shot but the source is a pure talking head). If inserting a generated clip, set meta.source_mode: "hybrid" in the EDL and flag it in qc-report.md. This is limited to one generated clip per run.
Audio-mode compatibility
Before running the EDL generator, check that the source's audio_mode is compatible with the target archetype:
| Target archetype | Required source audio | Action if missing |
|---|
creator-talking-head, multicam-podcast-clip | speech-only | If source is music-only, the archetype cannot apply; fall back to silent-product-demo or ask user. |
vo-product-demo, reaction-montage-explainer, brand-process-film, broll-narrative-essay | vo+music | If source is speech-only, add a music bed in audio.music before EDL generation; flag in qc-report.md. |
silent-product-demo, concept-loop | music-only | If source has speech, the recut will suppress VO in favor of captions-as-script. Confirm with user before proceeding. |
If the source audio mode is incompatible and no fallback is obvious, stop and report to the user with the specific incompatibility.
Tier-3 honesty — work with what exists
Per CREATOR_GRAMMAR.md §10 Tier-3: the recut cannot add footage that doesn't exist. If the target archetype needs a payoff-hold hero shot and no sufficiently strong visual moment exists in the source, select the best available clip for the payoff role and note the limitation in qc-report.md. Do not attempt to AI-generate a replacement hero shot unless the user explicitly requests hybrid mode.
Skip-recut recommendation
If the source already closely matches the target grammar (pacing within ±15%, payoff hold present, audio mode correct), report this finding before running and recommend the user skip the recut or apply only caption restyling (atoms/captions/style-captions). Burning an edit pass on a video that already conforms wastes time and may introduce new problems.
Target duration
If target_duration is not supplied, default to: source duration minus estimated breath-removal savings. Estimate breath savings as (number of gaps > 0.35s) × (mean gap duration) from the word timestamps. This prevents unintentional duration changes.
Output
<output_dir>/
├── analysis/
│ ├── source/
│ │ ├── grammar-profile.json # source grammar measurement
│ │ └── words.json # word-level transcript
│ └── reference/ # present only if reference_video was supplied
│ └── grammar-profile.json
├── transcription/
│ └── words.json # word timestamps for EDL planning
├── edl.json # validated conform EDL
├── planning-notes.md # EDL generator editorial decisions
├── master-recut.mp4 # the recut master (also copied to finals/)
├── manifest.json # run metadata
└── qc-report.md # PASS / NEEDS_REVISION verdict
Plus, in the project's canonical 5-folder layout:
finals/
└── <slug>-recut.mp4 # shippable delivery
storyboard.html updated with a "Recut — creator grammar" section showing the recut player and before/after pacing curve.
manifest.json required keys
{
"skill": "recut-video-to-creator-grammar",
"run_started_at": "<ISO>",
"run_completed_at": "<ISO>",
"status": "passed | blocked | failed",
"source_video": "<path>",
"target_archetype": "<id>",
"source_archetype": "<id>",
"burned_in_captions_detected": false,
"conform_mode": "contiguous | non-contiguous | hybrid",
"phases": {
"P1_grammar_profile": { "status": "...", "artifact": "analysis/source/grammar-profile.json" },
"P2_skip_check": {
Quality Checks
master-recut.mp4 exists, is non-zero, and ffprobe reports both video and audio streams.
ffprobe duration is within ±0.5s of meta.target_duration in the EDL.
edl_validate.py exits 0 on edl.json.
- Exactly one clip in the EDL has
role: "payoff-hold" and its duration is 2–4× mean_shot_len.
- All EDL clips are contiguous (
target_out[N] == target_in[N+1] within ±1 frame).
- Every
source.file path in the EDL resolves on disk.
qc-report.md ends with a PASS verdict (not NEEDS_REVISION) before the master is delivered to finals/.
/watch QC pass finds no subtitle collisions (burned-in + fresh layers) on any frame.
- If
burned_in_captions_detected: true and conform_mode: "non-contiguous" — a crop or cover strategy was applied and documented. Never deliver without this check.
manifest.json status is pass.
storyboard.html contains the recut video player.
Failure Modes
-
Burned-in captions + non-contiguous reorder. The most common and most damaging failure: stale captions from the original order appear on reordered clips, and fresh captions double-stack on top. Detection: analyze-reference-grammar warns in its manifest, and a visual frame check confirms it. Resolution: see Decision Rules — crop the caption band, switch to contiguous mode, or use a pre-caption source.
-
Source too short to re-cut to the target duration. If the source contains less total speech than the target duration, breath removal cannot lengthen the video. Reduce target_duration to the available speech duration, or accept a shorter output. The EDL validator will catch a target_out overshoot before render.
-
Target archetype requires an audio mode the source lacks. E.g. the user targets vo-product-demo (needs VO over music) but the source is pure speech with no music bed. Either add a music bed explicitly or downgrade the archetype to creator-talking-head. Document the mismatch in qc-report.md.
-
No strongest claim identifiable for hook reorder. When the transcript is short, low-contrast (every sentence equally strong), or the source is music-only, the EDL generator cannot confidently move a hook clip. It will keep the original order and log a warning in planning-notes.md. Review the planning-notes.md and manually specify the hook clip's source in/out if needed.
-
EDL validation failure. Non-contiguous timeline (gap between clips > 1 frame), missing payoff-hold, or target_duration mismatch. Fix: reorder clips by target_in, adjust the last clip's target_out to match meta.target_duration, confirm exactly one payoff-hold clip.
-
Payoff-hold candidate is too short. If no clip in the 60–85% window reaches 2× the mean shot length, the validator warns. Use the longest clip in the window and document the shortfall in planning-notes.md. A payoff that is 1.5× mean is acceptable with a note; below 1.5× means the source genuinely lacks a hero moment.
-
ffmpeg / ffprobe not installed. Install via brew install ffmpeg. The render-edl and analyze-reference-grammar atoms both require ffmpeg on PATH.