Set by Aga, 31 July 2026. Governs every email the retention rail sends or drafts from
hello@themovementathlete.com: R1 cancel-save, the T-30 watcher, dunning/payment-recovery, failed-purchase, reply-fulfilment, concierge, upgrade stages โ and any lane added later.The one sentence that decides every question below:
It has to look like Jesse just typed it.
These emails work because they are indistinguishable from a personal message. Every rule here exists to protect that. When a new idea conflicts with it, the idea loses.
Two completely different systems share the word "email". Never apply one's rules to the other.
| hello@ 1:1 rail (this document) | Marketing estate (ActiveCampaign / Customer.io) | |
|---|---|---|
| What | Personal notes from Jesse to one member about their account | Campaigns, sequences, broadcasts |
| Looks like | A person typed it | A designed email |
| Governed by | This file | CLAUDE.md EMAIL RULE โ /email-fleet, locked footer, email_lint.py, white canvas, design guide |
| Template | None. Ever. | Canonical template, mandatory |
| Sent by | Gmail API from hello@ | AC / CIO |
Running these through the marketing fleet would destroy the thing that makes them convert. Running marketing emails under these rules would fail the lint gate. Keep them separate.
No bold. No underline. No italics. No colour, no headings, no dividers, no images, no logo, no footer bar, no background colour, no buttons. A person writing to one other person uses none of these. (Aga, 31 Jul: "remove the bold so it really looks like Jesse just typed it.")
The renderer supports **bold** / _italic_ / __underline__ markers โ do not use them in
lane copy. They exist only so a future exception can be made deliberately, not by drift.
Note the deliberate difference from the marketing law. The estate rule ("bold the key line, italic the human beats, one underline") is correct for campaigns and wrong here. Same goal โ easy reading โ opposite means: in a personal email, readability comes from short paragraphs, not from formatting.
This is how people actually type, and it is the ONLY readability tool available under rule 1. Never stack the bad news, the reassurance and the instruction into one block. Break them.
(Aga, 31 Jul: "make a link an actual clickable link โ instead of a dead link they need to copy
and paste.") A URL sitting on its own line becomes a real anchor.
- Standard link blue #1155cc โ Gmail's own. Not a brand colour: branded links read as
a campaign at the exact moment we need trust.
- Keep the โ arrow โ under rule 1 it is the only visual cue the text is clickable.
- Built automatically by r1_lib.build_message() / text_to_html(). Never hand-build MIME.
Never "click here" (generic, tests poorly). Never over-promise what the first screen shows.
- Dunning โ Fix your billing โ โ task-framing. It must NOT say "Update your card",
because the link lands on the Stripe login page (enter email โ Stripe sends a sign-in
link โ then the card form). Promising a card form and delivering a login box creates doubt
on a billing page, which costs more than any click-rate gain.
- R1 cancel-save โ Keep training โ โ outcome-framing. They chose to leave; administrative
language reads as the process they already rejected. The email's real goal is a reply.
- Different lanes get different anchors on purpose โ the member's psychological state
differs. Any new anchor goes through the email-copywriter agent first.
text/plain (markers stripped, bare URL) + text/html (the clickable twin). Non-negotiable:
- plain-text clients and forwards must work;
- send_payment_drafts.needs_aga() reads the plain part โ lose it and the safety gate goes
blind (audit finding L1);
- a body with no link stays pure plain text โ no HTML part at all (e.g. failed-purchase
notes, guardian alerts). Don't add HTML for its own sake.
Reply-to is always hello@, a human reads it, and the copy says so. Where a lane can convert on
a reply instead of a link (failed-purchase: "hit reply and I'll send you a fresh link"),
prefer the reply โ it has no links to distrust and it starts a conversation.
Every lane's subject must be watched by reply_fulfil.py so STOP suppresses and a live
reply is surfaced. (This was missing until 31 Jul โ audit finding C1.)
Jesse
Head Coach, The Movement Athlete
--
You're receiving this because <the specific reason>. This isn't a marketing campaign.
Reply STOP and I won't email you about it again.
Jesse is Head Coach, never "founder". Say why they're getting it, in one honest clause. The STOP promise is real โ rule 6 makes it work.
Copy branches on the actual failure reason (bank block vs card details). No invented urgency, no fake deadlines, no claims we haven't verified. If we caused it, say so.
Every member-facing message is a Gmail draft waiting for Aga. Three explicit exceptions โ
the R1 T-30 watcher, the upgrade stages (both --live, templated pre-approved copy), and the
14-hour auto-send rule scoped to the dunning lane only. A new lane arms drafts-only.
Aga's pre-flight law: run the copy through the email-copywriter (CRO) seat, audit the whole
job family for bugs, document it into the register + cockpit โ then arm.
| Thing | File |
|---|---|
| Renderer (multipart, links, markers) | tools/retention/r1_lib.py โ build_message() ยท text_to_html() ยท strip_markup() |
| Dunning copy + anchor | tools/retention/payment_recovery_lane.py (BODIES, make_draft) |
| R1 copy + anchor | tools/retention/copy/seg-*.txt ยท send_r1.py ยท pre_expiry_watch.py |
| Failed-purchase copy | tools/retention/failed_purchase_lane.py (no links โ reply mechanic) |
| Reply + STOP capture | tools/retention/reply_fulfil.py (PAYMENT_SUBJECTS) |
| Safety gate | tools/retention/send_payment_drafts.py (needs_aga) |
Canonical companions: docs/company/GOVERNANCE/AUTOMATION_JOB_REGISTER.md (what each lane
does) ยท JOB_AUDIT_FINDINGS_2026-07-31.md (known bugs + open items).
Changing any rule here changes what a real member receives. Update this file in the same session, or it is drift.