--- name: clean-cut description: Step 1 of the AI Video Editor pipeline — turn raw talking-head footage into a clean master cut. Use when the user wants to "clean cut", "cut the raw footage", "remove filler / dead air / bad takes", "tighten the pacing", produce cuts.json, run the cut editor, or render a cleaned preview/master for a video-N project in this repo. Covers audio extraction, AssemblyAI transcription, authoring cuts.json (keeps/cuts/fluff categorized), the cut policy (content-aggressive, pause-natural ~0.5s), QA + review docs, the local cut-editor UI, tight/natural previews, the final 4K60 render, and producing edited-transcript.json as the handoff to /make-tsx. Not for building TSX overlays (that is /make-tsx) or the raw TSX authoring rules (that is vidtsx-2d-generator). --- # clean-cut — the step-1 cut pipeline Turn a project's raw clips (`videos/video-N/DJI_*.MP4`) into a **clean master** + **`edited-transcript.json`** (the word-level timing spine every later step anchors to). The single source of truth is **`videos/video-N/work/analysis/cuts.json`** — shared by Claude and the editor UI. Every tool lives in `tools/` and takes the project dir as its first arg. **You (Claude) author the cuts by reading the transcript.** No separate LLM call. The tools handle audio, encoding, QA, and the editor; the judgment — what is a retake, a false start, filler, or fluff — is yours. ## Pipeline (run in order) Let `P` = the project (e.g. `video-1`). Clip **id** = a short handle (`0233`); every artifact for a clip is named by that id (`0233.wav`, `0233.json`). The raw MP4 path is stored per-clip in cuts.json as `file`. 1. **Extract 16 kHz mono WAV per clip** → `P/work/audio/.wav` (used for transcription + the RMS noise-floor / snap-to-audio tails). Not scripted — run ffmpeg per clip: `ffmpeg -i videos/video-1/DJI_...0233_D.MP4 -vn -ac 1 -ar 16000 videos/video-1/work/audio/0233.wav` 2. **Draft this video's keyterms → `P/work/keyterms.txt`** (do this before transcribing). Keyterms bias the recognizer toward this video's proper nouns / product / tech names so they aren't mangled (e.g. "Seedream" not "sea dream", "Cloudflare" not "cloud flare"). Accuracy here is load-bearing: the transcript text drives cut decisions AND `/make-tsx` greps it for phrases to time beats — a garbled term breaks both. From the video's topic/title, list the ~10–40 likely brand names, tools, tech, and jargon, one per line (blank lines and `#` comments ignored). **This is per-video — never hardcode terms in `transcribe.py`.** If you skip the file, transcription still runs (empty fallback), just with more errors on specialty words. The shape is one term per line: ``` # tools + brands named in this video Claude Code Remotion AssemblyAI ElevenLabs Cloudflare ``` 3. **Transcribe** (needs `ASSEMBLYAI_API_KEY` in `.env`; verbatim, keeps fillers; auto-loads `work/keyterms.txt`): `python tools/transcribe.py P` → `P/work/transcripts/.json`. `--clips 0233` for one, `--force` to redo. It prints how many keyterms it loaded — a "none" line means you haven't drafted them. 4. **Readable take view** for analysis: `python tools/format_transcript.py P` → `P/work/analysis/takes-.txt` (segments on >0.8s gaps, fillers tagged inline with timestamps). 5. **Author `cuts.json`** (see schema below) by reading `takes-*.txt`: mark every span as a keep or a categorized cut, add fluff suggestions and judgment-call flags. 6. **QA + review docs**: `python tools/analyze_cut.py P [--style tight]` → `qa-report.md` (internal dead-air, clipped-tail risks, tiny fragments, fluff, hard entries at cut joins, **ghost speech** = untranscribed energy riding inside a keep, low-confidence kept tokens). Ghost/hard-entry checks exist because a transcript diff CANNOT see a mistimed token (clipped word onset) or an untranscribed false start ("and it—") that survives the cut — only energy-vs-token cross-checks catch them (a careful listen caught both before these checks existed). `python tools/make_review.py P` → `review.md` (per-clip keep/cut table + estimated length per style). 7. **Editor proxy** (once): `python tools/make_proxy.py P` → `P/work/editor/{proxy.mp4, waveform.png, manifest.json}` (720p concat of raw clips + per-clip offsets). 8. **Previews** (render BOTH, user picks): `python tools/render_cuts.py P --style tight --mode preview` and `--style natural` → `P/output/preview-