answer-ads-questions
Answer questions about a brand's Meta ads (spend, results, which ad is winning, is it paused,…
Final QC gate for a rendered 9:16 video ad, run before it is published. One script checks what a machine can decide — exact 1080x1920 size, a hook that moves and speaks in the first second, no frozen stretches, no dead air, no black frames, the brand's real logo on the end card
$ npx -y skills add gooseworks-ai/goose-skills --skill review-finished-ad --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/review-finished-adContext preview
The summary Claude sees to decide when to auto-load this skill.
Final QC gate for a rendered 9:16 video ad, run before it is published. One script checks what a machine can decide — exact 1080x1920 size, a hook that moves and speaks in the first second, no frozen stretches, no dead air, no black frames, the brand's real logo on the end card
name: review-finished-ad description: Final QC gate for a rendered 9:16 video ad, run before it is published. One script checks what a machine can decide — exact 1080x1920 size, a hook that moves and speaks in the first second, no frozen stretches, no dead air, no black frames, the brand's real logo on the end card (never a favicon, never a redrawn or wrong logo), end-card colours near the brand palette — and builds one contact sheet (frames with the TikTok/Reels UI safe zones shaded, beside the logo, product images and a font specimen) for the checks that need eyes — font, product likeness, product consistency across scenes, safe zones. Exit 0 PASS / 2 FAIL / 3 ERROR. Use on every finished video master before pinning it.
The gate between a rendered master and the user. A finished ad has to look like the brand's ad and play like an ad, not like a pile of clips. This skill checks both, fixes are made by the caller, and the gate is re-run until it passes.
Needs `ffmpeg` + `ffprobe` on PATH and `pip install --quiet numpy pillow`.
python3 scripts/review_finished_ad.py \ --video working/final.mp4 \ --json working/review/finished-ad.json \ --sheet working/review/finished-ad-sheet.png \ --logo working/brand/logo.png \ --palette "#0b3d2e,#f4efe6" \ --product-images working/brand/product-1.png,working/brand/product-2.png \ --font working/brand/font.ttf --brand-name "Acme"
`logos[0]`, or the wordmark file the recipe's end card uses. PNG, JPEG or SVG (an SVG is rasterised with `cairosvg` or `rsvg-convert`). Never a generated logo.
kit only has a favicon or no logo): omit `--logo`, and judge the text wordmark on the sheet.
silent or static end card would otherwise read as dead air or a freeze.
mid-video; the end card (last ~1.6s) is always checked.
silence is not judged.
**Exit 0 → PASS.** Still read the sheet (below) before publishing. **Exit 2 → FAIL.** `failed` lists the checks; each `note` says what to fix. **Exit 3 → ERROR.** The check could not run (missing file, no ffmpeg); fix and re-run. Never publish blind.
| Check | Fails when | Typical fix | |---|---|---| | `ratio` | output is not exactly 1080x1920 | scale + pad every clip to 1080x1920 BEFORE the concat | | `hook` | no sound in the first 1.0s, or the opening frame is still for > 1.5s | start the VO/music at 0s; open on motion or a cut, not a held title | | `pacing` | the picture is frozen for > 2.5s before the end card | add motion (push-in, b-roll, a cut) or trim the hold | | `dead_air` | silence > 1.0s mid-video (skipped with `--no-speech`) | tighten the VO timing or run the music bed under the gap | | `black_frames` | a black stretch > 0.3s | fix the concat / transition | | `logo_asset` | the logo file is favicon-sized (long side < 256px, or under 40,000 px²) | do not upscale it: ask for a real logo, or set the wordmark as text in the brand font (then drop `--logo`) | | `logo` | the kit logo is not found on the end card (below the fail line for its mode) | composite the uploaded logo file onto the end card; never regenerate or retype it | | `palette` | *(warn only)* no kit colour among the end card's main colours | use a kit colour for the end-card background or text |
`logo` is grayscale correlation with a fine size search, so the right logo scores 0.9+ at any size:
version on a dark card counts. Pass ≥ 0.85, fail < 0.75. Another brand's wordmark scores about 0.6-0.7; a same-font near-copy about 0.8 (warn).
Pass ≥ 0.85, fail < 0.70. A different mascot on a similar background scores about 0.5.
Between the two lines it is a `warn`: look at the sheet for a warped, cropped or redrawn logo.
`finished-ad-sheet.png` shows one frame per shot plus the end card, with the platform UI areas shaded red, and the brand references underneath. Open it and confirm each line in the verdict's `judge_on_sheet`:
(top 220px, bottom 400px, right 140px at 1080x1920).
(shape, label, colour). A stand-in, a catalogue image of another product, or a mascot is a fail.
Any of these failing is a FAIL, the same as a machine check.
Fix only the failing window (re-composite the end card, regenerate one shot, re-time one line), re-render, and re-run this script. Up to **2 repair rounds**. If it still fails, do not present the video as finished: the caller reports it as blocked with the failed checks, so the user sees a clear warning.
`--json` writes `{ verdict, failed[], video{width,height,duration,has_audio,cuts}, checks{<name>: {status, note, data}}, sheet, judge_on_sheet[] }`. Status is one of `pass`, `fail`, `warn`, `not_applicable`.
Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.
Repo: gooseworks-ai/goose-skills
Answer questions about a brand's Meta ads (spend, results, which ad is winning, is it paused,…
Burned-in captions for a finished vertical video, three kinds. transcribe.py gets word…
Composite a generated creator track into a product layer, per beat — in the creator's zone on…
Generate an AI creator talking to camera, saying an approved script, as one continuous track…
Generate or edit an image via any FAL image model (nano-banana edit, gpt-image, flux, ...),…
Generate a single photoreal or designed image with OpenAI gpt-image via fal.ai. Supports…