Maria Angelika Agutaya  ·  case study Video Ad Line · 2026-09-03

One brief in. Four gated video ads out. Nothing publishes itself.

Clientadd+ coffee, a real cafe I run in Calapan City My partThe whole line: spec, cost model, gates, review surface, the decisions StackClaude (research, angles, scripts), Higgsfield CLI (Veo 3.1 video, ElevenLabs voice), ffmpeg, Node, a vision gate on Claude This run4 finals, 89.2 credits, 9m 21s of paid wall time, 2026-09-03

The problem: video generation is cheap per clip and ruinous per batch. A line that renders first and checks later burns credits on scripts that were wrong at text cost.

What I built: a pipeline where every check that can run on text runs before a credit is spent, video renders last under a hard cap, and a human gate is the only way out.

The result: 4 finals from one brief for 89.2 credits (22.3 each), 1 held for revision, 2 approved, 2 exported in three ratios, 0 published.

The cost model

Text fails fast. Video renders last.

The order of the line is the budget. Research, angles, scripts, a claims check and an AI-tell scan all run at text cost. Only then does the run price the batch, compare it to the cap in code, and either refuse or spend. A script that invents a price dies before it can buy a clip.

SPEND PLAN: 4 videos x 22 = 88 credits + TTS (measured live, est <8). Cap 150. text gate: clean (claims + off-default copy-tells)
runs/run-addplus-sep/events.jsonl, the run's own log, 2026-09-03. The cap is a constant in line.mjs; the run refuses to start a batch that would cross it.
22 creditsper 8-second Veo 3.1 clip, preflighted with the CLI's cost command on 2026-09-03. The voiceover is a fraction of a credit.150the per-run cap. Over it, the run prints "over cap, refusing" and exits before the paid half.
Why the checkpoints matter as much as the cap

Every artifact under runs/<id>/ is a checkpoint: a voiceover, a raw clip, an assembled final. A file that exists is never re-billed, so a run that dies at clip three resumes at clip three. The one exception is deliberate: a checkpointed voiceover made before a rule existed must still pass that rule. A stale 10.2-second file once shipped a clipped last word, so the fit gate now re-measures old files and discards the ones over budget.

The line, as it ran on 2026-09-03

Eleven stages, one brief, no hand on the wheel until the end

Researchlive, cited, before any writing

Claude with web search, told to report only what a fetched page supports and to list what it could not establish. The gaps are the honest part: this run could not confirm the week's rotating drink, so no script may call a drink "this week's".

+ research.json: 11 cited findings, 8 gaps, 8 searches

Anglestwelve written, a critic keeps four

The critic scores thumb-stop, specificity, believability and novelty, then keeps four with four different mechanisms. This run it kept Identity-Coded Exclusion, Anchoring & Contrast, Common Enemy, Social Proof and killed the rest as one insight wearing different labels.

+ angles.json: 12 written, critic kept 4, running the top 2

The critic's reasoning, from angles.json

Angles 1, 2, 3, 7, and 9 are all the same 'weekly rotating menu' insight wearing different mechanism labels (curiosity, loss aversion, scarcity, liability inversion, novelty bias), they'd cannibalize each other in testing, so only the strongest survivor logic was needed and none scored high enough to beat the four kept. Angles 8, 11, and 12 are generic location/hours/local-pride copy with weak thumb-stop and low novelty, so they were cut outright. The keepers span four clearly distinct psychological levers, identity exclusion, contrast/anchoring, common-enemy framing, and social proof, while also being the highest scorers outside the duplicate cluster, giving a testable, non-redundant set.

Scriptshook, voiceover, video prompt

One script per angle per visual axis. The voiceover budget is 13 to 14 words this run, because a paid voice reads about two words a second and the clip is eight. The video prompt follows the synced Veo 3.1 spec: cinematography first, one named camera move, no on-screen text, no logos.

Text gatesclaims + AI-tell scan, exit 1 on failure

Every number and product name in the copy must appear in the brief or a cited finding. The copy is then scanned by off-default for AI tells. A failure exits before the spend plan.

