# Veo Prompt Lint

> Use before submitting a Veo prompt or a batch of clip prompts, and when a generated clip came back with unwanted speech, the wrong camera motion, ignored references, or a wrong environment after a cut. Runs a regex linter over prompt text and proposes rewrites for the gotchas that recur every episode. Triggers on "lint veo prompt", "check this veo prompt", "veo prompt review".

- Skill: `raphaelbgr/veo-prompt-lint` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add raphaelbgr/veo-prompt-lint`
- Raw SKILL.md: https://api.skillmd.com/api/skills/raphaelbgr/veo-prompt-lint/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: raphaelbgr (https://skillmd.com/u/raphaelbgr)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/raphaelbgr/veo-prompt-lint

---


# Veo prompt lint — screen before you spend

A regex-based linter that catches the Veo prompt mistakes that recur on every
production. It is a **heuristic, not a parser** — it nudges, it does not guarantee.
The point is to catch a 15-credit mistake before you pay for it.

Script: [`scripts/veo_lint.py`](scripts/veo_lint.py) — stdlib only, Python 3.8+.

---

## Rules

| ID | Trigger | Why it bites | Fix |
|---|---|---|---|
| **R1a** | A silent / non-dialogue clip that **has** an `Audio language: <X>` line | The explicit language directive forces Veo to generate unwanted speech | Delete the language line; add `No dialogue - ambient sound only` |
| **R1b** | A non-dialogue clip with **no** explicit silence directive | Veo defaults to **English** speech and invents lines | Add `No dialogue - ambient sound and SFX only` — and never an `Audio language:` line |
| **R2** | `LOCKED TRIPOD` / `locked-tripod` | Misread; Veo adds motion anyway, and sometimes renders a literal tripod | Use `static shot` (optionally `static shot, no camera movement`) |
| **R3** | More than 3 reference images / ingredients | Veo supports at most 3; the extras are silently ignored | Reduce to ≤3; merge, or split across shots |
| **R4** | An environment transition (door, hallway, room change) with no `Extend from prior clip` | Veo guesses the destination environment, usually wrong | Add `Extend from prior clip.` and describe the destination |

The rule logic, patterns and exact rewrite text live in `scripts/veo_lint.py` — that
file is the single source of truth. Tune the patterns there, not in this table.

---

## Usage

```bash
# a single prompt string
python scripts/veo_lint.py "your prompt text"

# a prompt file
python scripts/veo_lint.py path/to/clip07.txt

# a batch: blank-line-separated blocks, or a JSON array / JSONL of {"id","prompt"}
python scripts/veo_lint.py path/to/episode_prompts.txt

# machine-readable
python scripts/veo_lint.py prompts.json --json

# pipe
cat prompt.txt | python scripts/veo_lint.py --stdin
```

Exit code: `0` = clean · `1` = at least one violation.

---

## How to apply it

1. Run the linter on the prompt or batch.
2. For each violation, apply the suggested rewrite — **or** justify keeping it (e.g. the
   clip genuinely has dialogue the regex missed).
3. Re-run until clean, or until only knowingly-accepted WARNs remain.
4. Report **ERRORs vs WARNs** separately. ERRORs (R1a, R2, R3) almost always need
   fixing; WARNs (R1b, R4) need a judgment call.

---

## Calibrate it before you trust it

These are heuristics with expected false positives and negatives. Before running it on
a real production:

1. Pick 4–6 of your own past prompts — a mix: a silent clip, a dialogue clip, a
   continuity/transition clip, a multi-reference clip.
2. Run each one through the linter.
3. For every flag, confirm the rule actually applied (true positive) versus misfired
   (false positive). For every prompt you *know* had a problem, confirm it was flagged
   (catch the false negatives).
4. If a pattern is wrong, edit the corresponding `_*_RE` / `_REF_PATTERNS` in
   `scripts/veo_lint.py` and repeat steps 2–3 until your known-good and known-bad
   prompts classify correctly.
5. Write down the known blind spots, so future-you reads the WARNs with the right
   scepticism.

## Known false positives

- A dialogue clip whose lines are phrased without `says:` / `dialogue:` → R1b misfires.
  Add a clear `Dialogue:` label, or accept the WARN.
- "door" used metaphorically rather than as a real environment change → dismiss R4.
- A prompt listing four nouns that are not actually reference *ingredients* → R3
  over-counts. Check the actual reference panel.

---

## What it does not check

The linter is text-shaped, so it cannot see the things that need a human or another
pass: continuity between clips
([`multiclip-continuity`](../multiclip-continuity/SKILL.md)), whether the framing
matches the emotional beat ([`cinematography`](../cinematography/SKILL.md)), or whether
the prompt will trip a content filter
([`docs/content-filters-and-policy.md`](../../docs/content-filters-and-policy.md)).
Run those separately.

