# Copywriter Test Suite

The `copywriter` agent runs every draft against this file before delivery. Each test is PASS/FAIL with a specific match. After all tests pass, the agent does an LLM-judge naturalness score (1-10) and only ships if score ≥ 8.

**Maintenance:** when you catch a new AI-tell in delivered copy, add it here. The agent will catch it next time.

---

## Universal tests (all languages)

### T-U1: No emojis
- **Match:** any emoji character
- **Why fail:** emojis in copy are unprofessional for B2B and over-used in B2C ChatGPT output

### T-U2: No three-adjective stacks
- **Match:** patterns like "fast, easy, and effective" / "modern, sleek, and beautiful"
- **Why fail:** AI-tell — humans pick one strong adjective

### T-U3: No "imagine if" openers
- **Match:** opening line starts with "Imagine" / "What if" / "Picture this"
- **Why fail:** ChatGPT default opener, instantly recognizable

### T-U4: No "in today's fast-paced world" / "in the realm of"
- **Match:** "in today's", "in the realm of", "in this digital age", "in our modern world"
- **Why fail:** the most ChatGPT phrase ever written

### T-U5: No "delve / unlock / harness / leverage / navigate / streamline"
- **Match:** any of these verbs
- **Why fail:** LLM signature words

### T-U6: No "let's" or "let us" hedge openers
- **Match:** "let's dive in", "let's explore", "let us examine", "let's take a closer look"
- **Why fail:** translated marketing speak

### T-U7: CTA exists and matches commitment level
- **Match:** missing CTA OR cold-prospect CTA says "Buy Now"
- **Why fail:** broken funnel logic

### T-U8: Specificity check
- **Match:** vague claims with no number ("save tons of time", "much faster", "many clients")
- **Why fail:** weak — needs specificity

---

## Croatian / Bosnian (HR / BS) tests

### T-HR1: No em-dashes
- **Match:** `—` character anywhere in the text
- **Why fail:** em-dashes are not natural in HR/BS writing — they signal translation
- **Fix:** replace with comma, period, or parentheses

### T-HR2: No 2-word sentence fragments
- **Match:** any sentence with exactly 2 words ending in `.` (e.g., "Brzo. Jednostavno.")
- **Why fail:** translated English direct-mail style. HR/BS doesn't do this naturally for emphasis.
- **Fix:** combine into a fuller sentence

### T-HR3: Banned literal English phrases
Match any of these exact phrases (case-insensitive):