text gate: clean (claims + off-default copy-tells) SPEND PLAN: 4 videos x 22 = 88 credits + TTS (measured live, est <8). Cap 150.

VoiceoverElevenLabs preset, measured, fitted

Rendered, measured with ffprobe, fitted with a bounded atempo, and if it still does not fit, the writer compresses it once. This run's voiceovers landed at 6.5s, 5.8s, 7.5s, 7.8s.

VideoVeo 3.1, 9:16, 8 seconds

Four clips, one per script, the model picked in a 42-credit bake-off against Kling 3 and Kling 3 Turbo on the same prompt. Veo won on light, product fidelity and condensation physics.

Assembleffmpeg, deterministic

Voiceover muxed, one quiet monospace brand line burned inside the platform safe zones, no hook text on the frame. Same inputs, same bytes.

Gatesassembly, then vision

Aspect, audio and duration by ffprobe. Then three frames of each final go to a vision gate with the product list and the design spec. A block lands the variant on the revision list.

revision list: 1 of 4 held back (a10-street)

The humanapprove, kill, or reject the batch

Nothing leaves without a decision. Rejecting the whole batch asks for a reason, and the reason is injected into every writer prompt on the rerun, so a rejection steers instead of deleting.

Exportthree ratios, one manifest

Approved variants copied out as 9:16, 4:5 and 1:1, with a manifest carrying per-variant cost and the reviewer's note. This run: 2 exported, 2 skipped with the reason recorded.

Ledgeracross runs

One row per run: brand, model, variants, how many the gates held, credits against the cap, and how the spend was measured. 5 earlier runs were backfilled from their manifests after this run, which is why the run's own log line below counts one.

spent 89.2 credits (cap 150), 22.3 per variant. manifest at runs/run-addplus-sep/manifest.json ledger: 1 runs, 89.2 credits on record ledger.json now: 6 runs, 446.6 credits on record

The proof

One real run, replayed from its own log

The paid half printed 28 lines over 9m 21s. The recording replays them in order with their real timestamps; only the render waits are compressed, and the frame says so. Then the reviewer's gate, driven live, and the four finals.

Captured 2026-09-03. The review decisions in the recording were made during the recording session and are labeled in-frame; nothing in it publishes.
What the recording is not

Not a staged run. The terminal segment is generated from runs/run-addplus-sep/events.jsonl, which line.mjs appends to on every printed line with a millisecond timestamp. A checkpointed replay would read "exists, skipped" on every line, so the recording is of a fresh brief with the critic and the live research both running.

The gates

A vision gate that reads the frame, and a design spec it reads against

The assembly gate is arithmetic. The vision gate is judgment: three frames of each final, the product list, and the on-video design spec, judged by Claude with an exit code. It exists because a plain iced coffee once shipped under a Biscoff Blueberry voiceover.

hook band 0.10h to 0.35h brand line, ends above 0.75h top 7% unsafe bottom 25% unsafe right 13% unsafe

design-specs/ad-design.md, synced from four 2026 safe-zone sources. The gate treats any burned text inside a shaded zone as a finding, not a preference.

{ "severity": "block", "what": "The advertised product is never identifiable. All three frames show only a plain white ceramic mug held at arm's length, tilted away from camera, with no visible beverage, color, foam, garnish or cup branding, nothing distinguishes it as Shaken Cinnamon Oat, Biscoff Blueberry or Ube Latte (an ube latte would read purple). This is a generic/unreadable product per the stated intent.", "where": "frames 0, 1, 2, mug in center-right of frame", "fix": "Reshoot or re-cut to include at least one clear, in-focus top-down or side shot showing the actual drink (ube's purple layering, Biscoff crumb/blueberry, cinnamon-dusted oat foam) before the walking POV shot." }
A real block from runs/run-addplus-sep/a10-street-vision.json. Brand: add+ coffee. The variant was held for revision and never reached approve.
What the revision list changes

Before this pass, a vision failure was recorded and nothing happened: the variant sat next to the passing ones with the same approve button. Now a blocked variant is held with its reasons, the approve control is disabled on the review surface, export skips it and writes why, and the ledger counts it. The reviewer still sees it, because the failure is information about the next batch.

