Your pre-send checklist has not been opened in months.
A send reached the list addressed to {{first_name}}.
Your pre-send checklist has not been opened in months.
A client send went out with a merge tag that never resolved. Subscribers opened an email addressed to {{first_name}}. The checklist that would have caught it existed. In my experience, it lived in a Notion doc that had not been opened since the last hire. The person responsible knew the items by memory. Or thought they did. Two items got skipped on every send. Neither had caused a visible failure yet. This one finally did.
Why Manual Checklists Fail Under Time Pressure
Pre-send checklists are one of those things that look like a system but operate more like a habit that erodes under pressure. In my audits I often find that teams have a checklist. It lives in a Notion doc, a shared Google Sheet, or a sticky note in the deployment folder. It was thoughtfully built. The problem is that it requires a person to open it, read it, and actually check each item against the live email at exactly the moment when that person is under the most deadline pressure of the week.
Time pressure compresses judgment. The first few items on any checklist get attention. The middle gets a skim. The bottom gets a mental checkmark without verification. Legal items, always low on the list because they feel routine, often get the least scrutiny. The unsubscribe link is there. The physical address is in the footer. Probably. The checklist was designed for a calm environment and deployed into a chaotic one.
A team I work with sends three campaigns a week. The manual checklist had not been opened in four months by the time I audited the program. The person responsible knew the items by memory. Or thought they did. The process had quietly collapsed into habit. When I asked them to walk through a recent send using the checklist retroactively, they found two items they had been routinely skipping: preview text character count and merge tag fallback verification. Neither had caused a visible failure yet. Both are the kind of thing that fails slowly and expensively.
The prompt version removes the habit dependency. You paste the HTML. The prompt fails closed without it. Six categories validated. Every flag cites a line number or verbatim quote. Then the prompt stops at the human gate and waits for your decision.
Where the QA Prompt Sits
The prompt follows the four-mechanism Remint Prompt Pattern: prerequisites (HTML source and target ESP), self-validation (every flag cites evidence), human gate (operator decides what blocks send), and improvement proposal (recurring failures become candidate hooks).
The mechanism that matters most here is the human gate. The prompt does not auto-fix and does not auto-send. It returns the findings and stops. The operator decides which flags block the send and which can ship with a documented exception. Decision authority stays with the human at the most expensive point in the workflow.
The Six-Category QA Prompt, Full Wrapper
Paste it into Claude with your email HTML at the bottom. The prompt itself is self-contained. No prior context needed beyond your VOICE.md if you also want voice checks layered in.
## Prerequisites (required before running)
- Email HTML source (exported from ESP, not a screenshot)
- Target ESP name (Klaviyo, HubSpot, Mailchimp, custom)
If either is missing, do not proceed. Respond:
"Cannot run. Missing: [list]. Provide and re-run."
## Inputs
Target ESP: [ESP NAME]
Email HTML: [PASTE FULL HTML INCLUDING HEAD AND FOOTER BELOW]
## Task
Run a pre-send QA across six categories. For each, return PASS or FAIL.
For every FAIL, cite the specific instance with a line number or verbatim
quote. No summary verdicts. Specific evidence per flag.
Categories:
1. Personalization
- Merge tags have fallbacks declared
- No unclosed {{variable}} strings
- Fallback syntax matches the target ESP's expected pattern
2. CTA
- One primary action present
- Button text names the action, not the outcome
- Links do not chain through more than one redirect domain
3. Legal
- Unsubscribe link present with a real URL (no placeholders)
- Physical mailing address present in footer
4. Mobile
- No element wider than 600px in inline styles or CSS rules
- No body font smaller than 14px
5. Dark mode
- No hard-coded hex color on text without a
@media (prefers-color-scheme: dark) override
- No transparent background images on hero or content blocks
6. Preview text
- Present in a hidden preheader element
- Under 100 characters
- Does not repeat any word from the subject line
## Self-validation (run before returning output)
Before returning, check:
1. Every category returns PASS or FAIL
2. Every FAIL cites a line number or verbatim quote
3. No category marked PASS unless every check in that category ran
4. No suggestions outside the six categories above
If any check fails, fix internally. If you cannot satisfy a check after one
attempt, return:
"Validation failed: [rule]. Cannot produce compliant QA report."
## Human gate (before any change is applied)
After returning the findings, state:
"Review the QA report above. Type APPLY to block this send and queue the
flagged fixes for revision, or OVERRIDE [category] with a documented
exception note for any category you accept as-is."
Do not modify the HTML. Do not mark the send as ready. The operator
decides what blocks send and what ships with a tracked exception.
## Improvement proposal (optional)
If a recurring failure pattern appears across this run that is not in the
six categories above, append:
"PROPOSED RULE ADDITION (review before adding to a pre-commit hook):
[one line describing the pattern]"
Do not modify the QA prompt itself.The output is structured: one section per category, a verdict, and for any failure, the specific instance cited by line or quote. Not a summary. The exact broken merge tag, the exact redirect URL, the exact hex value without a media query override. That specificity is what makes it actionable rather than confirmatory.
Running It on the HTML
Run it on the HTML, not on a screenshot, not on a rendered preview, not on the text version. The issues this prompt catches are structural issues in the markup. Screenshots do not carry markup. A rendered preview will not show you that {{first_name}} has no fallback attribute. It will show you a name if your preview is populated with a contact record. In production, unpopulated records break.
Export the HTML from your ESP before the send. In Klaviyo, the "View source" option in the email editor. In Mailchimp, the code view. In any custom deployment, the file you are actually sending. Paste the full markup after the prompt. Do not abbreviate it or paste only the body section. The legal items, preview text, and some mobile constraints live in the head and footer, which get stripped if you only copy the visible content area.
The prompt does not require the email to be fully built. Running it on a near-complete draft at 80 percent done is useful. Structural issues surface early rather than at the send moment. Many teams find that running it twice produces more value than running it once: once at draft review stage, and once on the final exported HTML immediately before sending.
Category Breakdown: What Gets Validated
Personalization integrity. The most common failure here is a merge tag without a fallback. In most ESPs, merge tags accept a default value inside the tag syntax: something like {{first_name | default: "there"}} in Liquid, or a fallback field set in the merge tag configuration. Without a fallback, an unmatched contact record renders the raw tag string in the email. Claude flags any tag structure that lacks a fallback attribute and quotes the instance with its line number.
CTA structure. The category checks for a single primary action, not multiple competing calls to action. It also checks button text: the action, not the outcome. "Get your report" passes. "Unlock email growth" fails because it describes an outcome the click cannot verify. It also checks for redirect chains, which matter for deliverability. A link that routes through two or three tracking domains before reaching the destination is a pattern some spam filters treat as evasive.
Legal. Unsubscribe link and physical mailing address. Not negotiable under CAN-SPAM and most comparable legislation. The check looks for their presence in the HTML. If the unsubscribe link is there but broken (a placeholder URL, a mailto with no address), it is flagged. The physical address check looks for any block of text structured like a postal address in the footer area.
Mobile layout. Two hard constraints: fluid-widths for elements and no body font smaller than 14px. Both are stated in inline styles or CSS rules in the HTML, so the check reads them directly. The 14px minimum is the point below which text becomes impractical to read without zooming on a standard phone screen.
Dark mode. The check is for hard-coded hex colors on text elements without a corresponding media query override. When a dark mode client inverts backgrounds, hard-coded light text on a now-dark background disappears. The partial fix is a @media (prefers-color-scheme: dark) override. Partial because some email clients will auto invert anyway, with no way for you to control it. The prompt flags any color: # declaration on a text element that does not have a corresponding dark mode rule. It also flags transparent background images, which invert poorly in forced dark mode rendering.
Preview text. Three checks: present, under 100 characters, and not a repeat of the subject line. Preview text that echoes the subject line wastes the second line of visible real estate in the inbox. Under 100 characters is a practical limit based on what mobile clients display before truncating. The check reads the preview text from the hidden preheader element in the HTML and validates all three conditions.
What Good Output Looks Like
A clean result is six PASS verdicts with a one-line confirmation per category. "Personalization: PASS. All merge tags have fallbacks. No unclosed variable strings." That is the output you want immediately before sending.
A flagged result is more specific. Personalization: "FAIL. Line 47: {{customer.first_name}} has no fallback value." CTA: "FAIL. Button text reads 'Transform your email results': describes outcome, not action. Link at line 91 routes through two redirect domains before reaching destination." Legal: "FAIL. No physical mailing address found in footer."
The prompt quotes the specific instance rather than summarizing the category of problem. That instruction matters because a summary lets you assume you know what it means. A quote forces you to go to that exact line and fix that exact thing. The output is designed to be a work order, not a report.
If the result is a mix of passes and fails, fix the fails and run the prompt again on the updated HTML. Two passes, maybe three on a complex email, is the full workflow. The total time investment is less than a thorough manual review, and the coverage is consistent across every send.
Building This Into Team Workflow
For teams sending frequently, the prompt replaces the manual checklist as the final gate before deployment. Workflow: export HTML, paste into Claude with the prompt, address flagged items, re-export, run once more, send. The checklist document can be retired or kept as training documentation for new team members to understand what each category covers and why.
For teams where multiple people touch an email before it sends, the prompt can be run at handoff rather than only at send time. When the designer hands to the developer, run it. When the developer hands to the deployment operator, run it again on the final exported version. Running it at handoff catches structural problems before they compound.
The improvement-proposal block at the end of the wrapper is where this gets more powerful over time. When a specific failure pattern keeps showing up across QA runs (a particular ESP's merge tag syntax, a recurring dark mode issue from a designer who keeps using the same template), the proposal lines accumulate. The operator commits the recurring ones as pre-commit hooks. The hook catches them before the QA prompt ever runs. The QA prompt then catches whatever the hook missed. Coverage compounds.
The prompt does not require modification for different email types. It runs the same six categories against a promotional campaign, a transactional email, an onboarding sequence, or a newsletter. Some categories will be more relevant than others depending on the email type, but a universal checklist is more reliable than a type-specific one because it closes the gap where a sender decides a check "probably doesn't apply" to this particular send.
Audit Checklist
Export the raw HTML from your ESP before running the prompt, not a screenshot or text preview
Paste the full HTML including the head section, not just the body or visible content area
Check that every merge tag in the email has a fallback value set in the HTML syntax
Verify the CTA button text names the action, not the outcome
Confirm the unsubscribe link uses a real URL, not a placeholder or broken href
Confirm a physical mailing address is present in the footer
Check that no element inline style or CSS rule sets a width greater than 600px
Check that no body copy font-size is set below 14px
Verify that any hard-coded hex color on text has a corresponding prefers-color-scheme dark override
Confirm preview text is present, distinct from the subject line, and under 100 characters
If any category fails, fix the specific flagged instance and re-run the prompt on the updated HTML before sending

