Strategy Commander
How AutoPilot strategies work: the lifecycle journey model, the block grammar, versioning, and how the Strategies and Fulfillment views fit together.
1 · The Lifecycle Model
A strategy is a journey definition that a ticket-lot travels from purchase to a terminal state. It is not a bag of cron jobs and not a single waterfall — it is one spine with two anchors and an explicit end:
Anchors
| ANCHOR | SOURCE | ROLE |
|---|---|---|
| PO created in Reach (entry) | PurchaseCreate webhook → PG mirror (~1s); reconciled via GET /purchases?updatedDateSince= | The journey starts the moment tickets exist in Reach. Reach is truth. Which strategy claims the PO is resolved by the assignment model (§3). |
| Event date/time (end-side) | Reach event record; venue-local time, timezone inferred carefully | All T− offsets resolve against it. If the event date changes (postponement), pending timers re-resolve automatically. |
Three timing regions
Between the two anchors, blocks live in one of three regions — this is the core organizing principle of every strategy:
- AFTER PURCHASE (T+) Immediately-after-purchase verification and
T+Xfollow-ups, offset from the purchase anchor. Example:Verify purchase data @ T+0h, full sweep atT+2d. - ONGOING (RECURRING) Periodic health checks in the gap —
every 24h,every 7d. Bounded by the two anchors, and auto-suppressed once the T− window opens so cruise checks never collide with the fulfillment push. - BEFORE EVENT (T−) The fulfillment driver — the
T−72hTT wallet-link window,T−48hretry checkpoint, SMP fallback, hard transfer, and deadline escalations — all offset from the event anchor.
Event-triggered branches hang off the spine and can fire at any point on the timeline: error categories raised, status changes, purchase-canceled signals, or criteria matches. Branch actions include the first-class Transition to strategy X (journey-to-journey handoff), retry flows, escalation, and jumps to terminals.
Terminal states — everything must end
Every journey instance ends in exactly one terminal state (Step-Functions-style Succeed/Fail). Nothing dangles — if a lot is neither fulfilled nor explicitly canceled/surrendered/refunded, the journey is still running and the system still owns it.
| TERMINAL | MEANING |
|---|---|
| Fulfilled ✓ | The goal state. Delivery confirmed via API refresh — never a UI scrape. |
| Canceled | Purchase or tickets canceled upstream; journey exits, no re-entry. |
| Surrendered / FVE | The destructive escalation tail. FVE buyback spends money; surrender burns TM bind count — both are approval-gated. |
| Refunded | Money returned; journey exits. |
2 · Block Grammar
Everything you place on the timeline is one of five block families (anchors are the spine itself, not palette blocks).
Triggers
- Time-relative —
T+ offsetafter purchase,every Nrecurring,T− thresholdbefore event. Offsets are per-instance because each PO/event pair differs. - Event-based —
Error category raised(the 28-category sweep playbook),Status change(AQ order transitions likedelivery_problem → delivered),Purchase canceled(ReachPurchaseEditwebhook), andCriteria matched(a condition set flips true → fire the branch's follow-up actions).
Conditions & the four property domains
Condition blocks select from four property domains — the segmentation vocabulary used at entry, on the spine, and inside branches:
| DOMAIN | EXAMPLE PROPERTIES |
|---|---|
| Event | event date/time, days-to-event, venue, venue override list (transfer_everything), performer, FIFA/MLB flags |
| Account | site (TM 92 / FIFA 11990), credential health (bad_creds and login_403 are distinct — never bucket together), last successful sweep age, bind count, proxy class, phone-line validity |
| Purchase | PO created date, vendor, order total, canceled flag, delivery method, tags (nofulfill…), P0–P3 priority band (48/168/336h thresholds) |
| Ticket | barcode present, stock type (ETicketUrl / GenericMobileTransfer / SMPWALLET / MobileQRCode), canceled flag, marketplace of sale, net-proceeds price band, link/transfer state |
Actions
All existing lane actions plus three lifecycle-native ones:
- Sweep account (AQ) —
POST /accounts/{id}/launch; success is verified only when the downstream purchase-order-detail agent completes. - Extract wallet links (TT) — idempotency key
{pos_event_id}_{sync_account_id}is a hard invariant (one task forever), 5 probes per new event, 50 global open-task cap, 30/60/300/900s poll backoff.NO_LINKS_CREATEDis a wait state, not an error. - Merge links / Deliver URL (AQ) — merged-parent-wins: once a merged parent exists, child URLs are never delivered. Unmerged delivery only where the marketplace allows (TickPick, TicketEvolution, TicketNetwork, Automatiq B2B).
- SMP fallback link — Reach stock type
SMPWALLET; SMP cannot split links across a group. - Hard transfer (Reach) —
GenericMobileTransfer, mandatory for bound-out and fraud-blocked accounts. - FVE / surrender escalation — the approval-gated destructive tail.
- Notify human — grouped Slack alerts, intervention queue; final grouped alert deferred while any account is pending/NEP.
- Verify purchase data (new) — immediately-after-purchase integrity checks: tickets present, barcodes, account linkage, AQ backmatch (barcode-first, geometry fallback only with uniqueness).
- Transition to strategy X (new, first-class) — remove the instance from this journey and enroll it in the target strategy at the equivalent lifecycle position. The audit trail records
from_strategy@ver → to_strategy@verwith the criteria snapshot. - Mark terminal (new) — jump straight to a terminal (e.g. on purchase canceled →
Canceled).
Guards
Cross-cutting invariants that wrap actions:
- Retry policy per error category — playbook flows (rotate → reset → cap), original + 2 automatic rehandles, 4-touch cap per account per day.
- NEP cutoff — Never-Ending Pending, 45m primary / 120m escalated.
- Cooldowns — TT restart
minutes_remainingis terminal-for-this-run; sweep cooldown is marketplace-account scoped. - Rate & volume caps — AQ 60 rpm default / 95 max, max sweeps per account per day, max TT creates per tick.
- Marketplace capability checks — MLB rejects transferless links; SMP can't split groups; domestic TM needs barcode readiness; venue
transfer_everythingoverrides. - Autonomy level — dry-run / approve-first / auto, with human/automation mutual exclusion.
Components (reusable macros)
Named, versioned bundles of blocks that drop into any region and expand inline (Zapier Sub-Zap semantics). Editing a component creates a new component version; consuming strategies pin a version and upgrade explicitly — the same immutability discipline as strategies. Seed library:
- Standard Sweep Health Check — sweep(full) → verify via purchase-order-detail → proxy retry guard → NEP guard
- TT Wallet Link Ladder — TT extract → merge (parent-wins) → deliver; on NO_LINKS: wait → T−48 retry → SMP handoff
- Hard Transfer Fallback — capability check → GenericMobileTransfer (sale + inventory) → notify on stall
- Cancel Watch — purchase-canceled trigger → mark terminal Canceled → notify
3 · Versioning & Assignment
- Immutable versions. Published versions never change. Editing creates a draft; the canvas shows a block-level diff (ADDED / MODIFIED badges) against the published version. Publishing creates
vN+1. - Running journeys finish on their pinned version unless explicitly migrated. Publishing never yanks the rug out from in-flight instances.
- Event-level default. Each event gets one default strategy; new POs entering that event enroll in it. This is what the strategy chip on each event band in Fulfillment shows.
- Property-based overrides. Ordered rules keyed on the four property domains, most-specific wins — e.g.
Purchase.site=FIFA → FIFA Aggressive,Purchase.tag=nofulfill → Manual/None. Deterministic and previewable ("would affect N sales"). - Manual pin. A human can pin a lot to a strategy (or to Manual). Pins outrank all rules. Pin ≠ lock — a lock pauses automation entirely.
- Re-entry. Once terminal, an instance never re-enters. Cancel-then-uncancel and postponement edge cases create a new journey instance linked to the old one.
- Inherited Default is locked. The system fallback strategy is immutable in place — duplicate it into a new strategy to make changes.
4 · Phase 2 — Buy-Side Detection
The journey visibly starts before the entry anchor, with three signal sources — all variations on detecting a purchase and ensuring it gets PO'd properly:
- Cart / interaction signals — BigQuery interactions table (cart monitoring). Earliest signal, noisiest.
- Purchase confirmation emails — TexMail realtime new-mail fanout (sub-second) matching order-confirmation patterns.
- PO created in Reach — the reconciliation target. If signals 1/2 fire but no PO appears within a grace window → escalate an "un-PO'd purchase."
The contract with Phase 1: Phase 2 terminates by producing or confirming the Reach PO — its terminal state is Phase 1's entry anchor. Nothing in the Phase 1 grammar changes when Phase 2 lands; the DETECT blocks simply become editable with the same trigger/condition/action grammar and new signal sources.
5 · The Fulfillment View
Fulfillment is the operational read-out of every running journey, grouped by event:
- Strategy chips on each event band show the event-level default strategy governing that event's sales — the same identities (Standard Lifecycle, FIFA Aggressive, MLB Safe Mode, Inherited Default) you edit in the Strategies view.
- Progress steppers (Swept → Links → Delivered) show where each sale sits on its journey; badges surface exceptional states (NEP, escalations, buyer-not-accepted).
- The waterfall button on an event band opens Assign Strategy — change the event-level default with a preview of how many sales would be affected before applying.
- Deadline column — the T− countdown against the event anchor; the nearest deadline across all events shows in the toolbar.
- Human locks — a named lock on a sale means automation is excluded until released.
- DRY-RUN / LIVE — the same global mode switch as everywhere else; in DRY-RUN, all bulk and per-event actions simulate and log instead of executing against Reach / Automatiq / TT.
6 · Walkthrough
Reading the timeline
- Top to bottom = purchase to event. The two dark anchor pills (PO created / Event date) are fixed; everything else hangs between or off them.
- The greyed striped region at the very top is Phase 2 detection — visible, not yet active.
- Each colored region holds blocks with an offset chip (
T+2d,every 24h,T−72h) showing when it fires relative to its anchor. - The dashed red rail below the event anchor lists event-triggered branches — they can fire at any point, not just at the bottom.
- The four cards at the bottom are the terminal states. Every path through the strategy must be able to reach one.
Editing a strategy
- Pick a strategy in the left sidebar. Its published version and assignment footprint show in the strip above the canvas.
- Click a region header to target it ("✚ ADDING HERE"), then add blocks or components from the palette — they land with the region's default offset.
- Click any block to open it in the Inspector (right panel) — edit its offset and knobs. Component members expand inline; click a member to edit just that placement.
- Your first edit creates a draft — the DRAFT chip appears with a change count, and edited blocks get ADDED/MODIFIED badges.
- Use SIMULATE 7D to replay the last 7 days against the draft before committing.
Publishing
- PUBLISH freezes the draft as immutable
vN+1. Events using this strategy pick it up for new journeys; running journeys finish on the version they started with. - DISCARD DRAFT throws the edits away and returns to the published version.
- APPLY STRATEGY TO EVENTS… sets this strategy as the event-level default on selected events, with a preview of affected sales. In DRY-RUN, assignment is simulated.