warmbox/docs/sprints/sprint-1.4.md

1.4 KiB

Sprint 1.4 — Reply Rate Engine

Probabilistic reply sampling so warmup mimics real mailbox engagement (~30% default, max 45%).

What shipped

  • engaged_no_reply status on WarmupStatus enum
  • reply-rate.service.tsshouldReply(), getTodayReplyStats(), simulation helper
  • Campaign rescuer samples replies; non-replied messages still get read/flagged/spam-rescue
  • Hard daily cap — skips reply when actualReplies >= plannedReplies
  • Spam countersspamDetected / spamRescued increment on rescue
  • WarmupLog.placementinbox or spam
  • POST /api/jobs/rescuer/run — manual rescuer trigger

Algorithm

Per docs/07-reply-rate-engine.md:

  1. If daily reply quota met → skip
  2. If actual rate ≥ target → skip
  3. Else probabilistic bias: probability = needed / remaining

Manual QA

# Start campaign, dispatch sends, then run rescuer repeatedly
curl -X POST http://localhost:3000/api/jobs/dispatcher/run -H "x-api-key: $API_KEY"
curl -X POST http://localhost:3000/api/jobs/rescuer/run -H "x-api-key: $API_KEY"

# Check mix of complete vs replied logs
curl "http://localhost:3000/api/logs?campaignId=<id>" -H "x-api-key: $API_KEY"

Expect some logs with engaged_no_replycomplete and reply rate trending toward replyRatePercent.

Key files

  • src/services/reply-rate.service.ts
  • src/jobs/rescuer.job.ts