- `uronimo u` (let's dive in)
- `uronite u` (dive into)
- `u zaključku` (in conclusion) — Croatians say "na kraju" or "zaključno"
- `budimo iskreni` (let's be honest) — sounds like a translated podcast intro
- `krenimo` (let's start) when used as opener — pad word, just start
- `zamislite ovo` (imagine this) — opening
- `evo u čemu je stvar` (here's the thing) — direct English translation
- `da budemo realni` (let's be real)
- `bez okolišanja` (without beating around the bush) — translated idiom
- `dolje u nastavku` (down below) — redundant English structure
- `prijatelji` as a copy address — nobody calls customers "prijatelji"
- `igra je promijenjena` (game changed) — literal English
- `na kraju dana` (at the end of the day) — English idiom calque

### T-HR4: No literal "Hi/Hey [Name]" openers
- **Match:** "Bok [Ime]", "Pozdrav [Ime]," followed by a single newline (the <id> pattern)
- **Why fail:** Croatians don't open ACME Agency communication this casually unless very informal context
- **Fix:** "Poštovani [Prezime]," for formal, "[Ime], ..." for direct

### T-HR5: No comma splices in marketing-speak structure
- **Match:** sentence patterns like "Brže, jeftinije, bolje." or "Više leadova, manje truda, jednostavnije."
- **Why fail:** English ad rhythm transplanted into Croatian — sounds fake
- **Fix:** rewrite as a normal sentence

### T-HR6: Verb-noun agreement smell test
- **LLM judge:** read the draft and check for awkward gender/case agreements that signal machine translation
- **Why fail:** Native speakers immediately notice broken grammar even if the words are correct

### T-HR7: Naturalness LLM-judge score
- **Prompt:** "If a 35-year-old native Croatian/Bosnian speaker read this copy aloud to a friend over coffee, would they (a) sound human and natural [8-10], (b) sound like they're reading a translated brochure [5-7], or (c) sound robotic / AI-generated [1-4]? Score 1-10 and explain in 1 sentence."
- **Pass threshold:** ≥ 8
- **Why fail:** the whole point — we're trying to sound like a real native speaker

---

## German (DE) tests — for ACME Agency

### T-DE1: Formal "Sie", never "Du"
- **Match:** any "du", "dein", "dir", "dich" outside of explicit informal contexts
- **Why fail:** ACME Agency is formal B2B/B2C insurance — must always be "Sie/Ihr/Ihnen"

### T-DE2: No English-influenced syntax
- **Match:** "lassen Sie uns ..." (literal "let us"), "am Ende des Tages" (at the end of the day)
- **Why fail:** translated American direct mail in German clothes

### T-DE3: No banned LLM-German tells
- `In der heutigen schnelllebigen Welt` (in today's fast-paced world)
- `tauchen wir ein` (let's dive in)
- `lassen Sie uns einen genaueren Blick werfen` (let's take a closer look)
- `entdecken Sie das Potenzial` (unlock the potential)
- `nutzen Sie die Kraft` (harness the power)

### T-DE4: DSGVO/compliance language present where required
- For PKV lead forms, landing pages: must include DSGVO consent language and "Ihre Daten sind sicher" or equivalent reassurance
- **Why fail:** compliance violation, not just style

### T-DE5: Naturalness LLM-judge score (German)
- **Prompt:** "If a 45-year-old German insurance broker or PKV-eligible employee read this aloud, would it sound (a) like professional, dignified, native German [8-10], (b) like a translated American sales letter [5-7], or (c) robotic / AI [1-4]? Score 1-10."
- **Pass threshold:** ≥ 8

---

## English (EN) tests — for IA Outreach cold email

### T-EN1: No "Hope this finds you well" openers
- **Match:** "Hope you're doing well", "Hope this email finds you well", "Trust this finds you well"
- **Why fail:** banned cold-email opener, every prospect's spam-flag trigger

### T-EN2: No "Quick question" / "Quick favor" / "Got a minute?" openers
- **Match:** "Quick question", "Quick favor", "Got a minute", "Got a sec"
- **Why fail:** every cold-email tool uses these — instant filter trigger

### T-EN3: Subject line ≤ 60 characters and lowercase-friendly
- **Match:** subject > 60 chars OR Title Case Like A Newsletter
- **Why fail:** higher open rates for short, lowercase, conversational subjects in cold outreach

### T-EN4: P.S. exists in cold emails
- **Match:** cold email with no P.S. line
- **Why fail:** P.S. is the second-most-read element after subject — always use it

### T-EN5: One CTA, not three
- **Match:** more than one ask / link / question per email
- **Why fail:** multiple CTAs reduce conversion — pick one

### T-EN6: No corporate filler
- **Match:** "synergy", "circle back", "touch base", "leverage", "best practices", "thought leadership"
- **Why fail:** these are <id> cliches that prospects ignore

### T-EN7: Personalization actually exists
- **Match:** generic openers with no specific reference to the prospect's company, role, or recent activity
- **Why fail:** if it could be sent to anyone, it'll convert like spam

---

## Structural tests (all formats)

### T-S1: Headline length per platform
- **Meta primary text:** no individual paragraph over 4 lines
- **Meta headline:** ≤ 40 chars
- **Meta description:** ≤ 30 chars
- **Google RSA headline:** ≤ 30 chars (hard API limit)
- **Google RSA description:** ≤ 90 chars (hard API limit)
- **Email subject:** ≤ 60 chars
- **LinkedIn first line (the "see more" cutoff):** ≤ 140 chars

### T-S2: Variant differentiation
- **Match:** variant A and variant B share >70% of words OR use the same big idea OR use the same visual structure (all prose / all bulleted)
- **Why fail:** they're not real variants, they're rewrites — defeat the purpose of A/B
- **Fix for Meta ads:** use different structures across the 3 variants (bulleted / prose / Q&A)

### T-S3: One big idea
- **LLM-judge:** "Can you summarize the angle of this piece in one sentence? If you need two sentences, the piece has too many ideas."
- **Why fail:** muddled positioning

### T-S4: CTA exists, is specific, and matches awareness level
- **Match:** missing CTA, vague CTA ("learn more"), or mismatched CTA ("buy now" to a cold prospect)
- **Why fail:** broken funnel

---

## Meta ad structural tests (when using bullets)

### T-M1: Bullet content is concrete
- **Match:** bullets containing only adjectives or vague qualifiers ("Schnell und einfach", "Modern und professionell", "Individuelle Lösung")
- **Why fail:** adjective stacks are the #1 AI-tell in bulleted ads — humans use bullets for concrete benefits, features, or friction removal
- **Fix:** replace with a specific benefit, feature, or outcome ("Ohne Kündigung", "In 60 Sekunden", "Bis zu 350€ Ersparnis")

### T-M2: Bullet count
- **Match:** more than 4 bullets OR fewer than 3 bullets in a bulleted variant
- **Why fail:** 3-4 bullets is the feed sweet spot — more becomes a listicle and kills scan rate, fewer feels incomplete

### T-M3: Bullet length
- **Match:** any bullet longer than 7 words
- **Why fail:** feed scannability breaks when bullets wrap to 2 lines on mobile
- **Fix:** compress to 3-6 words, move detail to proof line below the bullets

### T-M4: Bullet redundancy
- **LLM-judge:** "Do any two bullets express the same concept with different words? If yes, which ones?"
- **Why fail:** repeating the same idea wastes the scan budget and signals AI-generated content

### T-M5: Variant structure diversity
- **Match:** all 3 Meta variants use the same visual structure (all bulleted / all prose / all Q&A)
- **Why fail:** META.md Step A.2 requires different structures per variant for real A/B testing
- **Fix:** rewrite at least one variant in a different format

---

## How the agent uses this file

```
1. Read .claude/agents/copywriter.tests.md
2. For each test applicable to the language/platform of the draft:
   - Run the match
   - Mark PASS or FAIL
3. If any FAIL → revise the failing parts only, increment iteration, re-test
4. After all PASS → run LLM-judge naturalness score
5. If score ≥ 8 → deliver
6. If score < 8 → revise for naturalness, increment iteration, re-test
7. Cap at 5 iterations. After cap, deliver best version with explicit failures listed.
```

---

## Adding new tests

when you catch an AI-tell in delivered copy, add it here:

1. Pick the right section (Universal / HR / DE / EN / Structural)
2. Add a new test with:
   - Test ID (next number in sequence)
   - Match pattern (regex, exact phrase, or LLM-judge prompt)
   - Why it fails
   - Optional fix suggestion
3. The next time the agent runs, it will catch it

Don't delete old tests unless they're causing false positives. Better to over-catch than under-catch.
