warmbox/docs/04-warmup-recipes.md

126 lines
3.3 KiB
Markdown

# Warmup Recipes
Four recipes control **how many emails the primary receives/sends per day** over the campaign duration.
## Global constraints (all recipes)
| Parameter | Default | Min | Max |
|-----------|---------|-----|-----|
| Duration | 30 days | 14 | 45 |
| Min emails/day | 1 | 1 | — |
| Max emails/day | 40 | — | 50 |
| Reply rate | 30% | 10% | 45% |
| Volume change cap | +20% / 48h | — | Industry best practice |
## 1. Grow — Progressive (recommended)
**Use when:** New domain or cold mailbox. Safest default.
### Behavior
- Start at `minEmailsPerDay` (default 1) on day 1
- Increase daily toward `maxEmailsPerDay` over `durationDays`
- Never increase more than 20% vs prior 48h average
- After reaching max, hold flat until campaign end
- Optionally continue background warmup post-campaign at 20% of max
### Algorithm (pseudocode)
```
totalGrowthDays = durationDays * 0.7 // reach max by ~70% of campaign
dailyIncrement = (maxEmails - minEmails) / totalGrowthDays
for day in 1..durationDays:
target = minEmails + floor(dailyIncrement * min(day, totalGrowthDays))
target = min(target, maxEmails)
target = cap48hIncrease(previousTargets, target, 0.20)
schedule[day] = target
```
### Example (30 days, min=1, max=40)
| Day | Planned sends |
|-----|---------------|
| 1 | 1 |
| 7 | ~8 |
| 14 | ~18 |
| 21 | ~30 |
| 24+ | 40 |
## 2. Flat
**Use when:** Mailbox already warm; maintain reputation during live outreach.
### Behavior
- Constant `maxEmailsPerDay` every day
- No ramp
- Same reply rate and rescue rules
```
schedule[day] = maxEmailsPerDay // for all days
```
## 3. Randomized
**Use when:** Experimentation; avoid perfectly predictable patterns.
### Behavior
- Daily volume random within `[minEmailsPerDay, maxEmailsPerDay]`
- Weighted toward middle of range (normal distribution)
- 48h spike cap still applies
- Seed per campaign for reproducibility (debugging)
```
schedule[day] = randomInt(min, max, seed=campaignId+day)
schedule[day] = cap48hIncrease(...)
```
## 4. Custom
**Use when:** Expert operators want per-day control.
### Behavior
- User defines array: `[{ day: 1, sends: 2 }, { day: 2, sends: 5 }, ...]`
- Validate: each value within [min, max], length ≤ durationDays
- Missing days: hold last defined value or interpolate (configurable)
- UI: spreadsheet-style editor + import CSV
## Recipe selection API (future)
```json
{
"recipe": "grow",
"durationDays": 30,
"minEmailsPerDay": 1,
"maxEmailsPerDay": 40,
"replyRatePercent": 30
}
```
## Dispatcher integration
1. Load active campaigns
2. For each campaign, read `DailySchedule` for today
3. If `actualSends < plannedSends`, schedule next send slot with jitter
4. Pick satellite from `CampaignSatellite` (weighted random)
5. Primary is always receiver for satellite→primary sends; primary may send replies back
## Post-campaign
| Mode | Behavior |
|------|----------|
| Complete | Stop sends; mark campaign `completed` |
| Maintenance | Switch to Flat at 20% of max (recommended) |
| Pause | Operator pause; resume later |
## UI copy (recommended labels)
| Recipe | Label | Subtitle |
|--------|-------|----------|
| grow | Grow | Progressive ramp — recommended for new mailboxes |
| flat | Flat | Steady volume — for already-warm inboxes |
| randomized | Randomized | Variable daily volume — for testing |
| custom | Custom | Define your own day-by-day schedule |