prompt-validator
Deterministic pre-spend gate: collect every prompt a video run is
about to send (all scenes, all blocks), cross-check them against each
other and against the run's locked facts (character lock, vocal map,
model capabilities), and block with a specific error on
contradiction. Skills are deterministic — the failure mode of a
multi-scene batch is not drift, it is contradiction: two prompts
that cannot both be true of the same video (AI-council convergence,
2026-06-06). One blocked batch costs a re-edit; one rendered
contradiction costs the whole spend.
When to use
- Immediately before the unified storyboard/cost preview gate in
/video:from-song
Step 8 / /video:from-script —
after every scene's eight-block prompt exists, before anything is
shown for approval or sent live.
- After an operator hand-edits scene prompts (
/video:scene re-runs) —
re-validate the batch, not just the edited scene.
Do NOT use when:
- Only a single scene exists (nothing to contradict) — the per-scene
checks in
video-director already cover internal consistency.
- The run is pure preview with no approval intent — validate when the
batch is about to be gated, not on every draft keystroke.
Inputs
<project>/script.md — every ## Scene N (duration, mood, action,
camera, dialogue).
- Every rendered scene prompt (the eight-block image/video prompts from
video-director / blueprint JSON), in scene order.
<project>/character.json — when present, the locked identity
(subject, palette, wardrobe, prop, seed).
<project>/vocal-map.json — when present, the signed-off
line → singer assignments.
- The chosen model's capability entry (
capability --model <id>).
Procedure
1. Collect the full prompt set
Read every scene's prompt blocks into one table:
scene → {style, subject, environment, action, camera, lens, lighting, mood, duration, aspect, dialogue/singer}. A scene whose prompt is
missing or unparseable → block: scene N: prompt missing/unreadable
— an incomplete batch is already a contradiction with the script.
2. Style consistency
The style block must agree across all scenes — one look per video
unless the script names an intentional break (e.g. "dream sequence").
- Conflicting render families (
photorealistic vs cel-shaded /
claymation / watercolor) with no scripted break →
style mismatch: scene 3 'photorealistic' vs scene 7 'cel-shaded'.
- Conflicting era/grade tokens (
1970s film grain vs clean digital HDR) → same error shape, name both scenes and both tokens.
3. Character consistency (character mode)
With character.json present, every scene naming the subject must
match the lock:
- Wardrobe / palette / prop drift (
red coat locked, scene says
blue jacket) → character mismatch: scene 5 'blue jacket' vs lock 'red coat'.
- A scene inventing a second recurring subject the script never cast →
flag it — uncast identities break continuity AND the likeness gate.
- Lip-sync ownership: a scene with a
dialogue: line must name the
vocal map's singer for that line — wrong mouth on wrong words is the
render-money-burning failure (media-sync-ground-truth). A "?"
singer with a lip-sync scene → block until resolved.
4. Physics + continuity
- Day/night or weather flips inside one contiguous song section
with no scripted transition →
continuity: scene 4 'noon sun' → scene 5 'starry night' within the same chorus.
- Impossible camera/action pairs (
locked-off tripod + whip pan),
(underwater + desert dust) → name scene + the two tokens.
- Duration / aspect vs. the model envelope: any scene outside
[min_duration, max_duration] or with an aspect the model does not
list → block with the violated bound (defense-in-depth after
song-to-script Step 1 — hand-edited prompts re-open this hole).
5. Verdict
- Zero findings → emit
prompt-validator: N scenes, no contradictions and hand the batch to the preview gate.
- Any finding → block the gate. Report every finding (not just
the first), each as
class: scene(s) + conflicting values + fix hint. The operator (or the calling command) fixes the prompts and
re-runs the validator — never "approve anyway" past a contradiction;
an intentional break gets scripted (named in script.md), which
legitimizes it on the next pass.
Output format
- One line per finding —
class: scene(s) + conflicting values + fix hint — and report every finding, never just the first.
- Terminal
verdict: line: OK with the scene count, or
BLOCKED (N contradictions) — fix and re-run; a blocked verdict
never hands the batch to the preview gate.
prompt-validator: 12 scenes checked
✅ style: one look (neo-noir, consistent)
❌ character: scene 5 'blue jacket' vs character.json 'red coat' — align scene 5 or update the lock
❌ lip-sync: scene 9 dialogue assigned to 'Freya' but vocal-map line 24.5-27.8 is singer '?' — resolve the singer first
verdict: BLOCKED (2 contradictions) — fix and re-run
Gotchas
- An intentional style break is scripted, not waved through. The
validator only accepts a break that
script.md names; "the operator
said it's fine in chat" does not survive to the next run.
- Re-validate after every hand-edit. A single edited scene can
contradict five untouched ones; the batch is the unit, not the scene.
verified: false capability entries still gate. Blocking on a
documented-best-effort bound beats rendering past a real one; the
report names the unverified flag so the operator can override by
editing the manifest, never by skipping the check.
Do NOT
- Do NOT auto-fix prompts — report and block; the fix is the
operator's (or calling skill's) edit, visible in the diff.
- Do NOT validate only changed scenes — always the full batch.
- Do NOT soften a contradiction into a warning — contradictions block;
only consistency passes.
- Do NOT duplicate
video-director's per-scene craft checks — this
skill owns cross-scene contradiction only.
See also
1---2name: prompt-validator3description: Pre-spend contradiction gate for AI-video runs: checks every prompt in the batch, blocks on style / character / physics mismatch. Triggers 'validate the prompts', 'check the storyboard'.4---56# prompt-validator78> Deterministic pre-spend gate: collect **every** prompt a video run is9> about to send (all scenes, all blocks), cross-check them against each10> other and against the run's locked facts (character lock, vocal map,11> model capabilities), and **block with a specific error** on12> contradiction. Skills are deterministic — the failure mode of a13> multi-scene batch is not drift, it is *contradiction*: two prompts14> that cannot both be true of the same video (AI-council convergence,15> 2026-06-06). One blocked batch costs a re-edit; one rendered16> contradiction costs the whole spend.1718## When to use1920- Immediately **before** the unified storyboard/cost preview gate in21 [`/video:from-song`](../../commands/video/from-song.md)22 Step 8 / [`/video:from-script`](../../commands/video/from-script.md) —23 after every scene's eight-block prompt exists, before anything is24 shown for approval or sent live.25- After an operator hand-edits scene prompts (`/video:scene` re-runs) —26 re-validate the batch, not just the edited scene.2728Do NOT use when:2930- Only a single scene exists (nothing to contradict) — the per-scene31 checks in `video-director` already cover internal consistency.32- The run is pure preview with no approval intent — validate when the33 batch is about to be gated, not on every draft keystroke.3435## Inputs3637- `<project>/script.md` — every `## Scene N` (duration, mood, action,38 camera, dialogue).39- Every rendered scene prompt (the eight-block image/video prompts from40 `video-director` / blueprint JSON), in scene order.41- `<project>/character.json` — when present, the locked identity42 (subject, palette, wardrobe, prop, seed).43- `<project>/vocal-map.json` — when present, the signed-off44 line → singer assignments.45- The chosen model's capability entry (`capability --model <id>`).4647## Procedure4849### 1. Collect the full prompt set5051Read every scene's prompt blocks into one table:52`scene → {style, subject, environment, action, camera, lens, lighting,53mood, duration, aspect, dialogue/singer}`. A scene whose prompt is54missing or unparseable → **block**: `scene N: prompt missing/unreadable`55— an incomplete batch is already a contradiction with the script.5657### 2. Style consistency5859The `style` block must agree across all scenes — one look per video60unless the script *names* an intentional break (e.g. "dream sequence").6162- Conflicting render families (`photorealistic` vs `cel-shaded` /63 `claymation` / `watercolor`) with no scripted break →64 `style mismatch: scene 3 'photorealistic' vs scene 7 'cel-shaded'`.65- Conflicting era/grade tokens (`1970s film grain` vs `clean digital66 HDR`) → same error shape, name both scenes and both tokens.6768### 3. Character consistency (character mode)6970With `character.json` present, every scene naming the subject must71match the lock:7273- Wardrobe / palette / prop drift (`red coat` locked, scene says74 `blue jacket`) → `character mismatch: scene 5 'blue jacket' vs lock75 'red coat'`.76- A scene inventing a second recurring subject the script never cast →77 flag it — uncast identities break continuity AND the likeness gate.78- **Lip-sync ownership:** a scene with a `dialogue:` line must name the79 vocal map's singer for that line — wrong mouth on wrong words is the80 render-money-burning failure (`media-sync-ground-truth`). A `"?"`81 singer with a lip-sync scene → block until resolved.8283### 4. Physics + continuity8485- Day/night or weather flips **inside one contiguous song section**86 with no scripted transition → `continuity: scene 4 'noon sun' →87 scene 5 'starry night' within the same chorus`.88- Impossible camera/action pairs (`locked-off tripod` + `whip pan`),89 (`underwater` + `desert dust`) → name scene + the two tokens.90- Duration / aspect vs. the model envelope: any scene outside91 `[min_duration, max_duration]` or with an aspect the model does not92 list → block with the violated bound (defense-in-depth after93 `song-to-script` Step 1 — hand-edited prompts re-open this hole).9495### 5. Verdict9697- **Zero findings** → emit `prompt-validator: N scenes, no98 contradictions` and hand the batch to the preview gate.99- **Any finding** → **block the gate**. Report every finding (not just100 the first), each as `class: scene(s) + conflicting values + fix101 hint`. The operator (or the calling command) fixes the prompts and102 re-runs the validator — never "approve anyway" past a contradiction;103 an intentional break gets *scripted* (named in `script.md`), which104 legitimizes it on the next pass.105106## Output format1071081. One line per finding — `class: scene(s) + conflicting values + fix109 hint` — and report **every** finding, never just the first.1102. Terminal `verdict:` line: `OK` with the scene count, or111 `BLOCKED (N contradictions) — fix and re-run`; a blocked verdict112 never hands the batch to the preview gate.113114```115prompt-validator: 12 scenes checked116✅ style: one look (neo-noir, consistent)117❌ character: scene 5 'blue jacket' vs character.json 'red coat' — align scene 5 or update the lock118❌ lip-sync: scene 9 dialogue assigned to 'Freya' but vocal-map line 24.5-27.8 is singer '?' — resolve the singer first119verdict: BLOCKED (2 contradictions) — fix and re-run120```121122## Gotchas123124- **An intentional style break is scripted, not waved through.** The125 validator only accepts a break that `script.md` names; "the operator126 said it's fine in chat" does not survive to the next run.127- **Re-validate after every hand-edit.** A single edited scene can128 contradict five untouched ones; the batch is the unit, not the scene.129- **`verified: false` capability entries still gate.** Blocking on a130 documented-best-effort bound beats rendering past a real one; the131 report names the unverified flag so the operator can override by132 editing the manifest, never by skipping the check.133134## Do NOT135136- Do NOT auto-fix prompts — report and block; the fix is the137 operator's (or calling skill's) edit, visible in the diff.138- Do NOT validate only changed scenes — always the full batch.139- Do NOT soften a contradiction into a warning — contradictions block;140 only consistency passes.141- Do NOT duplicate `video-director`'s per-scene craft checks — this142 skill owns *cross-scene* contradiction only.143144## See also145146- [`/video:from-song`](../../commands/video/from-song.md) —147 invokes this before the unified storyboard/cost preview gate (Step 8).148- [`video-director`](../video-director/SKILL.md) — produces the prompts149 this skill cross-checks.150- [`character-consistency`](../character-consistency/SKILL.md) — the151 lock this skill enforces against.152- [`song-to-script`](../song-to-script/SKILL.md) — upstream timing +153 vocal-map source.