auto-research-public
Autonomous cold email campaign launcher. Takes one target company domain, scrapes their…
Turns the raw first-name field on a lead row into the name a person would actually be greeted by, so it can open an email. Triggers on "clean these first names", "first name variable", "the greeting says Hi DR MATTHEW", "strip the titles off the names", "some rows have the whole
$ npx -y skills add growthenginenowoslawski/coldoutboundskills --skill playbook-first-name-cleaning --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/playbook-first-name-cleaningContext preview
The summary Claude sees to decide when to auto-load this skill.
Turns the raw first-name field on a lead row into the name a person would actually be greeted by, so it can open an email. Triggers on "clean these first names", "first name variable", "the greeting says Hi DR MATTHEW", "strip the titles off the names", "some rows have the whole
name: playbook-first-name-cleaning description: Turns the raw first-name field on a lead row into the name a person would actually be greeted by, so it can open an email. Triggers on "clean these first names", "first name variable", "the greeting says Hi DR MATTHEW", "strip the titles off the names", "some rows have the whole name in the first-name column", "normalize first names for the campaign". Outputs first_name_clean, one short string per row.
> All rules here are best practice, not law. Override any of them when the campaign calls for it; note the best practice once and move on.
**Use when:** any campaign whose email opens with the prospect's first name, which is every campaign anyone runs. Run it next to the company-name clean, **before any other custom variable**, because variables often interpolate the cleaned name.
**Do not use when:** you need the company name cleaned — that is `playbook-company-name-cleaning`, its twin, built to the same shape on purpose. Also not for finding a missing name. This playbook never looks anything up; a blank stays blank.
**One-line output:** `first_name_clean = "Ruba"` from the raw string `"Dr Ruba"`, so the email opens `Hi Ruba,` instead of `Hi Dr Ruba,`.
The first name is the first word of the email and the single most visible tell that a message was mail-merged. Lead databases store it the way a scraper found it, which is not the way anyone wants to be greeted. Real strings from a live contacts table:
`Dr Matthew` · `PAUL` · `javonne` · `👋 James` · `★ Marc` · `Kathryn (Katie)` · `Robert wilkie` (last name Wilkie) · `Araceli'S` · `Dr Sean Li We Are Actively Hiring At Antai Global` · `AAA` (at company AAA Upholstery) · `Admin` · `O.` · `Gowinder ` with a trailing space · and rows where the field is simply NULL.
Every one of those, pasted into `Hi {{first_name}},`, either looks broken or is not a person.
This playbook takes that string, plus the row's last name and company for context, and returns the short spoken form. It strips honorifics, credential suffixes, emoji and decoration, appended job titles and hiring notices, and possessive artifacts. It fixes shouting and all-lowercase. It picks the nickname when someone wrote one in parentheses. It refuses to mangle hyphenated and apostrophe names.
It explicitly does **not**: look the person up, translate or transliterate, expand an initial into a guessed name, split a run-together name into two words, or invent a letter not already in the input.
**Why the last name and company are inputs.** They are free, and they carry the only information that settles the hardest case. `ATC` alone is undecidable. `ATC` with last name `Systems` at company `ATC` is obviously not a person.
| Field | Type | Required? | |---|---|---| | `first_name_raw` | string | yes | | `last_name_raw` | string | no, but free — it catches the duplicated-full-name and company-in-person-column cases | | `company_name_raw` | string | no, but free — the only reliable discriminator for short ALL-CAPS tokens |
**Pass the RAW strings, not the cleaned company name.** The model needs to see the mess.
| Field | Type | Example | Max | Null? | |---|---|---|---|---| | `first_name_clean` | string | `Ruba` | 20 target, 40 hard | no, `""` instead | | `changed` | boolean | `true` | n/a | no | | `confidence` | enum | `high` / `low` | n/a | no | | `needs_review` | boolean, **computed by the guards, not the model** | `true` | n/a | no |
**Abstain value:** `""`. Never `N/A`, never `null` as text, never `there`, never `friend`, never a guess. This is not negotiable: **`N/A` renders into a live email as `Hi N/A,`.**
Two numbers, because the benchmark is deliberately adversarial and the production rate is not the same thing.
rows shipped a copy-ready value, 24 were correctly withheld for review, **0 silent failures.** Model-only accuracy 96/100, and **69/73 (94.5%) on rows the prompt had never seen.**
blank 0.05%, ALL-CAPS 0.03%, starts lowercase 0.03%, honorific prefix 0.05%, mailbox role word 0.01%, parenthesis 0.00%, ≤2 characters 0.84%, any non-ASCII 1.08% (mostly ordinary accents, which are fine). **The genuinely broken share is 1 to 3 percent.**
which stay exactly as written.
**Exclude and review. A generic greeting is never the fallback.**
| Condition | What happens | |---|---| | `first_name_clean` is empty | **EXCLUDE the row**, route to review | | `needs_review` is true (any guard fired) | **EXCLUDE the row**, route to review | | the name is written only in a non-Latin script (`珊`, `Дарья`, `عبدالله`, `준식`) | **EXCLUDE from an English-language campaign**, route to review | | any of the above, and someone suggests a generic greeting | **No.** Never `there`, `friend`, `team`, `folks`, or the company name. Not by substitution, not by spintax |
**The non-Latin-script rule is an exclusion, not an abstain and not a transliteration.** The pipeline keeps the name **exactly as written** and sets `needs_review`. Transliterating would invent letters; blanking would destroy a real person's real name. About 6 of the 100 benchmark rows land here. Routing them to a native-language campaign is a legitimate operator move, and **the preserved name is what makes it possible.**
Why exclusion rather than a generic greeting: an empty or unusabl
Open-source Claude Code skills for cold email infrastructure, lead sourcing, copywriting, and operations. Built by GrowthEngineX from patterns across 1,000+ real B2B campaigns. 31 skills that work together.
Repo: growthenginenowoslawski/coldoutboundskills
Autonomous cold email campaign launcher. Takes one target company domain, scrapes their…
Use the Blitz API to find decision-makers at specific companies when you already have a list…
Creates cold email copy through a stepwise confirmation process. Use when writing email…
Generates 15-25+ cold outbound campaign ideas with targeting strategies, AI personalization…
Single "start here" orchestrator for new cold email operators. Asks infrastructure-status…
Complete beginner-friendly cold email toolkit. Walks from zero to launched campaign — domain…