Docs/Skills and code/skill video-visual-production
.claude/skills/video-visual-production/references/edit-guide.md
Handling the user's notes: cheap edits, no rewrites: The rule: a note changes the beat sheet by the smallest possible amount, through edit.js, and the build re-renders only the scenes that changed.
Handling the user's notes: cheap edits, no rewrites
The rule: a note changes the beat sheet by the smallest possible amount, through edit.js, and the build re-renders only the scenes that changed. You never regenerate the beat sheet, never re-author other scenes, never edit the output video. Cost of a typical note: seconds to edit, about 10 to 30 s to re-render one scene, about 15 s to re-mix sound, about 1 minute to re-check.
The loop (for every batch of notes)
- Map each note to a scene id. The user cites ids from
REVIEW-<beat>.md(for exampleB1.06) or a time in seconds. If only a time is given:node .claude/skills/video-visual-production/scripts/edit.js show --sheet <sheet>lists every scene with its time range. Pick the scene that contains the time. If the note is ambiguous, ask one short question. - Pick the smallest change from the table below. Use
--note "<the user's words>"so the reason is logged. - Run the edit command. It snapshots the sheet, applies the change, lints it, and reverts automatically with the reason if it breaks a hard gate. Read its output. If it says
REVERTED, adjust (usually shorten the text, or move a cue earlier) and try again. - Look before building if the change is visual:
node .../scripts/preview-scene.js --sheet <sheet> --scene <id>(about 1 s) and open the PNG. - Rebuild once after the whole batch:
node .../scripts/build-beat.js --sheet <sheet>. Unchanged scenes come from the cache (the output listscachedorrenderedper scene). Use--skip-checkfor a quick intermediate build; always run the full build before reporting. - Report what changed, per note, in one line each, and what you could not do. Do not claim the result is better; say what was measured and what the user should look at.
Which command for which note
| The user says | Command (always add --sheet <sheet> --note "...") | Re-render |
|---|---|---|
| "change the wording of X" | edit.js set B1.08 props.lines.0.text "new words" (also update the same string in that scene's text list: edit.js set B1.08 text.0.value "new words") | that scene |
| "the highlight comes late / early" | edit.js words <a> <b> to find a better word, then edit.js cue B1.03 odd 33 | that scene |
| "highlight a different phrase" | edit.js set B1.06 props.highlights.1.phrase "..." (the phrase must be listed in that capture's highlights in assets: edit.js set sheet assets.0.crops.1.highlights.2 "..." then build-beat.js --refresh-assets) | that scene |
| "this number should stay longer" | cue earlier: edit.js cue ... , or shorten the text, or edit.js set B1.15 start_shift_frames 12 to start the next scene later | two scenes |
| "swipe/tick/stamp is too loud / quiet" | edit.js level swipe -22 (dB relative to the voice peak; defaults: tick -14, thud -9, stamp -9, whoosh -16, swipe -18, paper -20, pivot -14, clink -14, clock -30) | sound only |
| "drop the sound in X" | edit.js sfx-remove B1.02 0 (index in that scene's sfx list; edit.js show B1.02 shows it) | sound only |
| "bed too loud / remove the bed" | edit.js set sheet bed.level_db -30 or edit.js set sheet bed.enabled false | sound only |
| "change the colours" | edit.js set sheet style.accent "#e8a826" (keys: accent, good, loss, ink, muted, dim, bg0, bg1, panel, panelEdge, paper, paperInk, mark) | every scene |
| "use another kind of scene here" | edit.js set B1.07 type slam and edit.js set B1.07 props '{...}' (JSON), plus cues and text; copy from scene-catalogue.md | that scene |
| "make this scene longer/shorter" | scene length follows the voice; change its span and its neighbour's, or start_shift_frames | two scenes |
| "undo that" | edit.js undo (restores the previous snapshot) | |
| "what did we change?" | edit.js history |
Values with spaces need quotes. JSON values are parsed ('{"text":"x"}', -14, true), anything else is a string. Path syntax is dotted, arrays by index (props.highlights.0.phrase).
What is not cheap, and what to do
- A motion or layout change inside a scene type (for example "the glass should tilt"): edit
render/scenes.jsfor that function only. All scenes of that type re-render, the rest come from cache. Re-run the layout checks by running the full build. - A new scene type: write the function in
render/scenes.js, add the type name toSCENE_TYPESinscripts/beatsheet-lint.js, add a section toscene-catalogue.md, use it in one scene, build. Do not use it in more than one scene before the user has seen it. - A changed script or voice-over: word indexes move. Re-align the beat, re-check every cue (
edit.js words), and rebuild. This is the one expensive case, so tell the user the cost before doing it. - A different bed or real music: put the file path in the sheet's
bedblock after adding support; today the bed is a synthesised placeholder. Ask the user to audition candidates; do not choose music by yourself.
Rules for you while editing
- Never open a rendered MP4 or edit the PNGs. The beat sheet is the source of truth.
- Never edit lint rules or the checks to make a change pass. If a rule blocks a good idea, tell the user which rule and why.
- One note, one change, one log line. Do not "improve" other scenes while you are there.
- Keep every snapshot (they are in
video/history/); do not delete them. - If two notes conflict, do neither and ask.
- After a batch, tell the user the exact files to look at: the new
B1.mp4, the newcontact-sheet.png, and the scene ids that were re-rendered.
Show the raw text
# Handling the user's notes: cheap edits, no rewrites
**The rule:** a note changes the **beat sheet** by the smallest possible amount, through `edit.js`, and the build re-renders only the scenes that changed. You never regenerate the beat sheet, never re-author other scenes, never edit the output video. Cost of a typical note: seconds to edit, about 10 to 30 s to re-render one scene, about 15 s to re-mix sound, about 1 minute to re-check.
## The loop (for every batch of notes)
1. **Map each note to a scene id.** The user cites ids from `REVIEW-<beat>.md` (for example `B1.06`) or a time in seconds. If only a time is given: `node .claude/skills/video-visual-production/scripts/edit.js show --sheet <sheet>` lists every scene with its time range. Pick the scene that contains the time. If the note is ambiguous, ask one short question.
2. **Pick the smallest change** from the table below. Use `--note "<the user's words>"` so the reason is logged.
3. **Run the edit command.** It snapshots the sheet, applies the change, lints it, and **reverts automatically with the reason if it breaks a hard gate**. Read its output. If it says `REVERTED`, adjust (usually shorten the text, or move a cue earlier) and try again.
4. **Look before building** if the change is visual: `node .../scripts/preview-scene.js --sheet <sheet> --scene <id>` (about 1 s) and open the PNG.
5. **Rebuild once** after the whole batch: `node .../scripts/build-beat.js --sheet <sheet>`. Unchanged scenes come from the cache (the output lists `cached` or `rendered` per scene). Use `--skip-check` for a quick intermediate build; always run the full build before reporting.
6. **Report** what changed, per note, in one line each, and what you could not do. Do not claim the result is better; say what was measured and what the user should look at.
## Which command for which note
| The user says | Command (always add `--sheet <sheet> --note "..."`) | Re-render |
|---|---|---|
| "change the wording of X" | `edit.js set B1.08 props.lines.0.text "new words"` (also update the same string in that scene's `text` list: `edit.js set B1.08 text.0.value "new words"`) | that scene |
| "the highlight comes late / early" | `edit.js words <a> <b>` to find a better word, then `edit.js cue B1.03 odd 33` | that scene |
| "highlight a different phrase" | `edit.js set B1.06 props.highlights.1.phrase "..."` (the phrase must be listed in that capture's `highlights` in `assets`: `edit.js set sheet assets.0.crops.1.highlights.2 "..."` then `build-beat.js --refresh-assets`) | that scene |
| "this number should stay longer" | cue earlier: `edit.js cue ...` , or shorten the text, or `edit.js set B1.15 start_shift_frames 12` to start the next scene later | two scenes |
| "swipe/tick/stamp is too loud / quiet" | `edit.js level swipe -22` (dB relative to the voice peak; defaults: tick -14, thud -9, stamp -9, whoosh -16, swipe -18, paper -20, pivot -14, clink -14, clock -30) | sound only |
| "drop the sound in X" | `edit.js sfx-remove B1.02 0` (index in that scene's `sfx` list; `edit.js show B1.02` shows it) | sound only |
| "bed too loud / remove the bed" | `edit.js set sheet bed.level_db -30` or `edit.js set sheet bed.enabled false` | sound only |
| "change the colours" | `edit.js set sheet style.accent "#e8a826"` (keys: accent, good, loss, ink, muted, dim, bg0, bg1, panel, panelEdge, paper, paperInk, mark) | every scene |
| "use another kind of scene here" | `edit.js set B1.07 type slam` and `edit.js set B1.07 props '{...}'` (JSON), plus cues and text; copy from `scene-catalogue.md` | that scene |
| "make this scene longer/shorter" | scene length follows the voice; change its `span` and its neighbour's, or `start_shift_frames` | two scenes |
| "undo that" | `edit.js undo` (restores the previous snapshot) | |
| "what did we change?" | `edit.js history` | |
Values with spaces need quotes. JSON values are parsed (`'{"text":"x"}'`, `-14`, `true`), anything else is a string. Path syntax is dotted, arrays by index (`props.highlights.0.phrase`).
## What is not cheap, and what to do
- **A motion or layout change inside a scene type** (for example "the glass should tilt"): edit `render/scenes.js` for that function only. All scenes of that type re-render, the rest come from cache. Re-run the layout checks by running the full build.
- **A new scene type:** write the function in `render/scenes.js`, add the type name to `SCENE_TYPES` in `scripts/beatsheet-lint.js`, add a section to `scene-catalogue.md`, use it in one scene, build. Do not use it in more than one scene before the user has seen it.
- **A changed script or voice-over:** word indexes move. Re-align the beat, re-check every cue (`edit.js words`), and rebuild. This is the one expensive case, so tell the user the cost before doing it.
- **A different bed or real music:** put the file path in the sheet's `bed` block after adding support; today the bed is a synthesised placeholder. Ask the user to audition candidates; do not choose music by yourself.
## Rules for you while editing
- Never open a rendered MP4 or edit the PNGs. The beat sheet is the source of truth.
- Never edit lint rules or the checks to make a change pass. If a rule blocks a good idea, tell the user which rule and why.
- One note, one change, one log line. Do not "improve" other scenes while you are there.
- Keep every snapshot (they are in `video/history/`); do not delete them.
- If two notes conflict, do neither and ask.
- After a batch, tell the user the exact files to look at: the new `B1.mp4`, the new `contact-sheet.png`, and the scene ids that were re-rendered.
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.