ADR-0076: Queue Phase 1 + Billing v1 — Aggressive 12-Day Plan (Python)
Status: Superseded by 0076-queue-phase1-cpp-billing-v1.md (2026-05-11 UTC — operator elected C++ for Queue; timeline framing overridden by explicit operator statement "we don't need to manage the time like you are trying to do"; see 0076-queue-phase1-cpp-billing-v1.md for the current decision)
Original Date: 2026-05-11 UTC
Supersedes: ADR-0075 (framing that "v1 launches without billing")
Refs:
- ADR-0071 (Queue-as-authority — confirmed)
- ADR-0073 (Raptor stopgap — rejected)
- ADR-0075 (billing stays in Queue — confirmed; v1-without-billing framing superseded)
- docs/architecture/queue/queue-phase1-design.md (the execution design this ADR governs)
- docs/architecture/stripe-customer-billing.md (v3 schema — unchanged)
- Cards: #406, #407, #408, #409, #1630, #1631, #1632, #1633, #1635
Historical record only. This ADR documented the Python Flask + aggressive 12-day plan. It was superseded on 2026-05-11 UTC when the operator selected C++ for Queue. The core decisions it established — billing ships in Queue for v1, no Raptor stopgap, billing is not deferred — are all confirmed and carried forward in
0076-queue-phase1-cpp-billing-v1.md. What changed: the implementation language (Python → C++) and the timeline framing (12-day hard deadline → quality-first with accepted slip).
Context
Operator decisions (2026-05-11 UTC)
Three decisions made in quick succession during the evening:
-
21:08 UTC — "Billing is going to Queue, if it means slippage, so be it. Do not put billing in stopgap mode." (ADR-0075)
-
21:18 UTC — "No, v1 comes with billing..." (clarifying #1: billing is not deferred; it ships in v1)
-
21:20 UTC — "Hold 2026-05-23 launch — compress Queue + billing into 12 days (Aggressive)" + "Dispatch Queue Phase 1 architect immediately"
These three statements together mean: v1 ships on 2026-05-23 UTC WITH billing-in-Queue. Neither the launch date nor the architectural placement is negotiable. This is an engineering-sprint posture.
What ADR-0075 got wrong
ADR-0075 correctly established that billing stays in Queue (rejecting the Raptor stopgap). However, it interpreted the operator's "if it means slippage, so be it" as accepting a v1 launch WITHOUT billing. The clarifying statements at 21:18–21:20 UTC make clear that slippage refers to internal milestones and engineering comfort, not to deferring billing past v1. The launch date and billing are both fixed.
This ADR supersedes ADR-0075's "v1 proceeds without billing" framing.
Decision
v1 ships on 2026-05-23 UTC with billing-in-Queue. Queue Phase 1 (the minimum foundation to host billing safely) and the billing chain are built in parallel across a 12-day aggressive sprint ending 2026-05-23 UTC.
The design doc at docs/architecture/queue/queue-phase1-design.md governs the scope, sequencing, and cut-lines for this sprint.
Scope Boundaries
What ships in v1 (hard floor)
These are the minimum deliverables for "v1 launched with billing" to be true:
| Deliverable | Card | Why it's hard floor |
|---|---|---|
Queue queue/ scaffold: Flask factory, blueprints, service-auth, Alembic chain |
QP-1 | Everything else is blocked on this |
Billing schema migration in Queue (billing_customer, billing_subscription, billing_invoice, processed_stripe_events, billing_action_log, billing_subscription_mirror) |
QP-2 | Paywall requires schema; no schema = no billing |
| Stripe service layer (Queue) | #406 | Required for subscription CRUD and webhook processing |
| Stripe webhook handler (Queue) | #407 | Required for Stripe-driven subscription state |
JIT paywall check in Raptor (reads billing_subscription_mirror) |
QP-4 | Live trading must gate on subscription status |
POST /api/internal/billing/subscribe — single-tier subscription endpoint |
#406 subset | Customers must be able to subscribe at launch |
| Deploy pipeline for Queue (GH Actions workflow) | QP-3 | Queue must be deployable |
| Queue healthcheck endpoint | QP-1 | Observability prerequisite |
Infisical secret paths provisioned: /Raxx/Queue/Billing/Stripe/ |
Operator | Blocks #406 |
| FLAG_QUEUE_BILLING flag wiring | QP-1 | Kill-switch for billing routes |
What ships if schedule holds (v1 target)
| Deliverable | Card | Notes |
|---|---|---|
| Console billing customer list | #408 | Console reads Queue API; depends on Queue API being stable |
| Console billing customer detail | #409 | Same dependency |
| Founders Price ID backfill script | #1632 | One-shot ops script; can ship dark and run post-launch |
Cut line 1 — first to go if Day 7 has slipped
| Deliverable | Card | Disposition if cut |
|---|---|---|
| Customer billing dashboard (Antlers) | #1633 | Post-launch; customers can contact support for billing state |
| Tier transition / downgrade flow | #1635 | Post-launch; all v1 tiers are one-way upgrades initially |
Cut line 2 — second to go
| Deliverable | Card | Disposition if cut |
|---|---|---|
| DSR billing erasure flow | #1630 | Post-launch if and only if privacy policy explicitly states "billing DSR in development, submit via support@raxx.app"; GDPR clock starts at launch |
| PII retention automation | #1631 | Post-launch; 7-year retention window means no immediate risk — manual operator process documented in runbook |
Important: DSR and retention CAN be cut from v1 implementation only with the privacy-policy carve-out. If the privacy policy does not include the carve-out, they are v1-launch-blockers. PM and BLR must confirm before Day 8.
Hard floor restatement
v1 can launch on 2026-05-23 UTC as "launched with billing" if and only if these five conditions hold:
- A customer can subscribe to a paid plan via the in-product flow (Queue webhook handler + subscription endpoint).
- The paywall correctly blocks un-subscribed customers from gated features (JIT mirror check in Raptor).
- Stripe webhooks are processed durably (idempotent upsert + dedup table).
- The operator can view billing state (Console reads Queue billing API).
- The kill-switch works:
FLAG_QUEUE_BILLING=falsedisables all billing routes without a deploy.
Everything else is post-launch scope.
Consequences
Positive: - v1 ships with a real subscription flow, not manual Stripe ops. - Architectural integrity maintained: billing PII lives in Queue-DB only. - No post-launch migration required (billing was never in Raptor). - Aggressive schedule forces ruthless scope discipline — which is healthy for an early product.
Negative: - 12-day window is tight. Zero-slip budget on Queue scaffold (QP-1) and billing schema (QP-2) — these are the critical path. - Queue is being built partly under launch pressure. The risk is that auth/session/RBAC features in Queue are rushed alongside billing. Mitigation: Queue Phase 1 scope is deliberately minimal — only what billing needs. Full identity service (passkeys, session management, RBAC) is Phase 2 post-launch. - If the schedule slips on the hard floor items, the operator must choose between: (a) launching without billing (reverts to ADR-0075's original "without billing" posture), (b) slipping the launch date past 2026-05-23. This is a real decision point that must be visible by Day 8 (2026-05-19 UTC) at the latest.
The slip detection gate (Day 8 check): If by end of Day 8 (2026-05-19 UTC) the Queue scaffold and billing schema are not deployed to staging and the webhook handler is not passing tests, the operator should be paged. The slip is real and the choices narrow. Delay the page and the choices disappear.
Alternatives Considered
Accept ADR-0075's "v1 without billing" framing
Rejected — operator explicitly reversed this at 21:18 UTC. "No, v1 comes with billing" is unambiguous.
Slip the launch date to allow more Queue build time
Not this ADR's decision to make. Operator explicitly said "Hold 2026-05-23 launch." The 12-day sprint is the answer to "how do we keep the date AND ship billing in Queue."
Minimal Queue with only billing (no identity features)
This is exactly what Queue Phase 1 is — see queue-phase1-design.md. The minimal viable Queue to host billing safely, without the full identity service.
Related Decisions
- ADR-0065: Queue strangler-fig — Phase 1 co-locates Queue with Raptor (same Postgres, same dyno in v1).
- ADR-0066: Queue blueprint mount — Queue is a Flask blueprint mounted inside Raptor's app factory in Phase 1.
- ADR-0071: Queue-as-authority — billing PII in Queue-DB only. Confirmed.
- ADR-0073: Raptor stopgap — rejected.
- ADR-0075: Billing stays in Queue — confirmed; "v1 without billing" framing superseded by this ADR.