ad-preflight
Ad Preflight
The problem this solves: Meta rejects ads for policy reasons every day, and almost every rejection was preventable — a phrase that calls out a personal attribute, a health claim worded one notch too hard, an income promise, a before/after implication. The cost isn't just the bounced ad: repeated disapprovals train Meta's system to distrust the account, throttle delivery, and eventually restrict it. By the time you're appealing a restriction, it's weeks of lost spend.
This skill is the check that happens before Meta sees the ad. It reads your ad copy, works out which of Meta's Advertising Standards apply, pulls the live policy text from Meta's Transparency Center (never a stale hardcoded rule list — Meta edits these pages), and grades every element of every ad against what the policy actually says. Verdicts come back per ad:
- ✅ Cleared for launch — no findings worth acting on.
- ⚠️ Fix before launch — likely flag; specific fixes provided.
- ⛔ Grounded — clear violation; do not submit until rewritten.
Policy pages are fetched with your own web tools (Meta's Transparency Center is JS-rendered, so raw HTTP fetches return an empty shell — never try that route). The one script is Python 3 stdlib only — no pip installs, no API keys, no Meta login. Output goes to ./preflight-run/ in the current folder.
Portability: ${CLAUDE_SKILL_DIR} means this skill's own folder — if the variable isn't set in your environment (e.g. claude.ai), use the path to the folder containing this SKILL.md. If you can't open a browser at the end, run the renderer with --no-open and give the user dashboard.html as a downloadable file. If the session has no web access at all, stop and tell the user — a policy check graded from memory instead of live policy text is not worth shipping.
0 — Intake: the ads
Look in the current folder for ad copy (a text/markdown/CSV file of ads). If found, confirm it with the user; if not, ask them to paste their ad(s) directly into chat. One ad or twenty — the pipeline is the same. For each ad, capture whatever elements exist: