Banner Visual QA
Overview
Use this skill before showing Pafi, uploading, or handing off any raster banner. It catches objective production failures such as wrong dimensions, excessive file weight, wrong format, missing visible copy, blank exports, edge-risk text, and low-contrast OCR regions, then requires a separate visual inspection gate for hierarchy and polish.
This skill complements Claude's banner-critique skill:
banner-visual-qa checks measurable export correctness.
banner-critique checks subjective design quality through vision review.
- A banner is not final until both deterministic QA and visual inspection are recorded.
Quick Start
python3 ~/.codex/skills/banner-visual-qa/scripts/banner_qa.py \
--image "/absolute/path/banner.jpg" \
--width 800 \
--height 419 \
--max-kb 300 \
--format jpg \
--expected-text "A HUGE WELCOME BONUS OF $1000 AWAITS YOU" \
--expected-text "CLAIM IT HERE" \
--report "/absolute/path/banner.qa.md" \
--json-report "/absolute/path/banner.qa.json"
For known channels, use a preset:
python3 ~/.codex/skills/banner-visual-qa/scripts/banner_qa.py \
--image "/absolute/path/banner.jpg" \
--channel-preset smsplus-800w \
--expected-text "LUXURY CASINO" \
--report "/absolute/path/banner.qa.md"
Required Workflow
- Collect inputs — final image path, expected dimensions or channel preset, max KB, expected format, expected visible copy, and any required disclaimer.
- Run automated QA — execute
scripts/banner_qa.py.
- Read the report — status is
PASS, REVIEWABLE_PASS, or FAIL.
- Open the final image — inspect the actual exported file at 100% size using Codex image viewing or an OS/browser screenshot flow.
- Run visual critique when design quality matters — reuse Claude
banner-critique rubric if available, or manually score readability, hierarchy, depth, brand fit, and professional polish.
- Only deliver after recording visual inspection — never treat automated QA alone as final approval.
Status Semantics
PASS: objective checks passed and no warnings were detected. Manual visual inspection is still required before final delivery.
REVIEWABLE_PASS: no hard production blocker was found, but OCR was unavailable/imperfect, text is close to edges, contrast is risky, or manual inspection is required.
FAIL: hard blocker found, such as wrong dimensions, file too large, wrong format, blank image, or expected text/disclaimer missing.
Delivery Rule
Do not present a banner as final unless the response includes:
- final image path
- source assets used
- expected copy
- QA report path
- visual inspection confirmation
- remaining manual risks, if any
Script
scripts/banner_qa.py performs the deterministic checks. It is local-only and makes no external API calls. It uses:
- Python Pillow for image metadata and image statistics.
tesseract CLI if available for OCR text and bounding boxes.
- Graceful fallback to
REVIEWABLE_PASS when OCR is unavailable.
References
references/channel-specs.md contains default SMSads/VOX/IAB channel presets.
When to Use vs Alternatives
- banner-visual-qa: final export QA for raster banners.
- screenshot/playwright: capture source pages or desktop/browser state before banner production.
- imagegen/gpt-image-banner: create visual backgrounds or hero images, not final exact text validation.
- banner-critique: subjective design scoring; use after this skill or alongside it.
- pdf: extract vendor specs from PDF before choosing QA constraints.
Appropriate for: Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.
Not every skill requires all three types of resources.
1---2name: banner-visual-qa3description: Validate raster banner ads before delivery with deterministic checks plus a forced visual gate. Use when reviewing, QA-ing, exporting, or preparing final SMSads, RCS, WhatsApp, push, in-app, Rewards Affiliates, casino display, or other raster ad banners. ANTI-PATTERN: Do not use for generating banner concepts, writing copy, or subjective design critique alone; use imagegen/gpt-image-banner/banner-critique for those.4---56# Banner Visual QA78## Overview910Use this skill before showing Pafi, uploading, or handing off any raster banner. It catches objective production failures such as wrong dimensions, excessive file weight, wrong format, missing visible copy, blank exports, edge-risk text, and low-contrast OCR regions, then requires a separate visual inspection gate for hierarchy and polish.1112This skill complements Claude's `banner-critique` skill:1314- `banner-visual-qa` checks measurable export correctness.15- `banner-critique` checks subjective design quality through vision review.16- A banner is not final until both deterministic QA and visual inspection are recorded.1718## Quick Start1920```bash21python3 ~/.codex/skills/banner-visual-qa/scripts/banner_qa.py \22 --image "/absolute/path/banner.jpg" \23 --width 800 \24 --height 419 \25 --max-kb 300 \26 --format jpg \27 --expected-text "A HUGE WELCOME BONUS OF $1000 AWAITS YOU" \28 --expected-text "CLAIM IT HERE" \29 --report "/absolute/path/banner.qa.md" \30 --json-report "/absolute/path/banner.qa.json"31```3233For known channels, use a preset:3435```bash36python3 ~/.codex/skills/banner-visual-qa/scripts/banner_qa.py \37 --image "/absolute/path/banner.jpg" \38 --channel-preset smsplus-800w \39 --expected-text "LUXURY CASINO" \40 --report "/absolute/path/banner.qa.md"41```4243## Required Workflow44451. **Collect inputs** — final image path, expected dimensions or channel preset, max KB, expected format, expected visible copy, and any required disclaimer.462. **Run automated QA** — execute `scripts/banner_qa.py`.473. **Read the report** — status is `PASS`, `REVIEWABLE_PASS`, or `FAIL`.484. **Open the final image** — inspect the actual exported file at 100% size using Codex image viewing or an OS/browser screenshot flow.495. **Run visual critique when design quality matters** — reuse Claude `banner-critique` rubric if available, or manually score readability, hierarchy, depth, brand fit, and professional polish.506. **Only deliver after recording visual inspection** — never treat automated QA alone as final approval.5152## Status Semantics5354- `PASS`: objective checks passed and no warnings were detected. Manual visual inspection is still required before final delivery.55- `REVIEWABLE_PASS`: no hard production blocker was found, but OCR was unavailable/imperfect, text is close to edges, contrast is risky, or manual inspection is required.56- `FAIL`: hard blocker found, such as wrong dimensions, file too large, wrong format, blank image, or expected text/disclaimer missing.5758## Delivery Rule5960Do not present a banner as final unless the response includes:6162- final image path63- source assets used64- expected copy65- QA report path66- visual inspection confirmation67- remaining manual risks, if any6869## Script7071`scripts/banner_qa.py` performs the deterministic checks. It is local-only and makes no external API calls. It uses:7273- Python Pillow for image metadata and image statistics.74- `tesseract` CLI if available for OCR text and bounding boxes.75- Graceful fallback to `REVIEWABLE_PASS` when OCR is unavailable.7677## References7879- `references/channel-specs.md` contains default SMSads/VOX/IAB channel presets.8081## When to Use vs Alternatives8283- **banner-visual-qa**: final export QA for raster banners.84- **screenshot/playwright**: capture source pages or desktop/browser state before banner production.85- **imagegen/gpt-image-banner**: create visual backgrounds or hero images, not final exact text validation.86- **banner-critique**: subjective design scoring; use after this skill or alongside it.87- **pdf**: extract vendor specs from PDF before choosing QA constraints.8889**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.9091---9293**Not every skill requires all three types of resources.**