Taste
Alex's requirement, stated plainly: output must be genuinely good across any industry and any client, and must not read as AI slop. He has not seen an AI system do this.
This file is the answer to *how*, because "be tasteful" in a prompt achieves nothing.
Slop has a mechanism, and the mechanism is averaging
A single model pass asked to produce a good ad optimises a blend of every objective at once — hook, clarity, proof, voice, format fit — and settles on the median of all of them. The median of all ads is slop. Not because the model is weak, but because averaging is what one pass does, and the trade-offs happen internally where nothing can inspect them.
This is the same finding as depth.md, stated from the output side: if a single pass can be wrong in several independent ways, one pass will be mediocre in all of them.
Every other cause is downstream of this one:
- Genericness — abstraction is the safest average, so an unconstrained pass reaches for it
- Sameness — twelve concepts generated together cluster around one idea in twelve frames
- Unearned confidence — nothing in a generation loop is empowered to say "this is not good"
So taste is a rejection function, not a generation function
You cannot prompt a system into taste. You can generate wide and kill hard, and put the judgment in the killing. That inverts where the effort goes: most of the machinery is criteria for throwing work away.
Which means the criteria have to be specific and checkable. "Make it tasteful" is not a criterion. These are:
- No claim without an approved fact behind it
- No present-tense pain for an infrequent purchase *(the renovation-scam line)*
- No two surviving concepts sharing a persuasion mechanism — now enforced in code,
src/lib/creative/diversity.ts - No text-dominant format handed a hero image
- Nothing from the client's
donts - Every headline carries a concrete noun, number or named thing — abstraction is the tell
- No hook whose promise the body does not discharge. The strongest evidence in paid social is that hook rate and hold rate predict CPA together, and that a high hook with a low hold means the opening earned attention the body did not pay off. So a hook is not judged on how arresting it is; it is judged against whether the promise field settles the specific debt the hook takes on
- No angle with no identifiable mechanism. If the classifier cannot name why an angle should persuade, that is the abstraction failure showing up as a null, and the fix is upstream in the input, never in the wording
- No polish where a sharper idea in a rougher execution would win. UGC-style creative outperforms polished brand production by roughly a quarter on both engagement and conversion. Uncomfortable for a video agency, and the system is allowed to say it
- No static whose text weight the algorithm will penalise. The 20% rule left; the penalty did not
The numbers behind the last four, with sources, are in creative-intelligence.md. They are recorded rather than remembered so that a heuristic can be argued with, and retired when the evidence moves.
Four structural commitments
0. The critic itself has to be trustworthy. Generating wide and killing hard with a biased judge does not escape slop, it produces confident slop — and frontier models fail more than half of judge-bias tests. So judgment is pairwise rather than scored, run blind per criterion, every pair judged both ways, and a criterion that contradicts itself when the order flips is excluded rather than averaged in. Mechanism and evidence: creative-engine.md, tournament.ts.
1. Deterministic gates run before any critic. Proof-backing, format/awareness fit, text weight, banned words, claim-to-fact linkage — all checkable in code. They are free, they never vary, and they stop a model being asked to notice something a regex already knows. The expensive judgment is reserved for what genuinely needs it.
2. Diversity is enforced, not hoped for. Concepts are generated from deliberately different mechanisms — different insight, format and persuasion route per concept — and then checked pairwise. Two survivors that argue the same thing in different frames are one survivor. This is what "the proof card and the offer card are the same ad" looked like from the inside.
3. The critic must be able to reject everything. A pipeline that always returns twelve creatives will return twelve mediocre creatives on a bad brief. Returning "none of these are good enough, and here is what is missing" has to be a legal outcome, and the escalation machinery already exists for it. A system that cannot refuse has no taste, only output.
4. The rules are written down; the voice is not. There is deliberately no single house voice — tone follows the content type, because a long-form video, a paid Meta static, a YouTube pre-roll and an organic post are different jobs. What is universal is a set of copywriting rules, held in skills/copy-commandments and in taste_principles where workers read them at runtime.
Rule one is not generic, which means *only this brand could say it* — not that it must be hyper-specific. A line needs no statistic to be ownable. That distinction matters: chasing specificity produces stat-stuffed copy that is still forgettable, while chasing ownability produces lines a competitor could not publish.
How modular skills become one competent agent
The requirement is skills that are modular but not merely a pile — they have to compose into something that is actually good at the job.
They compose through a shared typed artefact, not by calling each other. Skills that invoke skills become an unpredictable graph nobody can debug. Instead every skill has a narrow contract — consumes X, produces Y, both schema-validated — and the pipeline order is code.
The insight object is the lingua franca. Research writes market facts. Synthesis reads brand facts plus market facts and writes an insight. Concept generation reads an insight and writes concepts. Copy reads a concept. Format selection reads a concept and the catalogue. Nothing reaches around another stage, and any stage can be improved or replaced without touching its neighbours.
That is what makes the orchestrator deterministic while the judgment stays in the workers — the principle already in cost.md, and the reason there is no model routing the pipeline.
The honest position
Taste is the hardest thing being attempted here, and no part of this guarantees it. What this design does guarantee is that the *mechanisms of slop* are structurally blocked: averaging is broken up into separable judgments, sameness is detected rather than tolerated, unsupported claims cannot pass, and the system is permitted to produce nothing.
That is not the same as taste. It is the necessary condition for it, and it is the part a system can actually enforce.
Approval is a moment, not a property
A line is checked once, approved, and then runs indefinitely while the rules change underneath it. Nothing was looking back until GET /api/copy/audit, which re-checks live copy against the rules as they stand today.
It earned its place immediately. An approved Inspire ID headline read "Accredited. Licensed. Accountable." — the exact construction the empty-credential rule exists for. That rule required a pronoun ("we're accredited", "proudly certified") to fire, so the barest form of the offence had never been caught, and the line was live. Dropping the pronoun makes a credential claim emptier, not safer.
Two properties worth keeping if this is ever rewritten:
- It never changes a status. A rule change that silently unapproved live copy would be a worse failure than the one this catches, and deciding whether a newly-flagged line is genuinely wrong is a person's job.
- It reports its own noisy rules. A rule firing on more than 60% of the corpus is describing the corpus rather than finding a fault in it. That matters more than it sounds: people stop reading a check that always fires, and it then misses the one line that mattered. Three rules were doing exactly this before being fixed —
borrowed-brandflagged "Reno", "Package" and "From" out of one headline, andreading-gradeflagged "Lifetime warranty on carpentry hardware." as too complex.