# Outreach agent re-contacted opted-out candidates from an old campaign

## TL;DR
The agent re-emailed people who opted out because the suppression list was a spreadsheet nobody loaded into the sending pipeline. Fix: move the do-not-contact list into the system the agent queries before every send, and make the suppression check a blocking gate. A list the send path never reads is not a suppression list.

## Error
```text
outreach agent re-contacted candidates from a 6-month-old campaign  -  the do-not-contact suppression list lived on a spreadsheet nobody loaded, so the opt-outs were never honored
```

## Steps
1. Export the spreadsheet and count the entries; then check how many of those addresses appear in recent sends.
   Expected: you know exactly how many opt-outs were violated.
2. Import the list into your sending system or a suppression table the agent can query: email (lowercased, trimmed), opt-out date, source. Dedupe on the normalized email.
   Expected: one authoritative list, no duplicates.
3. Add a blocking gate in the send flow: normalize the recipient, check suppression, abort the send on a hit, log the skip.
   Expected: a suppressed address can never be sent to, no matter which campaign or agent tries.
4. Retire the spreadsheet: point everyone who used to edit it at the new list, and mark the old file clearly so it stops being "the list" in anyone's head.
   Expected: one source of truth.
5. Test with a suppressed address and a fresh address.
   Expected: suppressed aborts with a logged skip; fresh sends normally.

## Use this when
- opt-outs get emailed again
- suppression data lives in spreadsheets, docs, or someone's inbox
- multiple agents or campaigns share one audience
- compliance wants proof of honoring opt-outs

## Not for this skill when
- the suppression list was loaded but the check ran after the send (that is ordering)
- the opt-out arrived as a reply the classifier missed (that is the reply-classifier problem)
- the candidate never opted out and just got too many emails (that is frequency policy)

## Variant phrasings
- "suppression list not loaded"
- "opted-out candidates emailed again"
- "do not contact list ignored by agent"
- "unsubscribe spreadsheet never synced"

## Why it happens
The spreadsheet was the process for a human team, and nobody rebuilt the process when the agent took over sending. The agent can only enforce rules that live in systems it reads; a file on someone's drive is invisible to it. Every manual list that matters to sending must become a queried table with a blocking check.

## Edge cases
- Emails change; also suppress on candidate ID or phone where you have them, not email alone.
- Keep the opt-out record even if the candidate later re-applies; stopping outreach is separate from recruiting them inbound.
- If the list updates from a form, the gate must read the live table, not a cached copy.
- Log every suppressed skip; auditors ask for this.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_lEq1KDliOs3JFOTpTPQBNA