Decisions on record

The model and the treatment were picked on evidence, then locked

Contact sheet of three frames each from Kling 3.0 Turbo, Kling 3.0, and Veo 3.1 rendering the same Ube Latte prompt
The bake-off, 42 credits. Same prompt, three models, three frames each. Veo 3.1 won on light, product fidelity and condensation physics, and the line switched the same day. Kling stays in the repo as the record of the choice.
Three caption treatments rendered on the same clean frame: A one quiet mono brand line, B editorial lower-third, C plum label chip
Three caption treatments on one clean frame. The first pass burned a hook in white with a black outline, the default every AI ad tool ships. Rejected. The three options were rendered on a raw frame, never on an already-captioned one, and Treatment A was locked: the voiceover and the footage carry the hook, one quiet brand line sits in the safe band.

The finals

4 variants, two angles, two visual axes, one run

Variants differ on named axes, never on a re-roll of the same prompt: a counter macro and a street walk per angle, recorded in the manifest, so distinctness is auditable. The decisions shown are the ones made in the recording session.

a5-counter · Identity-Coded Exclusion · counter axis Not for the plain-coffee crowd. Plain black coffee? add+ isn't for you. Try Ube Latte, see if you qualify. assembly gate pass · vision gate pass · voiceover 6.5s approved by the reviewer: hook lands, product reads
a5-street · Identity-Coded Exclusion · street axis Still ordering the same safe drink? Plain black coffee? add+ isn't for you. Try Ube Latte, see if you qualify. assembly gate pass · vision gate pass · voiceover 5.8s approved by the reviewer: keep, the walk sells it
a10-counter · Anchoring & Contrast · counter axis Pick your flavor lane now. Cinnamon Oat, Biscoff Blueberry, Ube Latte, three moods, one menu. Pick your lane. assembly gate pass · vision gate pass · voiceover 7.5s killed by the reviewer: VO promises three drinks, frame shows two mugs and neither is on the menu
a10-street · Anchoring & Contrast · street axis Three drinks, one perfect match. Cinnamon Oat, Biscoff Blueberry, Ube Latte, three moods, one menu. Pick your lane. assembly gate pass · vision gate FAIL · voiceover 7.8s

held for revision: vision: The advertised product is never identifiable. All three frames show only a plain white ceramic mug held at arm's length, tilted away from camera, with no visible beverage, color, foam, garnish or cup branding, nothing distinguishes it as Shaken Cinnamon Oat, Biscoff Blueberry or Ube Latte (an ube latte would read purple). This is a generic/unreadable product per the stated intent.

undecided
a5-counter exported at 4:5
4:5 export of a5-counter, center crop, brand line still inside the frame
a5-counter exported at 1:1
1:1 export of a5-counter, center crop, brand line still inside the frame

The export step writes each approved variant three ways and a manifest with the reviewer's note and the credits it cost. The files are named to upload; no ad account is connected, by design.

Where it stands

Measured in the files, 2026-09-03. Three of the runs on the ledger are fictional demo brands (Araw Botanicals, Gising!, Himbing) built to exercise the line; their spend was attributed from one batch, so the clean numbers below come from the add+ coffee runs only.

89.2

credits for this run, measured as the balance delta, 22.3 per final

6

runs on the ledger, 24 finals, 5 held for revision by the gates

178.4

credits across the 2 runs with a clean, single-run balance delta

11 / 8

cited findings and admitted gaps from live research, before a word was written

12 to 4

angles written to angles kept, four mechanisms, no near-duplicates

0

ads published by the line. Every batch stops at a human.

What did what

Claude wrote the research findings, the twelve angles and the critic's verdict, the scripts and the video prompts, and judged the frames in the vision gate. Veo 3.1 rendered the footage; ElevenLabs read the lines. I owned the spec and its locked decisions, the cost model and the cap, the gate order, the text gates, the on-video treatment, the review surface, the export, the ledger, and the verdicts. The brief is my own cafe, which is why the research gaps are real: the line could not find this week's drink because I had not posted it.

Maria Angelika AgutayaAI Engineer · mariaangelika.com · Video Ad Line, 2026