- • step.do() = durable retry · resumes after Worker restart
- • step.sleep(30m) covers NS mirror-back lag (ADR-019)
- • step.waitForEvent gates step 7 on admin decision
- • Each step row-mirrors into annual_roll_runs (migration 035)
- • Tight retry policy: D1 3× linear · AI 2× exp · Queue 5× exp
- • Snapshot outgoing SY to price_history (immutable later)
- • Derive next-SY prices from CME + index inputs
- • Apply customer programs / rebates / ladders
- • Flag outliers above drift_threshold_pct (default 15%)
- • Generate per-customer + per-vendor preview packets
- • Email Mike (ADMIN_EMAIL) with roll summary + packet links
- • step.waitForEvent('admin_decision') · no timeout
- • Decision payload: {decision, notes, decided_by}
- • Standing invariant: HITL on every NS write
- • Lock price_history rows for outgoing SY
- • Enqueue NS_PUSH_QUEUE · OAuth1 TBA writes
- • 30-min sleep, then compare D1 ↔ NS mirror
- • Mark run complete OR record drift in annual_roll_runs
- • Cutover effective_from = cutover_date (default 2026-07-01)