A self-learning ad creative engine. Give it a brand URL; it researches the brand, writes art-direction briefs where every claim traces to a sourced fact, renders finished ads (gpt-image-2), verifies its own output by reading the pixels back, and learns from every batch and every founder edit — so batch N+1 is measurably better-behaved than batch N.
Built at Push to Prod (Bengaluru, 2026-08-08) on Claude Managed Agents as the runtime. Submission: https://devfolio.co/projects/adloop-7e59
The core claim is that the engine learns. Every step of that claim is verifiable in tracked files, from one live run on godesi.in (an Indian D2C candy brand):
- Batch 2 shipped; the founder made two edits asking for "festival mela energy"
→
brands/godesi.in/batches/002/edit-ad-1/andedit-ad-2/(the thin edit loop: smallest brief change, single-ad re-render, re-verify). - Two edits with the same lesson = a permanent rule. The engine generalized both edits
into one promoted rule — written by the agent, unprompted, into
brands/godesi.in/memory.md: "make it festive / like a mela" = add triangular-flag bunting, change nothing else — including which brand color the flags take per ground, and a caution not to violate the design guide's one-magenta-element cap. - Batch 3 applied the rule with zero new instructions. All three briefs in
brands/godesi.in/batches/003/briefs.jsoncarry a mela-flag line in theirlayoutslot. Nobody asked. That is the loop closing. - Repetition is a decision, never an accident.
brands/godesi.in/history.jsonis the ledger: every shipped ad keyed by angle × SKU × persona with a status (shipped → approved/edited/killed → winning/fatigued). Batch 3's mix rationale (brands/godesi.in/batches/003/plan.json) shows winners re-run deliberately with new scenes, unproven cells never duplicated, and one exploration slot always kept.
Every fact is captured with a source URL into a number bank with an explicit forbidden
list (brands/godesi.in/inputs/facts.json). Every brief carries facts_used[]. After
rendering, a vision pass reads the finished image and diffs every numeral on canvas against
the facts:
brands/godesi.in/batches/003/verdicts.json: all three batch-3 ads FAILED verification — the image model hallucinated numerals into the scene (sticky notes reading "Client call 3:30 PM", "Q3 Review 4:00 PM"; an untraceable ₹5 badge) and the verify pass caught every one. Refusing to ship those IS the product working.- Batches 1–2: zero untraceable numerals across six ads
(
brands/godesi.in/batches/002/verdicts.json). - Validated before the build: 9 ads across 3 real businesses, zero invented claims — while a
captured competitor pipeline invented guarantees, review counts and discount codes
(
docs/COMPETITOR_TEARDOWN_MAKELOCALADS.md).
Chat / canvas ⇄ host CLI (engine/)
├─ capture — 1 CMA session, multiagent: 3 parallel research lanes (facts, design, personas);
│ input QA gate (view every ref image) is never delegated
├─ batch — 1 CMA session: read ledger → decide mix → write briefs (pinned 8-slot schema)
│ → assemble → render (KIE gpt-image-2, per-ad refs) → vision verify → ledger append
├─ edit — thin loop: smallest brief change → single-ad re-render → learn (edit log → rule promotion)
└─ memory store (per brand) = ledger + learned rules + fact bank, mounted read-write into every session
- Vault credentials: the render API key is substituted at egress — the model never sees it.
- Budgets: per-session hard caps with pause/resume (
budget_reachedpauses, host raises, work continues). - Pinned schemas: every cross-agent artifact shape is validated host-side (
engine/schemas.py); parsers accept only the pinned shape. - Stage runbooks (the full orchestration prompts):
engine/prompts.py. - Runtime decision + spike evidence:
docs/SPIKE_RESULT_CMA_GO_2026-08-08.md.
python3 -m venv .venv && .venv/bin/pip install anthropic # + .env.local with keys
python3 -m engine setup # standing cloud resources
python3 -m engine capture <url> # cold-start a brand
python3 -m engine batch <domain> # one batch, end to end
python3 -m engine edit <domain> ad-2 "make it more festive" # founder edit → re-render + learn
python3 -m engine canvas <domain> # live canvas at localhost:8787
Canvas pages: / (ad cards, verdicts, ledger, rules) · /start?replay (the six pipeline
stages replayed with the latest batch's real artifacts) · /memory (edits → rules → applied
unprompted).
| Claim | File |
|---|---|
| Founder edits become rules (2 = promote) | brands/godesi.in/memory.md, batches/002/edit-*/ |
| Next batch applies rules unprompted | brands/godesi.in/batches/003/briefs.json (layout slots) |
| Verify pass rejects hallucinated numerals | brands/godesi.in/batches/003/verdicts.json |
| Ledger: repetition is a decision | brands/godesi.in/history.json |
| Truth layer: number bank + forbidden list | brands/godesi.in/inputs/facts.json |
| Pinned cross-agent schemas | engine/schemas.py |
| Full stage runbooks (orchestration) | engine/prompts.py |
| Ground truth the build reproduces | reference/scratch-tests/ (3 validated end-to-end runs) |
| How the architecture was derived | docs/ORIGINS.md, CLAUDE.md |
Rendered ad images are not tracked (size); see the Devfolio gallery or run the canvas.