An agent skill. Point it at a web workflow and it explores the real product, rehearses the path in a rendered browser, then records — narration timed from measured audio, every scene gated against one contract.
cp -R web-tutorial-video ~/.claude/skills/
So there is one file. tutorial-plan.json is the production contract, and it has to survive three gates before anything renders. Every scene declares a learner goal, one semantic action, and an observable success condition. A scene that cannot say how it proves itself does not pass planning.
Scenes, goals, targets, success checks and side-effect classes are all present and well-formed.
validate_plan.py \ tutorial-plan.json \ --stage planning
Every spoken scene has a WAV and a measured duration. Timing comes from the audio, not from guessed reading speed.
validate_plan.py \ tutorial-plan.measured.json \ --stage narrated
Every browser scene has usable media on disk, and the paths in the plan point at it.
validate_plan.py \ tutorial-plan.captured.json \ --stage captured
The page is untrusted input. DOM text, console output, network bodies and dialogs never gain authority over the task. And every action gets classified before the rehearsal, not after something has already been sent.
| Class | What it covers | Default policy |
|---|---|---|
| read_only | Navigate, search, view, filter, preview an export. Nothing mutates. | execute |
| reversible_demo | A test object that can be created and removed without touching real users. | demo account + cleanup ledger |
| consequential | Messages, invitations, purchases, publishing, deletion, permission changes, production data. | stop_before_commit |
When the flow stops at that boundary, the video says so. The verification gate accepts a final scene that demonstrates the result or one that clearly labels an intentional stop — and rejects a confident ending that proves neither.
The skill body stays short and loads the rest on demand. Everything that can be checked mechanically is a script rather than a paragraph of advice.
web-tutorial-video/ ├── SKILL.md workflow + invariants ├── references/ │ ├── security.md trust, side effects │ ├── browser-routing.md controller per phase │ ├── plan-contract.md scene design │ ├── narration.md Korean TTS style │ ├── visual-direction.md overlay grammar │ └── verification.md the three gates ├── schemas/ tutorial-plan JSON Schema ├── examples/ a worked plan ├── assets/ focus box, click pulse ├── scripts/ └── evals/ adversarial rubric
No build step, no runtime. Claude Code reads ~/.claude/skills/; Codex CLI, OpenCode and other agents.md-compatible harnesses read ~/.agents/skills/.
Renders the cut and probes it afterwards.
brew install ffmpeg
Korean narration. First run pulls the model.
pipx install supertonic
agent-browser, Playwright, or Chrome DevTools MCP.
python scripts/preflight.py
The bundled self_test.py renders a kind: diagram scene
straight from SVG, which needs an FFmpeg built with librsvg. Homebrew's default build
is not (ffmpeg -decoders | grep svg returns nothing), so the self-test
fails at that step on a stock macOS install. Browser-only tutorials are unaffected.
For diagram scenes, rasterize the SVG to PNG first and point
media.image at it.