# Copy Critic

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 22-35 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 36-41 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 42-50 |
| [Hard Prerequisites](#hard-prerequisites) | Fail before scoring if any missing: | 51-62 |
| [Binary Checks](#binary-checks) | Any fail → REWRITE. | 63-84 |
| [Score Gate](#score-gate) | Only score after all binary checks pass. | 85-97 |
| [Output Format](#output-format) | Operating guidance and contracts for this section. | 98-111 |
| [Golden Before/After (imitate After)](#golden-beforeafter-imitate-after) | Map the draft to the nearest pair. | 112-259 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 260-266 |
<!-- END GENERATED: guide-map -->

## Purpose

Mandatory ship/rewrite gate before any draft is shown or saved. Mechanical lint
only kills tokens. This file kills clean-but-dead AI outbound.

Loop: brief → draft → **this critic** → mechanical `vf.copy.lint` → show.
Lint green is a floor. Critic SHIP is the craft gate.

For sequence-bound bodies use `vf.copy.lint(..., sequence_id=...)` or
`allowed_variables=` from `sequences.template_variables` — bare
`vf.copy.lint(text)` is standalone AI-draft only and false-flags real
enrichment vars. Backend `verify_copy` / `lint(llm=True)` score ≥ 7 is
mechanical only — it does not replace this critic.

## Use This When

- Any outbound body or subject is about to be shown to the user.
- Multi-step or sequence-bound drafts (always).
- After lint rewrites changed the body.

## Do Not Use This For

| Need | Use Instead |
| --- | --- |
| Em-dash, banned phrases, brackets, invent vars | `vf.copy.lint` (sequence-bound: pass `sequence_id=` / `allowed_variables=`) |
| Sequence topology / create_draft | `sequence_authoring.md` |
| AI structure catalog | `copy_ai_tells.md` |
| Personalization jobs | `copy.md` |

## Hard Prerequisites

Fail before scoring if any missing:

- Channel declared as one of: cold email (`email`), email reply (`reply_email`),
  LinkedIn connection (`linkedin_connection`), LinkedIn DM (`linkedin_message`).
  "Follow-up" is not a channel.
- Brief has audience, CTA, and either commercial economic value (make/save
  money or save time) or an explicit non-commercial outcome.
- Every recipient-specific claim is user-supplied or from enrichment /
  personalization evidence — never invented.

## Binary Checks

Any fail → REWRITE. Do not show.

| Check | Channels | Fail when | Fix |
| --- | --- | --- | --- |
| Swap test | email, reply, DM | Opener works after swapping company/person for a random ICP peer | Add mentionable hook or stay segment-honest |
| Parrot test | email, reply, DM | First sentence restates their title, mission, about-blurb, or bio | Drop bio echo; lead with mechanic/hook or offer |
| Preamble / tail | all | Announcement open ("wanted to reach out") or help-desk close | Cut; end on ask or soft-out |
| First + last | email, reply, DM | First+last alone do not carry why-now + ask | Rebuild: hook → mechanism → one ask |
| Mechanism | commercial email/DM | Only "streamline / drive outcomes" with no plain how | One concrete mechanism sentence |
| Economic value | commercial email/DM | Promise never lands on make money, save money, or save time | Rewrite the offer before polish |
| Density | all | Any sentence deletable with no meaning loss | Delete it |
| Rhythm | all | Three same-length sentences in a row or forced three-item list | Vary length; prefer one or two items |
| Voice | all | Press-release, chatbot, forced wit, no peer speaker | Peer operator voice |
| Connect-only | LI connection | Pitch, product, customers, URL, calendar, demo, multi-sentence VP | Reason only; optional "Would be great to connect." |
| CTA | email, reply, DM | Meeting-first without explicit user intent; multi-ask; vague chat | One low-friction legal ask |
| Proof | commercial email/DM | Invented customers/metrics or wrong peer scale | Real peer-scale proof or omit |
| AI structure | all | "Not X, it's Y", throat-clearing, dramatic fragments, bio echo | State the claim; load `copy_ai_tells.md` |
| Breakup soft-out | final/breakup email | Ask/offer without `, or <recipient-out>?` | Last sentence: offer, or soft-out? |
| New angle (reply) | reply_email | "Checking in / following up / circling back" with no new reason | Add one new reason or sharper offer |

## Score Gate

Only score after all binary checks pass. Rate 1–10 on each dim. Below 35/50:
rewrite. Do not show.

| Dimension | Question |
| --- | --- |
| Directness | Statements, or announcements? |
| Specificity | Survives swap test? (connect: real reason?) |
| Density | Anything cuttable? |
| Authenticity | Peer operator, or CRM/AI template? |
| CTA / goal | One legal low-friction ask? (connect: accept-only?) |

## Output Format

```text
REWRITE
Line: "..."
Replacement: "..."
Reason: one sentence.
```

```text
SHIP
One sentence: why a busy peer would act (or accept the connect).
```

## Golden Before/After (imitate After)

Map the draft to the nearest pair. If it looks like Before, rewrite.

### 1) Clean-but-dead commercial email

**Before (fail):**

```text
Hi {{first_name}},

I wanted to reach out because teams like {{company_name}} are navigating
complex GTM challenges. We help companies streamline prospecting workflows
and drive better outcomes.

Would it be worth a quick chat?
```

**After (pass):**

```text
Subject: SDR hiring

Hi {{first_name}},

Saw {{company_name}} has SDR roles open. We help GTM teams turn hiring
signals into routed prospect lists so reps spend less time building lists
by hand.

I can send a 3-step teardown for {{company_name}}. Should I send it, or is
SDR sourcing not a priority right now?

{{sender_first_name}}
```

**Why:** Before fails swap + mechanism + CTA. After has hook, how, one ask,
soft-out.

### 2) Bio-parrot personalization

**Before (fail):**

```text
Hi {{first_name}},

As a VP Engineering at {{company_name}} focused on shipping reliable AI
products, you know how hard evaluation can be. Loved your mission around
building trustworthy systems.

Happy to share how we help teams like yours.
```

**After (pass):**

```text
Subject: flaky judges

Hi {{first_name}},

{{personalization_note}}
We run eval harnesses so agent regressions show up before customer demos.

Want the short checklist we use for judge flakiness, or is eval tooling
already covered?

{{sender_first_name}}
```

(Note example: `Read your post on flaky LLM judges — the same-prompt different-score bit.`)

**Why:** Before restates LinkedIn. After uses a real note that ladders to offer;
empty note beats fake praise.

### 3) Meeting-first vs artifact ask

**Before (fail):**

```text
Hi {{first_name}},

Noticed you're hiring SDRs at {{company_name}}. We'd love 15 minutes to walk
you through our platform and see if it's a fit.

Does next Tuesday work for a quick call?
```

**After (pass):**

```text
Hi {{first_name}},

Saw {{company_name}} is hiring SDRs. We turn public hiring signals into
routed prospect lists so new reps aren't stuck in spreadsheet hell week one.

Should I send the 3-step teardown, or is list-building already owned?

{{sender_first_name}}
```

**Why:** First-touch meeting needs explicit user intent. After is one
reply-scale ask.

### 4) LinkedIn connection pitch vs reason-only

**Before (fail):**

```text
Hi {{first_name}}, we help GTM teams automate outbound from hiring signals
(CustomerA, CustomerB). Would love to connect and share a quick demo if useful.
```

**After (pass):**

```text
Hi {{first_name}}, saw {{company_name}} is hiring SDRs. Would be great to
connect.
```

**Why:** Connect is acceptance, not pitch. "Would love" fails lint; pitch fails
connect-only.

### 5) Checking-in reply vs new angle

**Before (fail):**

```text
Hi {{first_name}},

Just checking in on my last note. Curious if you had a chance to take a look.
Happy to find time if helpful.

{{sender_first_name}}
```

**After (pass):**

```text
Hi {{first_name}},

One sharper cut: teams hiring 3+ SDRs usually lose a week per rep to manual
list building before first dials. I can send how {{company_name}} could route
that from the job posts alone. Want it?

{{sender_first_name}}
```

**Why:** Follow-ups add a new reason. Check-ins are CRM texture.

## Related References

| Reference | Use When |
| --- | --- |
| `copy.md` | Brief, channel shapes, lint, personalization execution |
| `copy_ai_tells.md` | Still synthetic after binary checks |
| `sequence_authoring.md` | Saving steps after SHIP + mechanical pass |
