Engine decision after this research (2026-09-28): Gemini Omni is the only video model. Where this report routes shots to Veo 3.1, the engine uses Omni with the rules on the main page.
05 · Style engine: architecture, model routing and automatic 10/10 QC
Research for Lead Up's multi-style ad engine (vertical 9:16, 30-60 s, Tunisian Derja). Date: 2026-09-27. Scope: engineering of a "style engine" (any look, same script), model routing per shot, automatic quality control, creative testing and orchestration. Research only: no media generated, nothing spent.
Evidence tags: [official] Google/Meta docs or blogs · [paper] peer-reviewed or arXiv · [practitioner] blogs,
tool vendors, agencies · [ours] measured in this repo (ai-docs/03-lessons-learned.md) · [unverified] claim
seen once, or numbers with no traceable source · [proposal] my design recommendation.
Related earlier research (not repeated here): research/01-omni-prompting.md, 05-omni-pro-workflows.md,
06-nano-banana-2.md, 07-anti-ai-look.md, 08-hybrid-pipeline.md.
0. TL;DR
- Split the ad into three layers that never mix: a style-agnostic layer (script, VO, word timings, beat sheet,
"shot intents"), a style layer (a versioned style bible = data + reference images + per-model prompt fragments +
Remotion theme tokens + music/SFX recipe + QC thresholds), and a render layer (router → generators → judges →
Remotion). The same approved script then renders in any style by swapping one
style@versionpin. [proposal] - Shot intents, not shot prompts. The script produces semantic shots ("hook-macro: phone flooded with messages", "talking-head: installer answers", "data: 300 DT → 0"). A style adapter decides how each intent is made in each style (AI video, 2.5D still, or pure code). In 2D-flat or collage, most intents become code; in photoreal, most become Omni/Veo. [proposal]
- Style-locking is strongest at the still-image stage. Lock the look in one owner-approved style frame per
style, then make one first frame per shot from it (image-to-video inherits the look). Nano Banana 2 has no
dedicated style-reference slot (objects ≤10, characters ≤4); Nano Banana Pro has up to 3 style references
[official]. Use Pro for the style frame and for hard styles; NB2 for volume. Veo 3.1 accepts only asset
references (≤3, 8 s clips); style references exist only on
veo-2.0-generate-exp[official]. Omni takes style viain the style of <IMAGE_REF_0>and can restyle an existing clip while keeping its motion [official]. - Routing rule of thumb: Omni 1.1 Flash (4 s, 720p, $0.10/s) is the default AI-motion engine; Veo 3.1 Fast ($0.10/s at 720p) when you need subject references + native English/French dialogue or 8 s single takes; Veo 3.1 Standard ($0.40/s) only for hero photoreal shots; Veo 3.1 Lite ($0.05/s) for cheap atmospheric B-roll; code (Remotion) for every text, number, UI, map, logo, chart and for whole "graphic" styles. Derja lip-sync is not evaluated by Google on either model ("other languages not evaluated") [official]: use our TTS + a post lip-sync model, or avoid on-camera speech.
- "10/10" must be operational: all hard gates pass (deterministic checks: text correct, safe zones, loudness, colour range, no inserted cuts, no text in AI shots, luma, first frame lit) and the ad wins or ties a blind pairwise comparison against the style's "golden" ad, and a binary checklist judged by a VLM has no "no". VLMs rank far better than they score: pairwise judging reached 0.86 Spearman with human leaderboards vs 0.36 for pointwise scores (GenArena) [paper]; "VLM judges can rank but cannot score" [paper]. So: checklists for gates, pairwise for selection, never 1-10 scales for decisions.
- Best-of-N is cheap insurance, judging is cheaper still. One 4 s Omni take costs $0.40; judging it with Gemini 3.1 Pro at 8 fps/high resolution is about $0.02. With a 60 % pass rate, 3 takes give a 94 % chance of at least one pass. Gains from more samples converge (Video-T1) [paper]; spend the extra N on the hook (5-10 takes) not on filler.
- Styles are the cheapest real diversity for Meta. Meta's official guidance says diversify visuals/formats, messaging, storytelling and personas; Andromeda improved ads quality by 8 % and needs "more volume and diversity of creative" [official]. Ads that look alike are (per practitioners) grouped and compete as one; a style change is a genuinely different visual. Build concept = angle × style, variants = hooks/CTAs. [official + practitioner]
- Owner time ≈ 15 min per ad is realistic with 4 gates: script OK, style pick (from style cards, amortized), picks strip (optional), final phone watch. Everything else is automatic, logged, cached and cost-capped. [proposal]
1. Style system design
1.1 What the three layers contain [proposal]
LAYER A (style-agnostic, approved once per ad)
brief.md → script.md (Derja, linted, owner OK) → VO takes → align.json (word times)
→ beats.json (beat sheet: 8-10 beats, each with message + on-screen facts + CTA)
→ intents.json (25-35 shot intents: semantic type, subject, action, facts shown, duration window, importance)
LAYER B (style, reusable across ads; versioned)
library/styles/<style_id>/
style.yaml the style bible (data, section 1.2)
theme.ts / theme.json Remotion tokens (colours, fonts, springs, transitions, grain, LUT, caption preset)
frames/style_frame.png, palette_card.png, texture_swatch.png, golden/*.png (owner-approved stills)
golden_ad.mp4 the best finished ad in this style (pairwise anchor for QC)
prompts/nb2.j2, omni.j2, veo.j2, lyria.j2, tts_direction.txt
adapters.yaml intent type → recipe (engine, template, refs, N takes, trim rules)
qc.yaml thresholds (style similarity floor, luma range, cut rate, judge checklist additions)
library/characters/<char_id>/spec.yaml (style-neutral: age, build, wardrobe, colours, features)
/<style_id>/sheet.png (turnaround in that style; generated once, approved once)
library/worlds/<world_id>/spec.yaml + /<style_id>/plates/*.png (rooftop Tunis, blue door, living room…)
LAYER C (render, per ad × style)
router → keyframes (NB2/Pro) → motion (Omni / Veo / 2.5D / code) → judges → picks.json
→ timeline (VO anchors fixed, beat grid of THIS style's music) → Remotion(theme) → master → QC → publish
Why this split matters:
- The VO and word timings are shared by every style, so re-styling never re-records the voice. Music changes per
style, so the beat grid (and therefore exact cut points) is recomputed per style; this is a cheap local step
(pipeline/timeline.py).
- Characters and worlds are defined twice: once as neutral text specs (so a clay installer and a photoreal
installer are "the same person"), once per style as an approved sheet. Identity references cannot cross styles: a
clay sheet used as a reference for a photoreal shot drags the output toward clay.
- Intents make routing a table lookup rather than a prompt-writing session each time.
1.2 The style bible as data (schema) [proposal, fields justified by the sources in §1.3-1.5]
id: clay3d # stable slug; used in ad names and manifests
version: 1.3.0 # semver: major = look change (re-approve golden), minor = prompt tweak, patch = typo
family: 3d # photoreal | cinematic | ugc | 3d | 2d | anime | collage | kinetic-type
status: approved # draft | approved | retired
cost_class: ai-heavy # ai-heavy | mixed | code-only (drives budget estimates)
look: # words for AI prompts: NEVER hex codes in video prompts (Omni prints them) [ours]
medium: "hand-made plasticine claymation, visible thumbprints, matte surfaces"
palette_words: "chalk-white (pure white, never green or yellow), terracotta, Tunisian blue, warm sand"
palette_hex: {bg: "#F4EFE6", accent: "#1E6FD9", warm: "#C8643B"} # for Remotion + ΔE checks only
lighting: "one soft key light from 10 o'clock, gentle fill, soft contact shadows, no rim glow"
lens_camera: "35mm equivalent, eye-level, shallow but not creamy depth of field, locked-off or slow dolly"
texture: "fine clay grain, slight fingerprints, no plastic sheen"
line: null # 2D styles: "uniform 6 px ink outline, flat fills, no gradients"
composition: "subject off-centre on thirds, 25% negative space top for captions band"
semantic_negatives: # described positively (Google advice) + our measured failures
- "surfaces are matte; the air is clear, with no bokeh balls, sparkles, lens flares or glow"
- "the image contains no letters, numbers, logos or words anywhere"
- "never copy any word from a reference image"
dont: ["centred hero with glow", "rainbow gradients", "hyper-detailed skin pores"]
motion:
ai_motion_words: "stop-motion feel, snappy holds, objects squash on impact, already moving at frame one"
camera_words: "locked-off, then a short push-in"
forbidden_motion: "no floaty drift, no slow settle at the end"
code_feel: snappy # maps to Remotion spring presets in theme.ts
target_cut_s: [1.2, 2.0]
transitions_allowed: [hard-cut, whip, match-cut]
frame_step: 1 # 2 = animate on twos (stop-motion / collage feel) for code layers
type_and_captions:
caption_preset: owner-outline # owner rule: thick black outline captions (global unless the owner changes it)
display_font_ar: "Cairo ExtraBold"
latin_font: "Inter Black"
type_motion: "pop-in 6 frames, overshoot 8%"
audio:
lyria_prompt: "playful pizzicato and marimba, bouncy, 116-122 BPM, clear downbeats, no vocals"
sfx_palette: [squish, pop, clay-thud, soft-whoosh]
vo_direction: "warm, energetic, smiling" # Gemini TTS style prompt; same words, different delivery
grade: {lut: clay_warm.cube, grain: 0.02, vignette: 0.1}
references: # every reference has ONE job (practitioner rule; Google role tags)
- {file: frames/style_frame.png, role: style, note: "match rendering, palette, light; ignore content"}
- {file: frames/texture_swatch.png, role: style, note: "surface texture only"}
routing_overrides: # optional: per intent type
talking-head: {engine: omni, lipsync: none, framing: "over-shoulder or hands, mouth off-camera"}
qc:
style_sim_min_z: -1.0 # CSD similarity vs golden set, as z-score of in-style distribution (§3.5)
luma_yavg: [90, 190]
judge_extra_checks: ["no surface looks glossy or plastic", "no photographic skin texture"]
golden_ad: golden_ad.mp4
changelog: ["1.3.0 2026-09-27 chalk-white wording, removed 'soft glow'"]
Design notes:
- Words for models, hex for code. Omni wrote "#EF4444" on screen when given hex codes [ours]; Remotion and colour
checks need exact hex. Keep both in the bible.
- Semantic negatives. Google: "describe what you wish to exclude" as a positive scene description, e.g. "a
desolate landscape with no buildings or roads" rather than "no man-made structures" [official, Veo guide]; the Gemini
image guide calls them "semantic negative prompts" [official].
- Version everything. A style is a product: changing the lighting sentence is a new version, and an ad manifest
pins clay3d@1.3.0. That is what makes a winning ad reproducible months later.
- cost_class lets the planner mix styles for Meta diversity without blowing the budget (a kinetic-type or
2d style can be ~$0-3 of AI per ad; see §2.6).
1.3 Style-locking in Nano Banana 2 / Pro (keyframes, sheets, plates)
Facts [official]:
- NB2 (gemini-3.1-flash-image, GA): up to 14 inputs; up to 10 high-fidelity object images and up to 4 character
images; no style-reference category. NB Pro (gemini-3-pro-image): up to 6 objects, 5 characters, 3 style
references. NB2 Lite: 1K only. Price per 2K image: NB2 $0.101, Pro $0.134. Thinking level minimal/high.
(Tables and URLs in research/06-nano-banana-2.md §1.)
- Google's templates: "Describe the scene, don't just list keywords"; style transfer template "Transform the provided
photograph of [subject] into the artistic style of [style]"; multi-image template "Take the [element 1] and place it
with [element 2]"; inpainting "Change only the [element]… Keep everything else unchanged"; control the camera with
photographic language (85 mm, macro, Dutch angle) [official].
Practitioner consensus: start with 2-4 references and give each a role; "the reference image carries identity while the prompt carries everything else"; do not assume the model matches the reference's style by default, restate it [practitioner]. Measured by us: 3-4 parallel calls with 4 refs is the safe rate; always set an HTTP timeout; it copies words from references unless told not to; "one 2K first frame per shot" beat contact-sheet panels (16/16 usable) [ours].
Recommended lock recipe per style [proposal]:
1. Style frame (once per style, owner-approved): NB Pro at 2K, with 1-3 style refs (mood images the owner
supplied or earlier golden frames) + the style bible's look paragraph. Output: one hero still that defines
medium, palette, light, texture. Also a palette card and a texture swatch cut from it.
2. Character sheets per style: NB2 (or Pro) with the style frame as a reference ("match the rendering of image 1
exactly; image 1's content is irrelevant") + character spec text → turnaround (front, 3/4, profile, hands).
3. Per-shot first frames: NB2 2K, references = [style frame, character sheet(s), plate or prop], prompt =
verbatim style block + shot intent rendered as a scene description + semantic negatives. Same template for every
shot of every ad in that style.
4. Style QC before any video money: CSD style similarity vs the golden set (§3.5) + a VLM checklist (no text,
right palette, right light) + owner sees one contact sheet. Re-generate outliers only.
5. Seeds: the Gemini config accepts a seed, but image/video generation is not guaranteed deterministic (Veo docs
say seed "slightly improves" determinism) [official]. Reproducibility = keep the outputs (content-addressed
cache), not re-running a seed.
1.4 Style-locking in Omni and Veo (motion)
Omni 1.1 Flash [official, details in research 01/05]: 3-10 s, 24 fps, 9:16, 720p default (1080p/4K are upscaled),
reference tags <FIRST_FRAME>, <LAST_FRAME>, <IMAGE_REF_n>, <VIDEO_REF_n> (≤3 video refs ≤3 s, audio ignored),
style through the prompt ("in the style of gemini-omni-1.1-flash-preview on global only [ours]; the Gemini-API id
gemini-omni-1.1-flash is GA since 2026-08-27 [practitioner report of the release].
Veo 3.1 [official]: 4/6/8 s; 720p default, 1080p, 4K; 8 s mandatory for 1080p, 4K, reference images and
first/last frame; up to 3 asset reference images (person, character or product); style reference only on
veo-2.0-generate-exp; extend +7 s up to 20 times (148 s total, 720p only; not on Lite); native audio with dialogue in
quotes, SFX: and Ambient noise: lines; timestamp prompting [00:00-00:02] … for multi-shot; seed only "slightly
improves" determinism; 16:9 and 9:16; videos kept 2 days on the server; SynthID. Lite has no reference images and no
extension [practitioner, consistent with docs].
Lock recipe [proposal]:
- Image-to-video is the style lock. A first frame made in step 1.3.3 carries the style; the video prompt carries
motion only ("motion-only prompt", our rule 4) plus a fixed 1-sentence style phrase repeated verbatim in every
shot of the style (practitioner rule: "one fixed style phrase for every scene").
- Add the style frame as <IMAGE_REF_0> with the role spelled out ("use only for rendering style, palette and
light; do not copy its content"), and the character sheet as <IMAGE_REF_1>. Use exclusion language for every
reference (practitioner).
- Camera language from a fixed vocabulary in the bible (Google lists: dolly, tracking, crane, aerial, slow pan,
POV; wide, close-up, extreme close-up, low angle, two-shot; shallow DoF, wide-angle, macro; Omni adds push in, punch
in, dolly zoom, locked off, "oner", smartphone zoom, webcam style) [official]. Styles restrict it: UGC = handheld
smartphone, slight shake; cinematic = dolly/crane, anamorphic feel; collage = locked-off.
- Restyle for multi-style hero shots: make the choreography once (in the cheapest style or a grey-box Remotion
animatic), then Omni-restyle into each style. Same motion and timing across styles, so the same cut list works.
Costs one extra generation per style; quality of restyle on our content is untested [proposal, to test].
- Colour lock in post: one grade (LUT) and grain per style in Remotion/ffmpeg over all AI shots; this hides small
per-clip drift (research 07).
1.5 Style-locking in Remotion (code layers)
Remotion props flow: defaultProps → inputProps override at render → calculateMetadata() can compute duration
and other metadata asynchronously (e.g. from timeline.json); props can be validated by a schema (zod) and edited in
Studio [official]. So [proposal]:
- theme.json per style validated by a zod schema: colour tokens (bg, fg, accent, caption fill/outline), fonts per
script (Arabic display/body, Latin), type scale, stroke widths, corner radii, shadow model (none / hard offset /
soft), spring presets (snappy, bouncy, heavy: damping/stiffness/mass), easing curves, allowed transitions,
frameStep (animate on twos for stop-motion/collage), grain and LUT, caption preset.
- Scenes read only tokens, never literal colours or fonts. Rendering the same ad in a new style is
npx remotion render … --props=ads/<slug>/render_<style>.json.
- Code-only styles (kinetic type, 2D flat, infographic, collage from NB2 cut-outs) then cost almost nothing to add.
- Owner's caption rule (thick black outline) stays global; the theme may only change the font within the rule.
1.6 Starter style catalogue (what each needs) [proposal]
| Style | Main engine | AI $/45 s ad (est.) | Key risks | Notes |
|---|---|---|---|---|
| 3D clay (current) | NB2 frames → Omni i2v | ~$15-18 | glossy plastic look, glow creep | Already proven [ours] |
| Photoreal cinematic | NB Pro style frame, NB2 frames → Omni; Veo Std for 1-2 heroes | ~$18-30 | hands, faces, uncanny motion, Tunisian locations wrong | Needs strongest artifact QC |
| AI UGC (phone selfie) | NB2 "phone photo" frames → Omni/Veo; lip-sync post step | ~$15-25 + lip-sync | Derja lip-sync, "plastic" skin, over-clean light | Honest framing only: no fake testimonials (§4.5) |
| 2D flat vector | NB2 flat assets (alpha via diff-matte) + Remotion rigs | ~$2-5 | AI frames drift to 3D shading | Mostly code; very cheap diversity |
| Anime / cel | NB Pro style frame, NB2 frames → Omni | ~$15 | drift to 3D, face inconsistency | Anime forgives motion errors |
| Paper collage / cut-out | NB2 cut-out elements + Remotion on twos, paper texture | ~$2-6 | AI video can't do stepped timing well | Code is better than AI here |
| Kinetic typography | Remotion only (+ Lyria) | ~$0.1 | readability of Arabic | Zero AI video; strongest control |
| Cinematic 2.5D | NB2 plates + Depth Anything parallax | ~$2-4 | stretched edges | Research 08 §3 |
2. Model routing per shot type
2.1 Capability and price sheet (2026-09)
| Omni 1.1 Flash | Veo 3.1 Standard | Veo 3.1 Fast | Veo 3.1 Lite | Code (Remotion) | |
|---|---|---|---|---|---|
| Clip length | 3-10 s; extend to 40 s | 4/6/8 s; extend to 148 s (720p) | same as Std | 4/6/8 s, no extend | any |
| Resolution | 360p, 720p native; 1080p/4K upscaled | 720p, 1080p, 4K | 720p-4K | 720p (1080p priced) | 1080×1920 exact |
| Price /s | 360p ~$0.034 · 720p $0.10 · 1080p ~$0.152 · 4K ~$0.304 | $0.40 (720p/1080p) · $0.60 (4K) | $0.10 (720p) … $0.30 (4K) | $0.05 (720p) · $0.08 (1080p) | $0 (CPU) |
| Image refs | many (docs inconsistent: 5-10); style via prompt | ≤3 asset refs, 8 s only | ≤3 asset | none | n/a |
| Video refs | ≤3 × ≤3 s (motion/likeness) | no | no | no | n/a |
| First/last frame | yes (we use first only) | yes (8 s) | yes | yes | n/a |
| Restyle/edit clip | yes (≤10 s input) | edit exists on Vertex | n/a | ||
| Native audio | yes, always (music creeps in) | yes, dialogue + SFX + ambience | yes | yes | our SFX kit |
| Dialogue/lip-sync | English only evaluated | best of the family; non-English "not documented" | n/a | ||
| Arabic text in frame | no (invents garbled Arabic) [ours] | poor (subtitle problem) | exact | ||
| Batch discount | none | ||||
| Sources: Gemini API pricing page (Veo tiers, Omni $17.50/M video tokens = 5,792 tok/s at 720p ≈ $0.10/s) [official]; | |||||
| Omni per-resolution figures from an analyst breakdown [practitioner]; Omni specs from the API doc [official]; Veo specs | |||||
| from the Veo doc [official]; reference types from the Vertex references doc (search excerpt) [official]. |
Not available: no "Veo 4" exists as of September 2026; Google shipped Omni instead [practitioner, several trackers].
2.2 Routing table by shot intent [proposal]
| Shot intent | Default route | Fallback / upgrade | Takes N | Why |
|---|---|---|---|---|
| Hook (0-2 s) visual | Omni i2v 4 s from NB2 2K frame, trim to 0.8-1.5 s | Veo 3.1 Fast 4 s i2v | 5-8 | Highest leverage; selection matters most |
| Product/object hero, physics | Omni i2v 4 s | Veo Std 8 s 1080p for the 1 hero | 3 | Omni good at physical motion; Veo Std for flagship |
| Character action, no speech | Omni i2v + <IMAGE_REF> sheet |
Veo Fast 8 s with ≤3 asset refs | 3 | Reference-driven identity |
| Talking head in Derja | Our TTS VO + Omni/Veo performance with mouth hidden or off-camera (hands, over-shoulder, phone POV) | Omni/Veo take "speaking silently" → post lip-sync to our VO (lipsync-2-pro or LatentSync) | 3 + lip-sync | Neither model is evaluated for Arabic; our VO is the approved voice |
| Talking head FR/EN line | Veo 3.1 Std/Fast with dialogue in quotes | 3 | Best native lip-sync (~80 % single speaker, practitioner) | |
| Continuous move > 10 s | Omni extend (≤40 s) | Veo extend (720p) | 2 per link | Extension keeps momentum; avoid F/L chaining (research 05) |
| Same shot in several styles | Omni restyle of one master take | per-style i2v | 1-2/style | Keeps timing identical across styles |
| Atmosphere B-roll (sky, street, texture) | Veo 3.1 Lite 720p 4 s ($0.20) | Omni 720p | 2 | Cheapest acceptable motion |
| Camera move over a still | 2.5D parallax (Depth Anything V2 + Remotion) | Omni | 0 | Crisp, free, no wobble (research 08) |
| Text, numbers, UI, chat bubbles, counters, maps, charts, logo, end card, captions | Remotion | never AI | 0 | Exact; AI prints hex codes and fake Arabic [ours] |
| Graphic styles (2D, collage, kinetic) | Remotion + NB2 assets | Omni for 1-2 organic moments | 0-2 | Stepped timing and exact shapes are code strengths |
Router logic (pseudo) [proposal]:
engine = style.adapters[intent.type].engine # style decides first
if intent.has_text_or_numbers: engine = "remotion" # hard rule
if intent.speech_lang == "ar-TN": engine += "+lipsync" or reframe to hide mouth
if intent.needs_subject_refs and engine == "veo": duration = 8 # Veo refs force 8 s
if intent.importance == "hook": N = style.qc.hook_takes (5-8) else N = 3
if budget.remaining < estimate(engine,N): downgrade (Veo Std→Fast→Omni→2.5D) and log it
2.3 Upscaling and frame rate
- Omni 1080p/4K are upscales billed at 1.5×/3× [official/practitioner]. For a 1080×1920 feed ad, 720p→1080p is a 1.5× scale; Meta recompresses anyway. Use Omni 1080p only on hero shots with fine detail [proposal].
- Local options: Real-ESRGAN (
realesr-animevideov3for flat/2D) (research 04); SeedVR2 (Apache-2.0, one-step video restoration, ICLR 2026) needs an H100 for 720p×100 frames and its README warns it "tends to overly generate details" on lightly degraded inputs such as 720p AIGC videos [official repo]. Topaz (commercial) was used by Secret Level on Coca-Cola (research 07). - Frame rate: Omni is 24 fps, our composition 30 fps. Do not interpolate AI shots (warps); use RIFE only for deliberate slow-motion ramps. Consider a 24 fps master for AI-heavy styles to avoid pulldown judder [proposal; test].
2.4 Budget per style variant (45 s ad, ~28 shots, ~12 AI) [proposal, prices §2.1]
| Item | Calc | $ |
|---|---|---|
| NB Pro style frame (once per style, amortized) | 3 × $0.134 | 0.40 |
| NB2 keyframes | 14 × $0.101 (+30 % re-gens) | 1.8 |
| Omni takes | 11 shots × 3 × 4 s × $0.10 + hook 1 × 8 × 4 s × $0.10 | 16.4 |
| Judges (Gemini 3.1 Pro/3.x Flash) | ~45 clips + ~20 stills + final | ~1.5 |
| Lyria bed, TTS | < 0.2 | |
| Total AI-heavy style | ≈ $20 | |
| Code-heavy style (2D/collage/kinetic) | NB2 assets + 0-2 Omni shots | ≈ $1-5 |
| Extra hook variant (same body) | 1 shot × 6 takes × 4 s × $0.10 + Remotion | ≈ $2.5 |
Our real solar v2 cost ≈ $15 [ours], consistent with this.
3. Quality at 10/10, automatically
3.1 What the research says about automatic judges
- Pairwise beats pointwise. GenArena: pointwise VLM scoring has "stochastic inconsistency" and only 0.36 correlation with the LMArena leaderboard; pairwise raises accuracy by over 20 % and reaches 0.86 Spearman; with pairwise, open models beat top proprietary judges used pointwise [paper].
- "VLM judges can rank but cannot score." Rankings can be right while absolute scores are unreliable; reliability depends more on task definition and annotation quality than on the judge; use pairwise when uncertainty is wide; one strong judge beats multi-judge fusion there [paper].
- Rubric + pairwise for video. RAVEN-Eval uses task-specific rubrics and pairwise LMM preference over 4,500 videos from 20 models, 13 judges tested, with anchor-based insertion of new models to save cost [paper].
- LLM-judge biases (position, verbosity, self-enhancement) are mitigated by swapping order, few-shot examples, chain-of-thought and reference-guided judging; strong judges reach >80 % agreement with humans, the same as human-human [paper, MT-Bench].
- Learned video reward models: VideoScore2 (Qwen2.5-VL-7B, scores visual quality, text alignment and physical/common-sense consistency with rationales, used for best-of-N) [paper]; VisionReward (29 weighted dims) and VideoScore used as verifiers in Video-T1, where more samples "consistently" improved quality up to a convergence limit, and a mixture of verifiers helped [paper]. Image preference: HPSv3 (Qwen2-VL, MIT, 76.9 % preference accuracy vs 65 % for HPSv2/PickScore) [official repo]; aesthetics: LAION Aesthetic Predictor v2.5 (SigLIP, 1-10, "5.5+" = great, covers illustrations; AGPL-3.0) [official repo]; Q-Align (LMM with text-defined levels) [paper].
- Artifact detection with few labels: ArtifactLens detects distorted hands, warped objects, anatomy and interaction errors with "only a few hundred labeled examples per artifact category" using a VLM with in-context examples [paper]. Hands are much better in 2025-26 generators but still fail [practitioner].
- Style similarity: CSD (Contrastive Style Descriptors) embeds style separately from content [paper]; raw CSD cosine fails (hubness), so calibrate against reference sets and set thresholds per context [paper].
- Our own measurement: Gemini's "accent score" is useless (always 5/5); its transcript is reliable for wrong or missing words; its picture opinions are advisory [ours].
3.2 Gemini as judge: frame sampling and cost [official]
- Default video sampling is 1 fps, which "may miss" fast action; set a custom
fpsin the video metadata; clip withstart_offset/end_offset; up to 10 videos per request (Gemini 2.5+), which enables pairwise in one call; timestamps in MM:SS; put the text prompt after the media. - Gemini 3 tokens: images
low280,medium560,high1,120,ultra_high2,240; video frames 70 tokens at low/medium, 280 at high ("high" needed for OCR/small details); per-part resolution is Gemini-3-only. - Cost example: judging two 4 s takes at 8 fps, high: 2 × 32 frames × 280 = ~18k tokens ≈ $0.04 on Gemini 3.1 Pro ($2/M input) or ≈ $0.014 on 3.x Flash ($0.75/M through 2026-12-31). Generating those two takes cost $0.80. Judging is ~5 % of generation cost.
3.3 The rubric: hard gates (deterministic) + checklist (VLM) + pairwise (VLM) [proposal]
"10/10" = every hard gate passes, every checklist item is "yes", and the ad wins or ties the style's golden ad in a blind pairwise judgment (both orders). Owner's phone watch is the final gate.
A. Hard gates (code, no model opinion)
| # | Dimension | Check | Tool | Threshold |
|---|---|---|---|---|
| A1 | Hook | frame 0 lit and readable; first visual change ≤ 0.5 s; VO or hook text starts ≤ 0.3 s | signalstats YAVG on frame 0; scene/motion diff; align.json | YAVG(frame0) ≥ 90; change ≤ 15 frames |
| A2 | Text correctness | every on-screen string equals the approved string, char by char; RTL order by pixel position | Remotion props diff + OCR on stills (Gemini high-res OCR) | 0 differences [ours] |
| A3 | Readability | text height and dwell | Remotion layout metrics | Arabic cap ≥ 56 px at 1080 w; dwell ≥ 0.4 s + 0.25 s/word; contrast ≥ 4.5:1 |
| A4 | Safe zones | nothing essential in Reels UI overlays | bounding boxes from Remotion | top 14 % and bottom 35 % clear (our rule: top 270 / bottom 670 px) [practitioner] |
| A5 | No text in AI shots | zero glyphs in any AI clip | OCR (Gemini or PaddleOCR, Arabic+Latin) on 2 fps frames | 0 detections [ours] |
| A6 | No inserted cuts in the used segment | shot boundary | PySceneDetect / pipeline/alarm/cuts.py |
0 in kept range [ours] |
| A7 | No frozen/black frames, no flicker | ffmpeg freezedetect, blackdetect, luma delta per frame |
none; | |
| A8 | Edit rhythm | cuts on beats/words; mean shot length | timeline.json | 100 % cuts within ±1 frame of beat or word; mean 1.2-2.0 s |
| A9 | Seam energy | no clip ends on a "settling" still | optical-flow magnitude in the last 6 frames before each AI cut | ≥ 40 % of the clip's median flow [proposal] |
| A10 | Audio loudness | ffmpeg ebur128 |
−14 ±1 LUFS integrated, ≤ −1.5 dBTP [ours] | |
| A11 | VO intelligibility | transcript vs script | Gemini transcript (WER) + keywords | WER ≤ 5 %, all keywords present [ours] |
| A12 | Mix | VO over music | loudness per stem | music −12 to −18 LU under VO while speaking |
| A13 | Technical | container/colour | ffprobe | 1080×1920, 30 (or 24) fps, H.264 High, yuv420p, color_range=tv, BT.709, AAC 48 kHz [ours] |
| A14 | Brightness | whole film | signalstats | mean YAVG 90-190 [ours] |
| A15 | Brand + CTA | logo on end card ≥ 1.5 s; CTA said and shown in the last 5 s; brand named by 3 s (if the concept allows) | timeline + props | present |
| A16 | Style drift (stills) | CSD similarity to golden set | CSD embedding, z-score vs in-style distribution | z ≥ qc.style_sim_min_z (calibrate) |
| A17 | Compliance | claims match brief facts; no fake testimonial/review; AI-disclosure need recorded | brief facts list, human | pass |
B. VLM checklist (binary items; Gemini 3.1 Pro; each "no" needs a timestamp)
Per AI shot: identity matches sheet · hands (5 fingers, no fusion) · faces stable (no melting, eyes aligned) · objects
keep shape (no morphing) · physics plausible · no glyph-like marks · on-style (bible's look + judge_extra_checks) ·
intent fulfilled (the action in the intent happens in the kept segment) · no "AI tells" from research 07 (glow,
bokeh, sparkles, waxy skin).
Per ad: hook creates a question or surprise in 2 s · message understood with sound off · every beat's fact visible ·
product/offer clear · CTA explicit · pacing never drags (flag any 0.7 s+ of dead air) · music mood fits the style ·
SFX on visible impacts · nothing looks unintentionally AI.
C. Pairwise (selection and the final bar)
- Take selection: round-robin among N takes of a shot, both orders; winner = most wins; ties → deterministic
tiebreaker (higher motion energy at the trim point, then fewer checklist warnings).
- Ad-level bar: new ad vs golden_ad.mp4 of the same style, both orders, rubric in the prompt. "Win or tie in both
orders" = pass. A new winner can become the new golden ad after owner OK (a ratchet).
3.4 Making the judge reliable [proposal, grounded in §3.1]
- Deterministic checks first, VLM second: cheaper and never hallucinate. Reject before paying the judge.
- Binary questions with evidence, structured JSON output (
{item, pass, timestamp, evidence}); reject any "fail" without a timestamp and any "pass" on an item the judge could not see (e.g. hands not in frame = n/a). - Pairwise, both orders, temperature 0-low; disagreement between orders = tie → escalate (third call at higher fps or to the owner's picks strip).
- Few-shot from our own defect library: 1-2 labeled frames per failure (inserted cut, hex code text, garbled Arabic, green "lime-white", glossy clay…). ArtifactLens shows a few hundred labels per category are enough for a strong VLM detector; we can start with 10-20 per category.
- Sampling that fits the failure: 8-10 fps and
highmedia resolution for 4 s takes (morphs and hands happen between 1 fps samples); 1-2 fpslowfor whole-ad pacing reviews. - Calibrate against the owner. Label ~150 past takes (keep/reject + reason; we already have v1/v2/alarm takes and
picks.json). Automate a gate only if judge-owner agreement is high (Cohen's kappa ≥ 0.7); otherwise keep it advisory. Re-check each quarter and whenever a model id changes. - Self-preference: Gemini judging Gemini output. Pairwise among same-model takes cancels most of it; for the final ad, add a cross-vendor second opinion on stills (e.g. Claude) as advisory.
- Track judge vs market: correlate judge scores with hook rate/CPL (§4.4). If the judge prefers ads the market rejects, change the rubric, not the market.
3.5 Style-consistency metrics [proposal]
- Per style, a golden set of 20-50 approved frames. Compute CSD embeddings; store the in-style similarity distribution (mean/std of golden-to-golden cosine) and an out-of-style distribution (golden vs other styles). Gate new frames on the z-score, not raw cosine (the CSD failure paper) [paper].
- Palette ΔE: k-means (k=5) dominant colours vs
palette_hex; flag if the top-3 colours are > ΔE 15 from any palette colour (for photoreal, check only white balance/saturation band). - Identity: for stylized characters, the VLM checklist against the sheet (face embedding models are photo-trained; InsightFace models are non-commercial licensed, so avoid them for a paying agency).
- Aesthetic floor (advisory): LAION v2.5 ≥ 5.5 or HPSv3 relative ranking within a batch. Licenses: v2.5 is AGPL (fine as an internal tool, not distributed); HPSv3 MIT.
3.6 Best-of-N strategy and costs [proposal]
- P(at least one pass in N) = 1 − (1−p)^N. With p = 0.6: N=2 → 84 %, N=3 → 94 %, N=5 → 99 %. Expected cost per usable 4 s Omni shot ≈ $0.40 / p = $0.67.
- Sequential sampling: generate 2 in parallel, run gates + judge; generate the 3rd only if none passes or the pair is a near-tie. Hook: 5-8 in parallel from 2 different first frames (framing diversity beats seed diversity).
- Diagnose then repair: a failed take's checklist output drives a targeted prompt edit (e.g. "hands out of frame", "static camera", "stop before the cut") instead of blind re-rolls. After 2 failed repairs, change the intent route (e.g. to 2.5D or code) (practitioner rule from research 05: stop after 2 failed joins).
- Video-T1: returns from larger N converge; gains per model 1.6-5.9 % on benchmarks; tree search saves ~69 % compute but needs model internals, so for API models use linear best-of-N with early rejection [paper].
4. Creative testing and learning loops
4.1 What Meta says (official)
- Andromeda (Dec 2024) is the retrieval engine for Advantage+; +6 % recall and +8 % ads quality on selected segments; built for "exponential growth in volume of eligible ads" as GenAI tools let 1M+ advertisers create 15M+ ads a month [official, Meta engineering].
- "The Creative Advantage" (Meta for Business): Andromeda needs "more volume and diversity of creative"; diversify themes and messages, visuals, audio, copy; an example advertiser went from 3-4 new creatives a week to ~50 [official].
- "Demystifying creative diversification": diversification = "distinct campaign assets tailored to different personas or use cases", as opposed to iteration (small A/B tweaks). Dimensions: visuals and formats, messaging, storytelling, audience personas. Use Creative Insights to spot similarity and fatigue. Meta image-generation features: +11 % CTR, +7.6 % CVR [official].
4.2 What practitioners add (treat numbers with care)
- Similar ads are grouped (the "Entity ID" idea) and compete as one in retrieval; different visual style, format, angle and talent make distinct entities; small text changes on the same visual do not [practitioner, no primary Meta doc found].
- "Creative Similarity Score" thresholds (below 40 %, suppression above 60 %) circulate on many blogs with no traceable Meta source [unverified]; do not build on them.
- Structures: 8-12 distinct concepts per campaign, 2-3 variants each; one ad set with many diverse creatives beat five small ad sets by 17 % on conversions (Logical Position, via Segwise); 50 % new concepts / 30 % variants / 20 % proven; 2-3 week fatigue cycle; watch CTR −10 % WoW, CPA +15 % WoW, frequency > 3 [practitioner].
- Angle hierarchy: angle decides the argument, hook is the entry, claim pays it off, format shapes attention, CTA closes; a library should cover problem-agitation, social proof, transformation, comparison, demonstration [practitioner].
- Reels: hook in the first 3 s, sound-on native, 9:16, keep critical content out of the top 14 % and bottom 35 % [practitioner summaries of Meta specs].
4.3 The variant matrix for Lead Up [proposal]
- Concept = angle × style. Angles for solar installers (example): money burned on Boost; speed-to-lead (call in 5 min); risk reversal (0 DT until you sell); proof (calendar filling); comparison (agency vs doing it yourself).
- Variants inside a concept = hook × CTA (swap only the first 1.5-3 s and the last 3 s; the body is reused, so cost is ~$2.5 per hook variant).
- Launch pack per client (small Tunisian budgets): 3 angles × 2 styles = 6 concepts, + 2 extra hooks on the best 2 = 10 ads, all in one ad set. Styles alternate across angles so no two concepts share both angle and style. Code-only styles make the second style nearly free.
- Do not run full factorials: Tunisian SMB budgets cannot reach significance on dozens of cells. Let delivery pick, and read results by feature across ads (§4.4), not by cell.
4.4 Naming, tracking and the learning loop [proposal]
Ad name (parsable, like Motion's DATE_FORMAT_HOOK_ANGLE parsing):
LU_{client}_{offer}_{concept}_{angle}_{style}@{ver}_{hook}_{cta}_{len}s_{yyyymmdd}
LU_SOLARTN_PAYONSALE_C03_riskrev_clay3d@1.3_H2-priceflood_WA-SOLAR_45s_20260927
The same fields live in ads/<slug>/manifest.json (plus model ids, prompt template versions, costs, QC results), so
ad name ↔ manifest is a join key. Motion-style AI tagging (visual format, messaging angle, hook, talent, product,
…) can be replicated by running a VLM tagger over every exported ad and storing tags next to the manifest
[practitioner: Motion tags 8 dimensions].
Loop:
1. Pull per-ad daily metrics (Marketing API insights): impressions, 3 s views (hook rate = 3 s views /
impressions), ThruPlays (hold rate), CTR, cost per lead / per WhatsApp conversation, and the qualified-lead
outcome from Lead Up's CRM (the real target).
2. Join on ad name → manifest features: style, angle, hook type, first-frame brightness, face in first second,
cut rate, text density, music BPM, QC scores.
3. Model small data honestly: hierarchical/Bayesian shrinkage (Beta-Binomial on hook rate, Gamma on CPL) per
feature; report "probability style X beats Y on hook rate" instead of p-values.
4. Write back to the engine: style win rates per vertical in library/styles/*/stats.json; winning frames join
the golden set; winning hooks become templates; losing patterns join the defect/"don't" lists; planner allocates
next batch ~50 % new concepts / 30 % variants of winners / 20 % proven (practitioner split).
5. Check the judge (§3.4.8) against market results each cycle.
4.5 Guardrails for AI UGC and claims
Meta and most markets treat fabricated testimonials as deceptive; the brief's facts list is the only source of claims. AI UGC should be framed as a presenter or a dramatization, not a fake customer review. Record the AI-disclosure decision per ad. SynthID is embedded in Google outputs [official].
5. Workflow orchestration
5.1 Gates (owner time budget ≈ 15 min per ad) [proposal, matches repo rules 1-2]
| Gate | Who | What the owner sees | Spend unlocked |
|---|---|---|---|
| G0 Script | owner | script + lint report | VO (cents) |
| G1 Styles | owner | 1-card-per-style preview (style frame, palette, 3 s motion sample, cost estimate) | per-style keyframes |
| G1b New style (rare) | owner | style frame + 6 golden stills + 10 s test | adds a style to the library (amortized) |
| G2 Picks (optional) | auto, owner may glance | contact strip of chosen takes with judge notes | none (already spent) |
| G3 Final | owner | phone watch, sound on/off, QC report | publish |
Everything between gates is automatic. Each gate shows cost so far and projected cost (rule "each paid gate needs a go").
5.2 Pipeline as idempotent steps [proposal]
ads/<slug>/manifest.json pins: script hash, style@ver, prompt templates@ver, model ids, budget cap
steps (each: inputs → outputs, skip if output hash matches):
vo → align → beats → intents → [per style] music → timeline → keyframes → keyframe_qc
→ takes → take_qc (gates + checklist + pairwise) → picks → remotion_render → master → final_qc → publish
- Content-addressed cache: key = sha256(model id, location, prompt text, sorted reference hashes, params). Same key → reuse output, no call. Generators are non-deterministic, so the cache is the reproducibility.
- Run ledger
runs.jsonl: timestamp, step, model id/version, request (prompt, ref hashes, params, seed), response id, output hash, latency, cost, judge verdicts. The same idea as Promise's Muse, which "records prompts, settings and approvals" for production provenance [practitioner, press]. - Prompt templates in git (Jinja/TS), semver'd, rendered from bible + intent; optional Langfuse-style labels
(
production/staging), trace linking and experiments on a dataset [official Langfuse] if volume grows. - Budget guard: pricing table in config; the orchestrator refuses a call when projected spend > ad cap; per-gate cost report. Quotas: NB2 3-4 parallel, Omni 3 parallel, HTTP timeouts and retries [ours].
- Asset library with tags + SigLIP/CSD embeddings: approved takes are reusable B-roll across ads of the same style (a rooftop take from ad 1 can serve ad 5).
- Model drift watch: when a model id changes (e.g. Omni preview id deprecated 2026-09-30 [practitioner]), re-run a fixed 10-shot regression suite per style and compare to golden by pairwise judge before switching.
5.3 How the market tools map to this
- Pencil: multi-model orchestration, brand kit guardrails, approval workflows, pre-spend performance prediction, results flowing back into generation [practitioner/vendor]. Our equivalent: style bibles + gates + learning loop.
- Foreplay: swipe file, 100M-ad discovery, competitor tracking, briefs, Lens creative reporting [vendor]. Useful as the input (hooks and formats to imitate) for the angle/hook library.
- Motion: AI tagging across 8 creative dimensions to replace naming conventions [vendor]. Our manifest + VLM tagger.
- Icon: human UGC at $1,000 for 6 ads with 18 formats and creative directors [vendor] — a price benchmark: our code- and-AI engine costs $1-20 of compute per ad.
- AI UGC tools (Arcads, Creatify): avatar libraries and fast script-to-video; ~1 in 4 renders with lip-sync drift reported for Creatify [practitioner]; Veo inside Google Ads Asset Studio (≈10 s product motion) [practitioner].
6. Recommended build order [proposal]
- Refactor v2 into layers (1-2 days):
intents.jsonfrom the current shot list;library/styles/clay3d/from the existing kit;theme.jsonread by the Remotion scenes; manifest + run ledger + cache inpipeline/. - Deterministic QC (1 day): gates A1-A14 as one script producing
qc_report.json+ a contact sheet. - Judge v1 (1-2 days): take-level pairwise + checklist with Gemini 3.1 Pro; label 150 past takes; measure agreement; keep advisory until kappa is good.
- Second and third styles chosen for cost and diversity: one code-heavy (2D flat or kinetic type), one AI-heavy (photoreal cinematic or anime). Each: style frame (NB Pro) → golden stills → 10 s test → owner G1b.
- Re-render the approved solar script in 3 styles — the proof that the engine works — then the first real Meta test pack (6-10 ads) with the naming scheme and daily metrics pull.
- Derja talking-head test (small, paid gate): Omni/Veo silent performance + lip-sync to our VO; decide whether AI UGC is viable in Derja.
7. Open questions and unknowns
- Omni reference image limit on Vertex (docs say 5 to 10, inconsistently); test 3-5.
- Omni restyle quality on our content, and whether restyle keeps faces in stylized looks.
- Derja lip-sync quality of lipsync-2-pro / LatentSync on our VO; price and data terms of the hosted option.
- Veo 3.1 GA model ids on Vertex (
-001) vs-preview; check Model Garden before coding. - CSD license and CPU speed on this machine; a SigLIP embedding may be enough as a first proxy.
- Whether Meta's similarity grouping responds to style changes alone (no primary doc; test with our own delivery data).
Sources
Google (official) - Gemini API pricing (Veo 3.1 tiers, Omni token rate, NB2, Lyria, Gemini 3.x): https://ai.google.dev/gemini-api/docs/pricing - Veo 3.1 in the Gemini API (durations, 8 s rule, refs, extend 148 s, seed, latency, retention): https://ai.google.dev/gemini-api/docs/veo - Ultimate prompting guide for Veo 3.1 (formula, camera vocab, audio syntax, negatives, ingredients, timestamps): https://cloud.google.com/blog/products/ai-machine-learning/ultimate-prompting-guide-for-veo-3-1 - Introducing Veo 3.1 (developers blog): https://developers.googleblog.com/introducing-veo-3-1-and-new-creative-capabilities-in-the-gemini-api/ - Vertex: generate videos from references (asset vs style refs): https://docs.cloud.google.com/vertex-ai/generative-ai/docs/video/use-reference-images-to-guide-video-generation - Vertex: Veo 3.1 model page: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/models/veo/3-1-generate - Vertex: extend Veo videos: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/video/extend-a-veo-video - Gemini Omni API doc (specs, languages, refs, restyle, extension): https://ai.google.dev/gemini-api/docs/omni - Gemini Omni prompt guide (DeepMind): https://deepmind.google/models/gemini-omni/prompt-guide/ - Gemini Omni 1.1 Flash on Agent Platform: https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/gemini/omni-1-1-flash - Gemini Omni Flash model card: https://deepmind.google/models/model-cards/gemini-omni-flash/ - Nano Banana image generation doc (reference limits, thinking, grounding): https://ai.google.dev/gemini-api/docs/image-generation - Nano Banana 2 model page: https://deepmind.google/models/gemini-image/flash/ - How to prompt Gemini 2.5 Flash Image (templates, semantic negatives): https://developers.googleblog.com/en/how-to-prompt-gemini-2-5-flash-image-generation-for-the-best-results/ - Gemini video understanding (1 fps default, custom fps, clipping, 10 videos/request): https://ai.google.dev/gemini-api/docs/video-understanding - Gemini media resolution (tokens per image/frame): https://ai.google.dev/gemini-api/docs/media-resolution
Meta (official) - Meta Andromeda (engineering blog): https://engineering.fb.com/2024/12/02/production-engineering/meta-andromeda-advantage-automation-next-gen-personalized-ads-retrieval-engine/ - The Creative Advantage: diversification with Andromeda: https://www.facebook.com/business/news/the-creative-advantage-unlocking-the-power-of-diversification-with-meta-andromeda - Demystifying creative diversification: https://www.facebook.com/business/news/demystifying-creative-diversification - Advantage+ creative: https://www.facebook.com/business/ads/meta-advantage-plus/creative
Papers and model repos - GenArena (pairwise vs pointwise VLM judging): https://arxiv.org/abs/2602.06013 - VLM Judges Can Rank but Cannot Score: https://arxiv.org/html/2604.25235v1 - RAVEN-Eval (rubric-guided pairwise video evaluation): https://arxiv.org/abs/2608.09111 - Judging LLM-as-a-judge (MT-Bench; biases and mitigations): https://arxiv.org/abs/2306.05685 - VideoScore2: https://huggingface.co/papers/2509.22799 - Video-T1 test-time scaling: https://arxiv.org/abs/2503.18942 and https://arxiv.org/html/2503.18942v1 - Diagnosis-guided candidate recycling (related TTS work): https://arxiv.org/pdf/2608.29322 - ArtifactLens (few-label artifact detection): https://arxiv.org/abs/2602.09475 - CSD, Measuring Style Similarity in Diffusion Models: https://arxiv.org/abs/2404.01292 - When style similarity scores fail (CSD calibration): https://arxiv.org/pdf/2605.09030 - HPSv3: https://github.com/MizzenAI/HPSv3 - Aesthetic Predictor v2.5 (SigLIP): https://github.com/discus0434/aesthetic-predictor-v2-5 - Q-Align: https://proceedings.mlr.press/v235/wu24ah.html - SeedVR2 (video restoration/upscaling): https://github.com/ByteDance-Seed/SeedVR
Practitioner, vendor and press - Omni pricing breakdown per resolution: https://www.eesel.ai/blog/gemini-omni-1-1-flash-pricing - Omni reference-driven video (tags, limits): https://runware.ai/docs/models/google-gemini-omni-flash/guides/reference-driven-video - Omni review (duration, audio sync): https://www.buildfastwithai.com/blogs/gemini-omni-flash-review-google-ai-video-model-2026 - Veo 4 status (not released): https://wavespeed.ai/blog/posts/what-is-veo-4/ - Veo 3.1 Lite vs Fast vs Standard: https://www.buildfastwithai.com/blogs/google-veo-3-1-ai-video-generator - Veo dialogue/lip-sync in other languages: https://prompt-architects.com/blog/101-veo-dialogue-prompts and https://github.com/ulmeanuadrian/kie-mcp/issues/1 - Lip-sync models: https://sync.so/lipsync-2-pro , https://lipsync.com/blog/open-source-lip-sync - NB2 practical guide (roles for references): https://masonry.so/blog/nano-banana-2-guide - NB2 consistency (no style slot in NB2, Pro has 3): https://www.glbgpt.com/hub/nano-banana-2-subject-consistency/ - Andromeda playbook (concepts, cadence, similarity claims): https://segwise.ai/blog/meta-andromeda-update-creative-strategy-2026 - Entity ID explainer: https://www.artifexdigital.co/blog/understanding-metas-entity-id-why-your-28-ads-might-actually-be-3 - Creative testing frameworks: https://paidmediaworld.com/meta-creative-testing-framework/ , https://adlibrary.com/posts/creative-angle - Reels safe zones and hook guidance: https://adadvisor.ai/blog/facebook-reels-ads , https://withblip.com/blog/how-to-use-meta-ad-safe-zones-without-cutting-off-your-creative/ - Motion AI tagging: https://www.foxwelldigital.com/blog/ai-tagging-the-end-of-naming-convention-chaos-and-the-start-of-smarter-creative-analysis , https://www.motionapp.com/releases/introducing-ai-tagging - Foreplay: https://www.foreplay.co - Pencil platform: https://trypencil.com/the-platform - Icon: https://icon.com - AI UGC tools 2026: https://morphic.com/resources/tools/best-ai-ugc-ad-tools , https://novoads.ai/en/blog/arcads-vs-creatify - Promise studio (Muse records prompts, settings, approvals): https://www.forbes.com/sites/maureenkerr/2026/07/24/dave-clarks-ai-studio-promise-aims-for-films-hollywood-can-release/ - Asteria Continuum Suite: https://deadline.com/2026/03/asteria-launches-continuum-suite-ai-operating-system-film-tv-production-1236749265/ - Remotion parameterized rendering: https://www.remotion.dev/docs/parameterized-rendering - Langfuse prompt management: https://langfuse.com/docs/prompts/get-started
Internal
- ai-docs/01-architecture.md, ai-docs/03-lessons-learned.md, ai-docs/04-qc-checklists.md, research/01, 05-09.