# LeadPilot — Follow-Up Retry Policy

**Document Version:** 1.0.0 (Phase 9B)

---

## 1. Retry Strategy

LeadPilot uses bounded exponential backoff with a hard cap of **3 total attempts**.

| Attempt | Status After Failure | Reschedule Delay |
|---------|----------------------|------------------|
| 1st     | `scheduled`          | +5 minutes       |
| 2nd     | `scheduled`          | +15 minutes      |
| 3rd     | `failed` (permanent) | No retry         |

---

## 2. Transient vs Permanent Errors

| Error Type                  | Classification | Behaviour                          |
|-----------------------------|----------------|------------------------------------|
| Mail provider returns false | Transient      | Retry with backoff                 |
| Exception thrown by provider| Transient      | Retry with backoff                 |
| Max attempts (3) reached    | Permanent      | status → `failed`, activity logged |
| Missing template            | Permanent      | Fails immediately (no retry)       |

---

## 3. Stuck Job Recovery (Processing Lease)

If a worker process dies after claiming a follow-up but before completing:

- The follow-up remains in `status = 'processing'`
- After **10 minutes**, `recoverStuckJobs()` resets it to `status = 'scheduled'`
- It will be picked up by the next cron execution

```sql
UPDATE follow_ups
SET status = 'scheduled'
WHERE status = 'processing'
  AND processed_at < NOW() - INTERVAL 10 MINUTE;
```
