## TL;DR
Rebuild each candidate's sequence position from the mail provider's send history, then resume every sequence at the next unsent touch instead of #1. The migration dropped the table that tracked who got which touch, so the agent assumed everyone was new. Restore or rebuild the progress table, add migration guards, and never run a destructive migration without a snapshot.

## The error
```text
Follow-up sequence restarted from email #1 for 200 candidates - the sequence-progress table was dropped in a migration
```

## Steps
1. Pause all sequences so no more #1 re-sends go out.
   Expected: sends stop immediately.
2. Restore the sequence-progress table from the latest pre-migration backup if one exists.
   Expected: candidate positions are back to their pre-migration values.
3. If there is no backup, rebuild positions from the send history: for each candidate-plus-sequence pair, the next touch is one past the highest touch number already sent.
   Expected: every candidate maps to the correct next touch, verified against a sample.
4. Resume sequences from the rebuilt positions and send a brief apology or value-add touch where a duplicate #1 already went out.
   Expected: candidates continue their sequence instead of restarting it.
5. Add migration guards: block destructive changes on tables holding live workflow state, and snapshot those tables before every migration.
   Expected: the next migration cannot silently drop progress again.

## Use this when
- An agent runs multi-touch follow-up sequences
- Candidates receive early-sequence emails they already got
- A migration, deploy, or schema change touched the database recently

## Not for this skill when
- The restart was intentional (a deliberate re-engagement campaign should say so in the copy)
- Sequences are stateless by design (then the bug is the design; add progress tracking)
- The duplicates come from a different sequence with similar copy (check sequence IDs before blaming the migration)

## Variant phrasings
- follow-up sequence restarted from the beginning after migration
- sequence progress table dropped, candidates got email #1 again
- migration wiped email sequence state
- candidates receiving duplicate first-touch emails

## Why it happens
The migration treated the progress table as disposable schema and dropped it, but that table was live workflow state: the only record of where each candidate stood in their sequence. With the table gone, the agent's new-candidate query returned everyone, and the sequence logic did exactly what it was told: start from touch #1.

## Edge cases
- Touches sent during the blind window: rebuild from send history, not from the empty table.
- Candidates who replied mid-sequence: re-apply reply-based exits when rebuilding, or replies get followed up anyway.
- Schema renames: the guard should cover column renames that break the agent's queries too.
- Test migrations on a copy: a staging run would have caught the drop before production.

## Provenance

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