# Video Studio — house rules

> **Harness:** session protocol, feature state, and iron rules live in [`AGENTS.md`](AGENTS.md).
> Start every session with `./init.sh`; the feature source of truth is `feature_list.json`.

A personal AI video-editing studio. Claude Code is the conductor; two vendored
open-source tools do the heavy lifting:

- **`tools/video-use`** — transcript-driven cutter. ElevenLabs Scribe → word-level
  transcript → EDL (keep/cut ranges) → ffmpeg cut on word boundaries. This is 80%
  of the value. Its full production rules live in `tools/video-use/SKILL.md`.
- **`tools/hyperframes`** — HTML/CSS/GSAP → MP4 motion graphics (title cards,
  lower-thirds, on-screen figures, overlays). Optional polish layer.

The orchestrator skill that ties them together: `.claude/skills/video-studio/SKILL.md`.

## The one rule everything else comes from

**Edit the transcript, and let the video follow.** Decisions happen on the
transcript in plain English, confirmed before any render. Never surprise the user
with a render.

## House defaults (output)

- **Aspect: 9:16 vertical** unless told otherwise.
- **Preserve source resolution. Never downscale.** If the source is 4K, the
  deliverable is 4K. 1080×1920 is the floor and is used ONLY for fast previews
  (`--preview`).
- **Frame rate: match the source.**
- **Subtitles: burned in LAST** in the filter chain, after every overlay
  (otherwise overlays hide captions). Short chunks, bold, hyperlegible, sized to
  clear the TikTok/Reels UI (`MarginV` high enough to sit above the buttons).
- **Color grade** only when asked; render a comparison contact-sheet of options
  with the settings baked into each, and let the user pick — don't eyeball a slider.

## Workflow (per video)

1. **Transcribe** with video-use (cached per source — never re-transcribe an
   unchanged file).
2. **Propose a cut** as marked transcript ranges + a one-line reason each
   (filler, dead air, retakes). **WAIT for approval.** Never cut before OK.
3. **Cut** to `edit/base.mp4`, snapping every edge to a word boundary; run silence
   detection so a trailing breath is cut instead of the last word.
4. **Suggest 2–3 graphic moments** and build them in hyperframes if approved.
5. **Render vertical at source resolution.** Captions last.
6. **Self-eval** the rendered output at every cut boundary before showing it.

## Project layout

Every project is one dated folder:

```
projects/<YYYY-MM-DD-slug>/
├── raw/            ← source footage (drop here, untouched)
├── edit/           ← transcripts, takes_packed.md, edl.json, base.mp4, master.srt
├── compositions/   ← hyperframes HTML sources per graphic slot
└── renders/        ← preview.mp4, final.mp4
```

Never write session output inside `tools/`. Keep the vendored tools clean and
upstream-syncable.

## Secrets

`ELEVENLABS_API_KEY` lives in `.env` at this studio root (gitignored). Never write
it into a project folder or into `tools/`.

## Prereqs

`git`, `node 22+`, `python3`, `uv` (Python deps), `bun` (hyperframes),
`yt-dlp` (optional), and an ElevenLabs API key.

**ffmpeg: must be `ffmpeg-full`, not the slim formula.** Homebrew's regular
`ffmpeg` ships WITHOUT libass/freetype, so subtitle burn-in fails. Install
`brew install ffmpeg-full` (keg-only) and prepend `/opt/homebrew/opt/ffmpeg-full/bin`
to PATH for renders. The slim `ffmpeg` can stay as the system default for other
tools — only the studio needs the full one.

Run `./setup.sh` to install/verify everything idempotently.
