Docs/Skills and code/skill video-visual-production
.claude/skills/video-visual-production/SKILL.md
Build, rebuild, edit and check a video beat (1080p, 30 fps) for the "Why X died" channel from a finished voice-over, its aligned word times and a hand-written beat sheet.
name: video-visual-production
description: Build, rebuild, edit and check a video beat (1080p, 30 fps) for the "Why X died" channel from a finished voice-over, its aligned word times and a hand-written beat sheet. Produces on-screen evidence (captured article passages, licensed photos), data and diagram scenes tied to spoken words, synthesised sound effects, a quiet placeholder bed and a measured mix. Use when the user asks to make, render, preview, edit, check or revise a video or a video beat, to apply their notes on a video, or to run the B1 smoke test.
Video visual production
Start here (30 seconds)
- Read
references/runbook.mdand follow it step by step. It is written so that a small model can run it. The worked example is beat B1 of Moser Baer v7 Hinglish. - Notes from the user on a built video: read
references/edit-guide.md. Edits are small, logged, linted and re-render only the scenes they touch. - Something broke:
references/troubleshooting.md. - Choosing or filling a scene:
references/scene-catalogue.md. - The reasoning, research and plan behind all of this:
research/video-production/(start atREADME.md; the B1 plan is07-b1-smoke-test.md; legal and YouTube findings are in04and06).
You write one file, the beat sheet (research/<topic>/video/beat-sheet-<beat>.json). Scripts do everything else. You cannot watch or hear the video: the checks are measurements and stills, and the user judges taste. Never say a video is good; say what was measured and what you saw.
Commands (from the repo root; S=.claude/skills/video-visual-production/scripts)
| Do | Command |
|---|---|
| One-time install | cd .claude/skills/video-visual-production/render && npm install |
| New beat sheet (scaffold) | node $S/new-beat.js --beat B4 --title "..." --slug <slug> --audio <wav> --words <words.json> --dir research/<topic>/video |
| Find a word index and time | node $S/edit.js words 100 140 --sheet <sheet> |
| Lint (hard gates must be 0) | node $S/beatsheet-lint.js --sheet <sheet> [--damage] |
| Quick look at the build | node $S/build-beat.js --sheet <sheet> --preview |
| Full build and check | node $S/build-beat.js --sheet <sheet> (about 4 min; only changed scenes re-render) |
| One scene as a PNG | node $S/preview-scene.js --sheet <sheet> --scene B1.06 |
| Apply a note | node $S/edit.js set|cue|level|sfx-remove|undo|history ... |
| The whole B1 proof | node $S/smoke-b1.js |
Output goes to C:\video-build\<slug>\<beat>\ (outside OneDrive; override with VIDEO_BUILD_DIR): <beat>.mp4, contact-sheet.png, spectrogram.png, <beat>.srt, audio/ stems, cache/. Tracked files go beside the script in research/<topic>/video/: beat-sheet-*.json, ledger-*.json, timeline-*.json, assets.csv, credits-*.txt, lint-*.md, STATUS-video-*.md, REVIEW-*.md (give this to the user: scene ids, times, what is said, what is shown), edits-*.md (the edit log), history/ (snapshots).
How it fits together
| Stage | Script | Reads | Writes |
|---|---|---|---|
| Assets | assets.js | beat sheet assets | captures (headless Chrome, one passage each, with phrase boxes, URL, date, hash), Commons photos (free licences only), a record each, assets.csv, credits |
| Lint | beatsheet-lint.js | sheet, word times, ledger, records | lint-*.md; exit 1 on a hard gate; --damage runs 15 mutations that must all be caught |
| Timeline | timeline.js | sheet, words.json | integer frames at 30 fps, cue seconds, sound events |
| Render | render/render.js | timeline, assets | silent MP4 from raw frames piped to ffmpeg; per-scene cache keyed by scene content, timing, assets, style and code |
| Sound | sfx.js, mix.js | timeline, voice WAV, levels, bed | stems and mix.wav at -14 LUFS, peak under -1 dBTP |
| Captions | captions.js | words | .srt sidecar (not burned in; the Roman-Hinglish decision is open) |
| Review | review.js | sheet, timeline | REVIEW-*.md |
| Check | check-video.js | final MP4, stems, layout audit | STATUS-video-*.md, contact sheet, spectrogram |
Standing choices (from the user or the research; do not re-ask)
- Articles and text on screen are approved: cropped screenshots of one passage (highlighted, source line, capture record) and typeset or animated text. No article photographs, no broadcaster video, never ANI footage. Reasons and law:
research/video-production/06-real-footage-and-youtube.md. - If a capture fails the scene falls back to our own typeset card and says so on screen and in the status file. A typeset card never imitates the paper's own page.
- Only ledger statuses
V,V-1source,derived,analysisare drawn;[CHECK]and[V-search]never are. - The bed is a synthesised placeholder labelled as such; real music is chosen by the user after auditioning.
- Do not commit, push or deploy unless asked. Do not spawn subagents unless asked. When you add or change a tool, add a row in
.claude/skills/video-script-production/references/tools.mdand a line inhistory.mdin the same session.
Rules the lint and the check enforce (hard gates)
H1 every scene has a class and a known type. H2 figures resolve to a ledger row. H3 evidence scenes have a record, a source URL and an on-screen source line. H4 no news video, logos, faces, stock. H5 only allowed ledger statuses. H8 every numeral spoken is shown and every numeral shown is spoken (or recalled). T1 text holds at least max(1.2 s, 0.35 s a word). T2 to T4 text size, contrast, safe area, no overlaps (measured on the rendered scenes). A3/A4 sound spacing, density, event ids. S2 each sound within one frame of its event. Q0 to Q4 format, frame count, no undeclared black, freeze over 8 s or silence over 1.5 s, cuts land, audio and video agree. A1 -14 LUFS (+-1), true peak under -1 dBTP. The verdict is never "BAR MET": that needs the user's eyes and ears.
Running many beats
Storyboarding is done with a compact plan: write research/<topic>/video/plan-<beat>.json (format and one example per scene type: references/plan-format.md, regenerated by render/make-plan-format.js) and run node scripts/compose-beat.js --beat B#, which derives the beat sheet and ledger. Hand-writing a full beat sheet is only for new scene types.
Use .claude/skills/video-beats-orchestrate/SKILL.md (Haiku for prepare and build, Sonnet for storyboard and review). One-command helpers: align-beat.js --beat B#, brief-beat.js --beat B#, new-beat.js ... --local. build-beat.js queues for one of two build slots.
Known gaps
Word times: B1 (words.json, global timeline with an offset), B0 and B2 onward (align-beat.js, local times). Scene types: the original 12 in scenes.js, 9 for the hook in scenes-b0.js, 12 generic data and diagram scenes in scenes-data.js (see the catalogue). 12 of the 26 planned scene types exist; four of them (cast, photo, merge, cocktail) contain B1-specific text or layout (see scene-catalogue.md). No burned captions, no recognition foley or licensed music, no OTIO export, no retention report. Scene-type changes affect every scene of that type.
Stitching the beats
scripts/stitch.js joins the built beats into one video with transitions and a continuous synthesised score (scripts/score.js, specs in research/<topic>/video/score-spec.json). Steps and outputs: references/runbook.md, last section. The score is a plain additive-synthesis pad that nobody has listened to; say so.
Show the raw text
---
name: video-visual-production
description: Build, rebuild, edit and check a video beat (1080p, 30 fps) for the "Why X died" channel from a finished voice-over, its aligned word times and a hand-written beat sheet. Produces on-screen evidence (captured article passages, licensed photos), data and diagram scenes tied to spoken words, synthesised sound effects, a quiet placeholder bed and a measured mix. Use when the user asks to make, render, preview, edit, check or revise a video or a video beat, to apply their notes on a video, or to run the B1 smoke test.
---
# Video visual production
## Start here (30 seconds)
1. **Read `references/runbook.md`** and follow it step by step. It is written so that a small model can run it. The worked example is beat **B1** of Moser Baer v7 Hinglish.
2. **Notes from the user on a built video:** read `references/edit-guide.md`. Edits are small, logged, linted and re-render only the scenes they touch.
3. **Something broke:** `references/troubleshooting.md`.
4. **Choosing or filling a scene:** `references/scene-catalogue.md`.
5. The reasoning, research and plan behind all of this: `research/video-production/` (start at `README.md`; the B1 plan is `07-b1-smoke-test.md`; legal and YouTube findings are in `04` and `06`).
You write one file, the **beat sheet** (`research/<topic>/video/beat-sheet-<beat>.json`). Scripts do everything else. You cannot watch or hear the video: the checks are measurements and stills, and the user judges taste. **Never say a video is good; say what was measured and what you saw.**
## Commands (from the repo root; `S=.claude/skills/video-visual-production/scripts`)
| Do | Command |
|---|---|
| One-time install | `cd .claude/skills/video-visual-production/render && npm install` |
| New beat sheet (scaffold) | `node $S/new-beat.js --beat B4 --title "..." --slug <slug> --audio <wav> --words <words.json> --dir research/<topic>/video` |
| Find a word index and time | `node $S/edit.js words 100 140 --sheet <sheet>` |
| Lint (hard gates must be 0) | `node $S/beatsheet-lint.js --sheet <sheet> [--damage]` |
| Quick look at the build | `node $S/build-beat.js --sheet <sheet> --preview` |
| Full build and check | `node $S/build-beat.js --sheet <sheet>` (about 4 min; only changed scenes re-render) |
| One scene as a PNG | `node $S/preview-scene.js --sheet <sheet> --scene B1.06` |
| Apply a note | `node $S/edit.js set\|cue\|level\|sfx-remove\|undo\|history ...` |
| The whole B1 proof | `node $S/smoke-b1.js` |
Output goes to `C:\video-build\<slug>\<beat>\` (outside OneDrive; override with `VIDEO_BUILD_DIR`): `<beat>.mp4`, `contact-sheet.png`, `spectrogram.png`, `<beat>.srt`, `audio/` stems, `cache/`. Tracked files go beside the script in `research/<topic>/video/`: `beat-sheet-*.json`, `ledger-*.json`, `timeline-*.json`, `assets.csv`, `credits-*.txt`, `lint-*.md`, `STATUS-video-*.md`, `REVIEW-*.md` (give this to the user: scene ids, times, what is said, what is shown), `edits-*.md` (the edit log), `history/` (snapshots).
## How it fits together
| Stage | Script | Reads | Writes |
|---|---|---|---|
| Assets | `assets.js` | beat sheet `assets` | captures (headless Chrome, one passage each, with phrase boxes, URL, date, hash), Commons photos (free licences only), a record each, `assets.csv`, credits |
| Lint | `beatsheet-lint.js` | sheet, word times, ledger, records | `lint-*.md`; exit 1 on a hard gate; `--damage` runs 15 mutations that must all be caught |
| Timeline | `timeline.js` | sheet, `words.json` | integer frames at 30 fps, cue seconds, sound events |
| Render | `render/render.js` | timeline, assets | silent MP4 from raw frames piped to ffmpeg; per-scene cache keyed by scene content, timing, assets, style and code |
| Sound | `sfx.js`, `mix.js` | timeline, voice WAV, `levels`, `bed` | stems and `mix.wav` at -14 LUFS, peak under -1 dBTP |
| Captions | `captions.js` | words | `.srt` sidecar (not burned in; the Roman-Hinglish decision is open) |
| Review | `review.js` | sheet, timeline | `REVIEW-*.md` |
| Check | `check-video.js` | final MP4, stems, layout audit | `STATUS-video-*.md`, contact sheet, spectrogram |
## Standing choices (from the user or the research; do not re-ask)
- Articles and text on screen are approved: cropped screenshots of one passage (highlighted, source line, capture record) and typeset or animated text. No article photographs, no broadcaster video, never ANI footage. Reasons and law: `research/video-production/06-real-footage-and-youtube.md`.
- If a capture fails the scene falls back to our own typeset card and says so on screen and in the status file. A typeset card never imitates the paper's own page.
- Only ledger statuses `V`, `V-1source`, `derived`, `analysis` are drawn; `[CHECK]` and `[V-search]` never are.
- The bed is a synthesised placeholder labelled as such; real music is chosen by the user after auditioning.
- Do not commit, push or deploy unless asked. Do not spawn subagents unless asked. When you add or change a tool, add a row in `.claude/skills/video-script-production/references/tools.md` and a line in `history.md` in the same session.
## Rules the lint and the check enforce (hard gates)
H1 every scene has a class and a known type. H2 figures resolve to a ledger row. H3 evidence scenes have a record, a source URL and an on-screen source line. H4 no news video, logos, faces, stock. H5 only allowed ledger statuses. H8 every numeral spoken is shown and every numeral shown is spoken (or recalled). T1 text holds at least max(1.2 s, 0.35 s a word). T2 to T4 text size, contrast, safe area, no overlaps (measured on the rendered scenes). A3/A4 sound spacing, density, event ids. S2 each sound within one frame of its event. Q0 to Q4 format, frame count, no undeclared black, freeze over 8 s or silence over 1.5 s, cuts land, audio and video agree. A1 -14 LUFS (+-1), true peak under -1 dBTP. The verdict is never "BAR MET": that needs the user's eyes and ears.
## Running many beats
Storyboarding is done with a compact plan: write `research/<topic>/video/plan-<beat>.json` (format and one example per scene type: `references/plan-format.md`, regenerated by `render/make-plan-format.js`) and run `node scripts/compose-beat.js --beat B#`, which derives the beat sheet and ledger. Hand-writing a full beat sheet is only for new scene types.
Use `.claude/skills/video-beats-orchestrate/SKILL.md` (Haiku for prepare and build, Sonnet for storyboard and review). One-command helpers: `align-beat.js --beat B#`, `brief-beat.js --beat B#`, `new-beat.js ... --local`. `build-beat.js` queues for one of two build slots.
## Known gaps
Word times: B1 (words.json, global timeline with an offset), B0 and B2 onward (`align-beat.js`, local times). Scene types: the original 12 in `scenes.js`, 9 for the hook in `scenes-b0.js`, 12 generic data and diagram scenes in `scenes-data.js` (see the catalogue). 12 of the 26 planned scene types exist; four of them (`cast`, `photo`, `merge`, `cocktail`) contain B1-specific text or layout (see `scene-catalogue.md`). No burned captions, no recognition foley or licensed music, no OTIO export, no retention report. Scene-type changes affect every scene of that type.
## Stitching the beats
`scripts/stitch.js` joins the built beats into one video with transitions and a continuous synthesised score (`scripts/score.js`, specs in `research/<topic>/video/score-spec.json`). Steps and outputs: `references/runbook.md`, last section. The score is a plain additive-synthesis pad that nobody has listened to; say so.
Shown as it is in the repository at build time (2026-11-03); the home directory appears as <home>. If this page and the file differ, the file is right. Back to the catalogue.