Docs/Skills and code/skill video-visual-production

.claude/skills/video-visual-production/SKILL.md

Markdown72 lines7.4 KBSkill: video-visual-production

What the file says about itself

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.

Skill header (frontmatter)

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)

DoCommand
One-time installcd .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 timenode $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 buildnode $S/build-beat.js --sheet <sheet> --preview
Full build and checknode $S/build-beat.js --sheet <sheet> (about 4 min; only changed scenes re-render)
One scene as a PNGnode $S/preview-scene.js --sheet <sheet> --scene B1.06
Apply a notenode $S/edit.js set|cue|level|sfx-remove|undo|history ...
The whole B1 proofnode $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

StageScriptReadsWrites
Assetsassets.jsbeat sheet assetscaptures (headless Chrome, one passage each, with phrase boxes, URL, date, hash), Commons photos (free licences only), a record each, assets.csv, credits
Lintbeatsheet-lint.jssheet, word times, ledger, recordslint-*.md; exit 1 on a hard gate; --damage runs 15 mutations that must all be caught
Timelinetimeline.jssheet, words.jsoninteger frames at 30 fps, cue seconds, sound events
Renderrender/render.jstimeline, assetssilent MP4 from raw frames piped to ffmpeg; per-scene cache keyed by scene content, timing, assets, style and code
Soundsfx.js, mix.jstimeline, voice WAV, levels, bedstems and mix.wav at -14 LUFS, peak under -1 dBTP
Captionscaptions.jswords.srt sidecar (not burned in; the Roman-Hinglish decision is open)
Reviewreview.jssheet, timelineREVIEW-*.md
Checkcheck-video.jsfinal MP4, stems, layout auditSTATUS-video-*.md, contact sheet, spectrogram

Standing choices (from the user or the research; do not re-ask)

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.