Raxx v1 — Plan to Production
Filed: 2026-07-11 UTC
Adjudicator / PM: raxx-pm-bot
Parent epics: #94 (Production Release v1.0), #146 (raxx-console), #3483 (Paper Trading v1), #3126 (Pre-launch readiness)
Branch: feature/beta-walkthrough-activation-scaffold (commit to develop after operator review)
Companion docs (in progress):
- docs/architecture/defense-in-depth-to-production.md — architect defense-in-depth design (being drafted in parallel; referenced as security gate in Waves 2 and 9)
- docs/marketing/production-launch-portfolio.md — marketing outcome portfolio (being drafted in parallel; referenced as go/no-go input in Wave 9)
1. Definition of "Finished Product" — v1 Launch Bar
Raxx v1 is a trust milestone, not a feature-completeness milestone. Three gates must be true simultaneously on the day public traffic is admitted.
Gate 1 — Self-onboarding works end-to-end. A net-new user visits raxx.app, registers a passkey, connects a paper-trading broker account, lands on a working Dashboard, and can submit a paper order through the Simulate surface. No operator shortcuts, no console hand-holding, no SQL. Kristerpher walks this exact path on staging and signs off before prod traffic opens.
Gate 2 — Paper trading is stable and the core product is shippable.
FLAG_PAPER_TRADING_V1 is flipped on staging, soaked for 7 calendar days with drift < 2%, then promoted to prod. The Simulate surface (unified forward/backward toggle) renders without errors. MBT securities-only backtest remains the existing quality bar. Options backtesting stays behind ENABLE_OPTIONS_BACKTEST=false. The LCC engineering sprint has NOT shipped; it starts after paper trading soak completes.
Gate 3 — The operator can run the platform safely without manual CLI operations.
Velvet token rotation works end-to-end via HTTP API (no shell-out to gh/heroku CLIs in the dyno). Console shows real deploy status. Every secret is rotatable from the console. WAF Phase 1 rules are in Block mode on all surfaces. BFM is re-enabled. The first customer email can land and be triaged in FreeScout. Nightly security scan produces output (scan-output absence is treated as HIGH).
What v1 explicitly is NOT (confirmed deferrals): - Live Stripe billing / billing console (#403 and all sub-cards) - iOS companion (#167 and all sub-cards) - Full BYOB broker aggregator (#495) - AI-Assisted Trading (#80) - Options backtesting (#256 gated — Alpaca/ORATS licensing unresolved) - LCC engineering (#3313) — ships in post-v1 wave 0 once paper trading is soaked - Shape 2/3 real-time Rack sentiment (#1398) - Full RBAC/SAML/Workspace OIDC Phase 3+ (#972, #973) - Burr v2 multi-region HA (#1876–#1884) - demo.raxx.app (#482) - Heroku exit strategy (#2075) - Self-serve passkey account recovery (Card 2 of #3842 — full Stripe Identity flow) - Terraform PR automation (#1834 and sub-cards) - WAF Phase 3 CRS block mode (7 days post-launch, not a launch gate)
2. Card Inventory and Disposition
2a. Must-Ship-v1
Cards that gate one of the three v1 launch criteria. In wave order.
Wave 1 — CI Stability
| # | Title | Agent |
|---|---|---|
| #4139 | infra(ci): provision raxx-ci-config GitHub App for wp-config-svc | operator-action + sre-agent |
| #4141 | chore(ci): wp-config-svc shadow soak validation + forge connectivity healthcheck | sre-agent |
| #4142 | chore(ci): cut over wp-config-svc to active mode + retire weekly-restart workaround | sre-agent |
| #4106 | epic(ci): cut over 8 deliberate-GHA-hold workflows to Woodpecker | feature-developer |
| #4107 | WP agent: Docker socket mount + ECR vcpkg layer cache | feature-developer |
| #4108 | WP AWS auth: vault IAM users + S3 bucket + rotation runbook | sre-agent |
| #4109 | Formalize woodpecker-healthcheck.yml as permanent GHA-stay | feature-developer |
| #4110 | Port deploy-failure-streak-alert.yml to WP | feature-developer |
| #4111 | Port security-zap.yml to WP | feature-developer |
| #4112 | Port queue-docker-smoke.yml to WP | feature-developer |
| #4113 | Port deploy-antlers-cutover.yml to WP (or retire if cutover ran) | feature-developer |
| #4114 | Port freescout-apply.yml to WP | sre-agent |
| #4115 | Port terraform-email-delivery-stack.yml to WP | sre-agent |
| #4116 | Port deploy-queue.yml to WP | feature-developer |
| #4067 | Port audit-integrity cron group (4 workflows) | feature-developer |
| #4068 | Port billing cron group (3 workflows) | feature-developer |
| #4069 | Port MBT + market-data cron group (7 workflows) | feature-developer |
| #4070 | Port smoke / backup / security cron group (6 workflows) | feature-developer |
| #4071 | Port Antlers CF Pages deploy pipelines | feature-developer |
| #4072 | Port Queue + Velvet Heroku deploy pipelines | feature-developer |
| #4073 | Port static-site CF Pages deploy pipelines | feature-developer |
| #4074 | Port infra / synthetic / release-candidate pipelines | feature-developer |
| #4075 | Fix daily-bot-token-smoke vault key mismatch | feature-developer |
| #4038 | ci(woodpecker): Console Ops Dispatch cutover to Woodpecker API | feature-developer |
| #4020 | ci: disable ios-ci.yml now | feature-developer |
| #4017 | ci(woodpecker): Phase 3b — migrate heavy CI | feature-developer |
| #4018 | ci(woodpecker): Phase 4 — migrate deploy/release pipeline | sre-agent |
| #4039 | ci(woodpecker): Wave B infra — scale arbiter Lambda | sre-agent |
| #4012 | infra(ci): Terraform baseline — VPC, ALB, WAF, IAM, SSM, runner fleet | sre-agent |
| #4148 | SC-IK-4: Wire idempotency to paper reset + order replace (Wave 2) | feature-developer |
| #4149 | SC-IK-5: Wire idempotency to billing mutation endpoints (Wave 3) | feature-developer |
Wave 2 — Security Hardening
| # | Title | Agent |
|---|---|---|
| #1735 | HIGH: No CF WAF rules configured — pre-launch blocker | sre-agent |
| #1736 | SC-WAF-00: Phase 0 CF account WAF settings + Logpush destination | operator-action + sre-agent |
| #2282 | SC-WAF-04: WAF cutover staging — challenge mode Phase 2 | sre-agent |
| #2283 | SC-WAF-05: WAF cutover staging — block mode soak 48h Phase 3 | sre-agent |
| #2285 | SC-WAF-05b: WAF prod rollout — log to challenge to block Phase 4 | sre-agent |
| #3634 | ops: restore BFM on raxx.app once CF-Access WAF skip rules are live | operator-action + sre-agent |
| #1025 | B5: Remove CF Access gating from raxx.app + api.raxx.app | sre-agent (post-WAF) |
| #3209 | operator-action: execute CF Access removal from raxx.app + api.raxx.app | operator-action |
| #3738 | feat(vault): provision per-agent scoped Infisical machine identities | sre-agent |
| #1903 | reliability: audit workflows using static CF repo secrets — migrate to vault-sourced | feature-developer |
| #3286 | SC-A4 audit webhook not provisioned in FreeScout | sre-agent |
| #3285 | FreeScout admin TOTP enrollment unknown | operator-action |
| #3284 | privacy@raxx.app mailbox missing in FreeScout | operator-action + sre-agent |
| #1987 | ops(ci): add actionlint to ci-pr.yml | feature-developer |
| #1985 | perf(ci): nightly-security-scan.yml cache trivy + gitleaks | feature-developer |
| #1984 | perf(ci): ci-pr.yml cache commitlint + reduce migration-gate fetch depth | feature-developer |
| #1982 | perf(ci): deploy-heroku.yml cache heroku CLI | feature-developer |
| #1981 | perf(ci): ci.yml add pip cache + parallelize | feature-developer |
| #2148 | reliability: lint gate reject DO $$ migrations without POSTGRES-ONLY | feature-developer |
Wave 3 — Queue Cutover
| # | Title | Agent |
|---|---|---|
| #1517 | feat(queue): Phase 2 cutover — dual-mode middleware + flag flip (QC-2) | feature-developer |
| #2445 | feat(console): cut over Console customer-data reads to Queue REST (QC-1) | feature-developer |
| #2447 | feat(antlers): cut over session-context reads from Raptor to Queue (QC-4) | feature-developer |
| #2449 | refactor(velvet): re-target customer-active validation call to Queue (QC-6) | feature-developer |
| #2450 | chore(reasonator): audit + re-target customer-context reads to Queue (QC-7) | feature-developer |
| #2446 | feat(queue): Stripe webhook receiver — move from Raptor to Queue (QC-3) | feature-developer |
| #2451 | feat(queue): audit ledger unification — flip to Queue-only after dual-write soak (QC-8) | feature-developer |
| #1473 | refactor(console): cut over all 17 console blueprints to require_rbac_role | feature-developer |
Wave 4 — Paper Trading v1
Sub-cards for #3483 are referenced by label in the epic body. card-groomer files them as discrete sub-issues at Wave 4 kickoff. Dependency chain from epic:
SC-15 (flag + B1 migration) — first
SC-1, SC-2, SC-3 (schema migrations) — parallel
SC-4 (Alpaca Data API client) — after schema
GAP-1 (1-min bar provider)
GAP-2 (bid/ask fill model)
SC-5 (market order endpoint)
SC-6 (limit orders)
SC-7 (IC builder wiring)
SC-8 (LCC roll wiring)
GAP-3 / SC-9 (expiry sweep)
SC-10 (dividend / split batches)
GAP-5 (equity MTM)
GAP-4 (tax wire-up, Founders-gated) — parallel with order chain
SC-12 (trade history + tax section)
SC-11 (Simulate UI forward mode)
SC-12 (history tab inside Simulate)
SC-13 (reset endpoint + UI)
SC-14 (live-broker CTA placeholder)
Additional paper trading-adjacent card: | #3292 | feat(tax): gain/loss estimator — after-tax P&L for realized trades (Founders-gated) | feature-developer |
Wave 5 — Antlers / Onboarding / Shape 1
| # | Title | Agent |
|---|---|---|
| #3513 | feat(beta): walkthrough activation scaffold — merge to develop FIRST | feature-developer |
| #469 (sub-cards) | Onboarding Wizard sub-cards (passkey bind, email verify, profile, wizard flow, first-run dash) | feature-developer |
| #3403 (sub-cards) | Beta tester program (intake form, walkthrough links, rubric, scoring pipeline, operator digest) | feature-developer |
| #3833 (SHAPE1-1 through SHAPE1-5) | Shape 1 personal trade-context journal engineering (flag OFF at launch) | feature-developer |
| #3842 Card 1 | Console ghost-reset tool for stuck/ghost-enrolled users | feature-developer |
| #3147 | polish(antlers): Order Ticket V2 help-mode copy review | ux-polisher |
| #1110 | design(antlers): Jupiter/Bandz scenario illustrations to error + empty states | ux-polisher |
| #2281 | arch(antlers): DemoContext pre-mount flag access design decision | software-architect |
| #2280 | chore(antlers): migrate App.js routing isEnabled() to useFlag() | feature-developer |
| #2356 | Privacy policy v1: add Microsoft Clarity + session replay vendor disclosure | feature-developer |
| #511 | feat(trace): SC-13 live-paper trading mode transitions as named sys_* events | feature-developer |
| #3928 | reliability: pytest-cov hangs in Backend tests job | feature-developer |
Wave 6 — FreeScout + Support
| # | Title | Agent |
|---|---|---|
| #707 (sub-cards) | epic(support): FreeScout productionization | sre-agent |
| #710 | ops(support): create support@raxx.app mailbox in FreeScout admin | sre-agent |
| #713 | feat(support): auto-reply on new ticket | sre-agent |
| #721 | feat(support): Slack DM webhook on new FreeScout ticket | sre-agent |
| #722 | ops(support): pre-write canned responses + basic knowledge base | sre-agent |
| #725 | ops(support): define FreeScout activity log retention policy | sre-agent |
| #656 | support.raxx.app sub-5: FreeScout customer mailbox + customer_raxx_id field | sre-agent |
| #1211 | ops(email): confirm support@raxx.app is not claimed by Google Workspace | operator-action |
| #1213 | ops(email): publish DMARC p=none monitoring record for raxx.app | sre-agent |
| #1215 | bug(email): diagnose and fix Google Groups non-delivery on moosequest.net | sre-agent |
Wave 7 — Velvet + Operator Tooling
| # | Title | Agent |
|---|---|---|
| #949 | feat(velvet/flows): three-stage operational flow state machine | feature-developer |
| #952 | feat(velvet/ui): three-stage rotation modal — verify, distribute, validate+revoke | feature-developer |
| #953 | feat(velvet/ui): per-subscriber distribute-status table inside rotation modal | feature-developer |
| #954 | feat(velvet/ui): yaml-driven revocation auth gate | feature-developer |
| #955 | docs(velvet): operator runbook v2 + bus-adapter-author guide | feature-developer |
| #251 | Security H3 — rotate HEROKU_API_KEY + set rotation schedule | operator-action + sre-agent |
| #1334 | feat(billing): UNIQUE constraint on (vendor, period_start) in vendor_billing_snapshots | feature-developer |
| #2595 | ops(billing): set BILLING_DB_PATH after #2159 ships | sre-agent |
| #2655 | BCP Win 4: Verified restore drill — Heroku Postgres + FreeScout | sre-agent |
| #1898 | ops(devops): set TF_ROLE_ARN_EMAIL_DELIVERY_STACK repo secrets | sre-agent |
| #596 | ops(vault): Phase 1 — audit per-secret env coverage (prod/staging/dev) | sre-agent |
| #1372 | ops(reliability): CD freshness monitor — alert when prod lags main >24h | sre-agent |
| #2016 | feat(console): POST /flags/ |
feature-developer |
| #798 (sub-cards) | epic(console): staging to prod flag promotion flow | feature-developer |
| #1587 | Add toggle category tagging to feature_flags.yaml | feature-developer |
| #1588 | Add decommission-after field to feature_flags.yaml + B1 CI check | feature-developer |
| #2151 | reliability: add Slack alert on release.yml failure | feature-developer |
| #2150 | reliability: require spec update in PR template for backend_v2/api/routes/ changes | feature-developer |
| #1749 | chore: rotate raxx-lambda-freescout-bridge CF Access service token (due 2027-03) | sre-agent |
Wave 8 — Marketing Site + Docs
| # | Title | Agent |
|---|---|---|
| #582 (non-legal sub-cards) | Epic: getraxx.com launch readiness — engineering + infra items only | feature-developer |
| #586 | Add Privacy Policy and ToS placeholder pages to marketing site | feature-developer |
| #581 (sub-cards) | Epic: status.raxx.app — surface registry wired, 3P upstream polling | feature-developer |
| #608 | status.raxx.app sub-6: evaluate + implement upstream 3P partner status API polling | feature-developer |
| #2678 (non-blocked sub-cards) | Epic: docs.raxx.app go-live for customers | sre-agent |
| #575 | feat(api): generate OpenAPI 3.1 spec from backend_v2 routes | feature-developer |
| #1012 | feat(support/ops): S9 CF Pages provisioning + DNS + surface registry entry | sre-agent |
| #3439 | Status dashboard — green hero state when all services are operational | ux-polisher |
| #3440 | Status dashboard — stronger visual weight for degraded and down tiles | ux-polisher |
| #3441 | Status dashboard — wire 48h availability sparkline into V2 side panel | feature-developer |
| #3442 | Status dashboard — overlay deploy markers on 48h sparkline | feature-developer |
| #3443 | Status dashboard — mobile-responsive single-column tile layout | ux-polisher |
| #3444 | Status dashboard — keyboard navigation J/K between tiles | feature-developer |
| #3447 | Status dashboard — per-service dependency-config schema | feature-developer |
| #214 | Instrument Antlers + Raptor with PostHog | feature-developer |
| #659 | support.raxx.app sub-8: launch checklist (meta tags, brand lint, sitemap, robots) | feature-developer |
Wave 9 — Go/No-Go + Launch
| # | Title | Agent |
|---|---|---|
| #4166 | v1 launch go/no-go gate — staging walkthrough + checklist (see Appendix A) | operator-action |
| #4167 | Flip FLAG_PAPER_TRADING_V1 to prod — post-7-day-soak activation step (see Appendix A) | sre-agent |
| #2819 (remaining) | Launch-day: console + status + adjacent services — complete sweep | sre-agent |
| #402 | review: secrets-store organization audit pass | sre-agent |
2b. Defer — Post-v1
These cards will not block launch. Confirmed deferred.
iOS: #167, #175, #176, #177, #178, #179, #180, #181, #182, #2448
Billing console: #403, #408, #409, #410, #411, #1633, #1635
BYOB/Hybrid broker: #495
AI-Assisted Trading: #80, #245
LCC engineering: #3313
Shape 2/3: #1385, #1390, #1398, #1401, #1402, #1403, #1404, #1405, #1406
Obfuscate mode + Founders promo mechanics: #204 sub-cards #207–#240
Heroku exit strategy: #2075
demo.raxx.app: #482, #493
i18n: #1463
Full RBAC Phase 3+4: #972, #973, #1474, #1475, #1476, #1479, #1725
RBAC compliance role: #1479
Console break-glass full suite: #1692, #1693, #1694, #1695, #1696
Burr v2 multi-region HA: #1876, #1877, #1878, #1880, #1881, #1882, #1883, #1884, #1888, #1889
Terraform PR automation: #1834, #1836, #1837, #1838, #1839, #1840, #1841, #1842, #1843, #1844, #1845, #1846, #1847, #1848, #1849
Ubicloud runners: #728
CI billing posture: #726
Self-serve passkey recovery (Card 2): #3844
Percentage-rollout for flags: #1590
WCB sparkline + account merge v2: #1660, #1661, #1662, #3301, #3302
Workflow UUID tracing replay UI: #500, #513
Passkey E2E encryption: #250, #272
Support portal public SPA: #652, #655, #657, #658, #663, #664, #665
Docs BLR full audit: #2681
Polygon contract: #3504
Amazon Associates signup: #2769
Console flag decommission sunset notification: #1589
pg_audit extension + audit archiver: #1493, #1494
RBAC drift detection service: #1967
Console Recents autocollapse flag fix: #2210
WAF Phase 3 CRS block mode: (7 days post-launch)
CF Pages logs to S3 Logpush: #3458
Status dashboard Variant B service map: #3448
Status dashboard alerts/paging vendor: #3449
Flag operator UX hardening + Pony docs: #2299
Demo session continuation: #493
SC-12 replay UI in console: #513
Console flag operator UX hardening: #2299
FreeScout productionize Phase 2 (email notifications sub-6, SPA sub-4): deferred to post-v1 launch window
Reasonator Pro tier badge: #1405
Reasonator review queue: #1691, #1693, #1695, #1696
OpenAPI spec Phase 2 (full docs site publish): beyond #575
Heroku exit strategy trigger conditions: #2075
Local dev environment design: #2054
Burr v1 audit + pentest: #1869 (post-v1; Burr v1 stays in place at launch)
HEROKU_API_KEY rotation cadence (calendar event): post-Wave 7 operator action
Legal/compliance items (out of scope per operator directive):
3858, #3840, #3149, #3141, #3142, #3143, #3144, #3145, #3146, #3148, #2847, #2850, #2856, #2859, #2862, #2863, #2864, #2865, #2855, #1642, #197 (gates flag flip but is not an engineering card), #185, #152, #300
2c. Closed as Obsolete or Superseded
| # | Title | Reason | Status |
|---|---|---|---|
| #1556 | epic(raptor): migrate Raptor from SQLite to Postgres | Complete per 2026-07-03 comment; all sub-cards closed | CLOSED 2026-07-11 |
| #350 | infra: console PR previews via Heroku review apps | Duplicate of #1890 | CLOSED 2026-07-11 |
| #417 | epic(rotation): target-adapter framework | Superseded by Velvet (#907); close after #907 ships | Close at Wave 7 completion |
| #253 | Epic: Automated credential rotation pipelines | Superseded by Velvet (#907); close after #907 ships | Close at Wave 7 completion |
| #2245 | chore: daily card-groomer pass log | Operational log; no acceptance criteria possible | Close as process artifact — card-groomer to confirm |
3. Release Waves — Sequenced Plan
Pre-Wave: Immediate Operator Actions (do now, unblocks everything)
- Provision
raxx-ci-configGitHub App (#4139) — 10-step browser procedure in the card; store App ID, private key, and installation ID in SSM. Unblocks Wave 1 wp-config-svc cutover. - Authorize CF WAF skip rules + BFM re-enable sequence (#3634 Action A) — confirm
sre-agenthasZone:Bot Management:Editscope, or provisionCLOUDFLARE_RAXX_AUTOMATION_API_TOKENfor the BFM toggle. Unblocks Wave 2. - Confirm Alpaca data redistribution posture —
FLAG_PAPER_TRADING_V1stays OFF until the operator either receives written confirmation from Alpaca sales or makes an explicit documented decision to proceed under the existing terms. File the decision as a comment on #3483. Unblocks Wave 4 flag flip only (engineering proceeds regardless).
Wave 1 — CI Stability
Entry: Pre-wave operator actions done (specifically #4139 GitHub App provisioned).
Exit criteria:
- gh workflow list --all returns exactly woodpecker-healthcheck.yml and ios-ci.yml (disabled)
- wp-config-svc in active mode; CloudWatch shows zero forge fallbacks for 48h
- #4148 and #4149 merged; FLAG_IDEMPOTENCY_MIDDLEWARE soaking on staging
- All WP cron and deploy pipelines show a 24h green run
Dependencies: #4141 shadow soak must complete before #4142 dispatches. #4107 and #4108 are shared-infra prerequisites for the deliberate-holds batch (#4106).
Agent responsibilities: sre-agent owns wp-config-svc cutover (#4141, #4142) and Terraform/runner infra (#4012, #4039). feature-developer owns all WP pipeline port cards in parallel batches.
Risk and mitigation: If the forge connectivity probe added by #4141 fails during cutover, roll back by setting SHADOW_MODE=true and re-enabling the forge path. Do not proceed to Wave 2 with CI unstable.
Wave 2 — Security Hardening
Entry: Wave 1 CI stable.
Exit criteria:
- CF Managed Ruleset in Block mode on all 9 surfaces
- Auth endpoint rate limits live and tested against synthetic traffic
- BFM re-enabled on raxx.app zone (skip rules verified live)
- CF Access removed from raxx.app + api.raxx.app (#1025, #3209)
- Per-agent scoped Infisical identities provisioned (#3738)
- Nightly security scan producing output for 3 consecutive nights
- WAF Phase 2 (OWASP CRS in Log mode on api.raxx.app) active
- Architect defense-in-depth doc (docs/architecture/defense-in-depth-to-production.md) signed off
Dependencies: WAF skip rules must precede BFM re-enable. CF Access removal must follow WAF Phase 1 block mode. Never remove CF Access while WAF is not blocking.
Agent responsibilities: sre-agent owns all WAF Terraform, BFM, and CF Access removal. software-architect reviews WAF rule set against defense-in-depth doc.
Risk and mitigation: WAF false-positive on WebAuthn CBOR payloads (large bodies). Mitigation: deploy WAF in Challenge mode on api.raxx.app for 48h before Block mode; add a size-exception whitelist rule on /api/auth/register. CRS stays in Log mode at launch.
Wave 3 — Queue Cutover
Entry: Wave 2 security stable; prod Queue dyno confirmed live (not zero-dyno state).
Exit criteria:
- FLAG_QUEUE_V1 ON in prod
- All consumer services (Console, Antlers, Velvet, Reasonator) read from Queue API, not direct-DB
- Raptor customers and sessions tables read-only (no new writes outside Queue)
- 7-day dual-write audit soak complete with < 0.1% row discrepancy
- QC-8 audit unification flag flipped and stable for 24h
Dependencies: #1517 (session-mint cutover) must soak before #2445, #2447, #2449, #2450 dispatch. #1473 (console blueprint cutover) must land before #2445. QC-5 (iOS) deferred.
Agent responsibilities: feature-developer owns all QC-* cards in strict dependency order.
Risk and mitigation: Stripe webhook receiver (QC-3, #2446) touches the billing path. At v1 there are no live Stripe keys on prod (billing deferred per ADJ-7), so this is a safe schema/routing change. Proceed.
Wave 4 — Paper Trading v1
Entry: Wave 3 Queue stable; Alpaca redistribution posture confirmed (operator comment on #3483).
Exit criteria:
- All SC- and GAP- cards under #3483 merged and CI green
- FLAG_PAPER_TRADING_V1 ON on staging; 7-day soak with drift < 2%
- market_data_access_log populated with every Alpaca fetch (redistribution audit trail)
- Simulate UI forward mode renders paper portfolio tile and trade history
- Backtest tab functions without regression
- Paper reset cooldown enforced server-side; cooldown_expires_at returned in API when blocked
- Tax section in SC-12 is Founders-gated and confirmed hidden (not grayed) for Free/Pro
- Securities attorney sign-off on MBT profile narrative (#197) confirmed before flag flip to prod
Dependency chain: SC-15 first, then SC-1/2/3 in parallel, then SC-4, then GAP-1, GAP-2, then the order endpoint chain. See epic #3483 for the full tree.
card-groomer should break SC-1 through SC-15 and GAP-1 through GAP-5 into discrete sub-issues under #3483 at Wave 4 kickoff. Each becomes a standalone PR.
Agent responsibilities: feature-developer owns all paper trading cards. data-scientist reviews fill model against reference implementation (PR #3481).
Risk and mitigation: Alpaca redistribution clause is the top risk. If operator has not confirmed posture by the time SC-4 is ready to merge, SC-4 must not merge. Escalate to operator immediately rather than proceeding.
Wave 5 — Antlers / Onboarding / Shape 1
Entry: Paper Trading scaffolding in place (SC-15 flag card merged); Wave 2 security stable.
Exit criteria:
- Beta walkthrough PR (#3513, current branch) merged to develop
- Beta tester program intake form, signed walkthrough links, and scoring pipeline operational
- Onboarding Wizard (#469) allows a net-new user: passkey register → email verify → broker connect (paper) → working Dashboard, zero operator assistance
- Shape 1 SHAPE1-1 through SHAPE1-5 merged; FLAG_SENTIMENT_JOURNAL stays OFF at launch
- Console ghost-reset tool (#3842 Card 1) tested against a ghost-enrolled staging account
- DemoContext pre-mount flag access design resolved (#2281) before routing refactor (#2280)
- pytest-cov hang (#3928) resolved so CI is not flaky during this wave
Note on Onboarding Wizard open questions (ADJ-11 closes these): Q1 = 14-day trial, no card required. Q2 = Free / Pro $39 / Pro+ $79 / Founders intro $29. Q3 = demo persistence is Phase 2 (deferred).
Agent responsibilities: feature-developer for all engineering. ux-polisher for copy review (#3147) and illustration passes (#1110). software-architect for DemoContext design (#2281).
Wave 6 — FreeScout + Support Readiness
Entry: Wave 4 product stable.
Exit criteria:
- support@raxx.app mailbox live in FreeScout and confirmed not claimed by Google Workspace
- DMARC monitoring record published
- Auto-reply on new ticket functioning
- Slack DM webhook fires on new ticket creation
- privacy@raxx.app routes DSR intake
- FreeScout admin TOTP enrolled; recovery codes in vault
- Audit webhook provisioned and #3286 resolved
- Canned responses and basic KB pre-loaded
Agent responsibilities: sre-agent owns all FreeScout infra. Operator performs TOTP enrollment manually (#3285).
Risk and mitigation: If Google Groups non-delivery bug (#1215) cannot be resolved quickly, route directly via Postmark into FreeScout, bypassing Google Groups entirely. Do not let email routing block support readiness.
Wave 7 — Velvet + Operator Tooling
Entry: Wave 6 support ready.
Exit criteria:
- Velvet three-stage rotation modal shipped; zero shell-out to gh/heroku CLIs in any dyno
- HEROKU_API_KEY rotated end-to-end through Velvet and confirmed clean (#251)
- CD freshness monitor (#1372) active; alert fires if prod lags main > 24h
- Flag promotion UI (#2016, #798 sub-cards) merged; FLAG_CONSOLE_FLAG_PROMOTIONS flipped ON after smoke test
- FLAG_IDEMPOTENCY_MIDDLEWARE soaked and flipped ON in prod
- Billing DB path (#2595) set correctly
- BCP restore drill (#2655) completed and documented
- #417 and #253 closed (Velvet is now the canonical rotation system)
Agent responsibilities: feature-developer for Velvet UI and flag system. sre-agent for secrets rotation, BCP drill, and monitoring.
Wave 8 — Marketing Site + Docs
Entry: Wave 5 onboarding stable; runs in parallel with Wave 7.
Exit criteria:
- getraxx.com engineering items live: Privacy/ToS placeholder pages (#586), pricing copy update, pillar refresh
- status.raxx.app surface taxonomy wired; 3P upstream polling live; tile polish complete (#3439–#3444, #3447)
- docs.raxx.app public (noindex removed from docs subdomain; all links valid)
- OpenAPI 3.1 spec generated from backend_v2 routes (#575) and linked from docs index
- PostHog instrumentation live on Antlers + Raptor (#214)
Note: Marketing copy items gated on attorney review (dual-audience messaging #2856–#2865, investment-adviser disclaimers #2859) are legal-blocked. Only engineering-unblocked items ship in this wave. Blocked copy cards defer until attorney signs off.
Wave 9 — Go/No-Go + Launch
Entry: ALL waves 1–8 complete or explicitly confirmed deferred.
Entry gate checklist (every item must be TRUE before prod traffic):
Infrastructure: - [ ] Woodpecker CI stable; zero GHA workflows active except healthcheck and ios-ci (disabled) - [ ] wp-config-svc active mode; forge fallbacks zero for 48h - [ ] WAF Phase 1 Block mode live on all 9 surfaces - [ ] BFM re-enabled on raxx.app zone - [ ] CF Access removed from raxx.app + api.raxx.app - [ ] Per-agent scoped Infisical identities active (#3738)
Product: - [ ] FLAG_PAPER_TRADING_V1 on staging; 7-day soak green; drift < 2% - [ ] Alpaca redistribution posture documented (operator comment on #3483) - [ ] FLAG_IDEMPOTENCY_MIDDLEWARE on prod; Waves 2 and 3 soaked - [ ] FLAG_QUEUE_V1 on prod; Queue cutover soaked 7 days - [ ] Onboarding Wizard E2E working on staging (zero operator shortcuts) - [ ] Kristerpher completes full self-onboarding on staging and files sign-off comment on #94
Security: - [ ] Architect defense-in-depth doc signed off - [ ] Securities attorney sign-off on MBT narrative (#197) OR explicit written operator waiver filed on #197 - [ ] HEROKU_API_KEY rotated through Velvet; rotation confirmed clean end-to-end - [ ] Nightly security scan: 7 consecutive nights with output (zero silent-dark events) - [ ] FreeScout TOTP enrolled; recovery codes in vault (#3285)
Support: - [ ] support@raxx.app live in FreeScout - [ ] Auto-reply functioning - [ ] privacy@raxx.app routes DSR intake
Marketing:
- [ ] getraxx.com engineering items live (pricing, Privacy/ToS placeholders, pillars)
- [ ] Marketing outcome portfolio (docs/marketing/production-launch-portfolio.md) complete
- [ ] noindex removal scheduled (remove on launch day, not before)
Exit (launch is live): - FLAG_PAPER_TRADING_V1 flipped ON in prod (#4167) - noindex headers removed from raxx.app and getraxx.com - First closed-beta tester cohort invite sent via signed walkthrough links - Operator files sign-off comment on #94 confirming Gate 1 (self-onboarding) passed on PROD
4. Adjudication Log
Every open decision found in the backlog. Ruling and rationale are final.
| ID | Decision | Ruling | Rationale |
|---|---|---|---|
| ADJ-1 | Idempotency: encrypt response_body JSONB at rest vs Postgres RBAC |
Postgres row-level security; no column encryption in v1 | Column encryption adds key management overhead and breaks JSONB operators. Heroku Postgres volume encryption handles at-rest. raptor_app role RLS policy prevents cross-tenant reads. response_body must never contain auth tokens (ADR-0138 invariant). Schedule field-level encryption review for v2 if a GDPR DPA requires it. |
| ADJ-2 | Idempotency: make Idempotency-Key REQUIRED on Tier-1 order endpoints at GA |
Required on Tier-1 (paper order submit, order replace); optional on all others | Deterministic-execution invariant makes silent double-fire uniquely dangerous on money/position paths. Client burden is low (UUID v4 per order form submit). Billing mutation endpoints stay fail-open; upstream Stripe dedup covers them. Add to API contract before Wave 4 ships. |
| ADJ-3 | wp-config-svc cutover timing | Wave 1 — before v1 launch | The forge connectivity scaling wall will cause CI instability during high-velocity Wave 4–5 merges. Fixing CI first is the correct dependency order. 48h shadow soak (#4141) is the safety gate. |
| ADJ-4 | LCC engineering (#3313) — v1 or post-v1? | Post-v1; starts after 30-day paper trading soak | LCC requires a stable fill engine and positions layer. Shipping both simultaneously creates entangled failure modes. Reference implementation is ready; the sprint can start immediately after paper trading completes its post-launch soak. Target: post-v1 Wave 0. |
| ADJ-5 | Shape 1 (trade-context journal) — v1 or post-v1? | Engineering in v1 (dark behind FLAG_SENTIMENT_JOURNAL); flag flip post-v1 | Shape 1 is designed as "launch-ready" per epic #3833. Engineering invariants are sound. The flag flip is gated on Privacy Policy update — that is a legal step, not an engineering step. Engineering delivers; legal unblocks the flip. |
| ADJ-6 | iOS companion (#167) — v1 or post-v1? | Confirmed post-v1 | Prior operator decision in #94 and ship plan. #4020 (disable ios-ci.yml) ships in Wave 1. |
| ADJ-7 | Billing scope for v1 | No Stripe integration, no billing console at v1.0 | No paying customers required for v1 (prior operator decision). Stripe webhook receiver moves to Queue (QC-3) as architectural correctness. Billing console (#403 + sub-cards) defers until first paying customer target is set. |
| ADJ-8 | WAF block mode timing | Phase 1 Block mode is a hard v1 gate; Phase 2 (CRS log) at launch; Phase 3 (CRS block) 7 days post-launch | Public traffic without WAF Block mode is unacceptable per #1735 severity:critical. Phase 3 deferral avoids false-positive risk on WebAuthn CBOR payloads at launch day. |
| ADJ-9 | CF Access removal timing | After WAF Phase 1 is in Block mode — not before | CF Access is the current perimeter guard. Removing it before WAF blocks creates an unguarded window. Two-step sequence is non-negotiable: WAF block then CF Access remove. |
| ADJ-10 | Queue cutover — which surfaces and sequencing? | QC-2 (session) first; then QC-1/4/6/7 parallel; QC-3 (Stripe webhook) concurrent; QC-8 (audit) after 7-day dual-write soak; QC-5 (iOS) deferred | Session cutover is the foundation for all consumer correctness. iOS deferred per ADJ-6. Stripe webhook safe at v1 (no live billing). |
| ADJ-11 | Onboarding Wizard open questions (Q1, Q2, Q3) | Q1: 14-day trial, no card required. Q2: Free / Pro $39 / Pro+ $79 / Founders intro $29 for 6mo then $79. Q3: demo persistence is Phase 2 (deferred) | Frictionless wizard is Gate 1. Paywall on day one defeats signup-never-blocks posture. Pricing tiers are locked per memory. Demo persistence is post-v1 per demo.raxx.app deferral. |
| ADJ-12 | Beta tester program (#3403) — v1 or post-v1? | v1; closed-beta validation layer before public launch | Walkthrough scaffold is built. Scoring pipeline + operator digest complete the feedback loop. This is how product-market fit is validated before the public waitlist opens. |
| ADJ-13 | Passkey recovery scope for v1 | Card 1 only (Console ghost-reset tool); Card 2 (Stripe Identity self-serve) is post-v1 | Ghost-enrollment is a known failure mode. Console tool prevents recurring manual SQL incidents. Full self-serve requires architect threat-model and Stripe Identity integration — post-v1. |
| ADJ-14 | Alpaca data redistribution — proceed or gate? | Gate FLAG_PAPER_TRADING_V1 prod flip until operator makes an explicit documented decision | BLR confirmed the risk in #3483. Proceeding without a recorded decision creates legal exposure. Engineering ships behind the flag; the prod flip requires operator comment on #3483 with the decision. |
| ADJ-15 | Burr v2 multi-region HA (#1876–#1884) — v1 or post-v1? | Post-v1; Burr v1 is adequate for solo-operator launch | One operator, one region at launch. Burr v1 SSO-OIDC is functional. Multi-region HA adds infra complexity with zero v1 user impact. Ship in first 30-day post-launch window with RBAC Phase 3. |
| ADJ-16 | FLAG_CONSOLE_FLAG_PROMOTIONS — flip when? | After Wave 7 ships the promotion UI (#2016, #798 sub-cards) | The flag UI route returns 404 when the flag is OFF. Promotion flow must be tested against a real staging flag cycle before going ON in prod. |
| ADJ-17 | Velvet (#907) — when do #417 and #253 close? | At Wave 7 completion, when Velvet rotation is verified end-to-end | #417 and #253 are explicitly superseded by Velvet per the 2026-05-04 ship plan. They stay open as tombstones until the replacement is proven in prod, then close with a comment referencing the Velvet epic. |
5. Definition of Done per Surface
Antlers (raxx.app customer frontend)
- Self-onboarding flow complete end-to-end (passkey register, email verify, profile, broker connect paper, working Dashboard)
- Simulate surface renders paper portfolio tile and trade history; forward/backward toggle is URL-persisted; backtest tab not regressed
- Paper order submit sends
Idempotency-Keyheader on every request - All surfaces are CE-skinned (zero raw react-bootstrap chrome)
useFlag()used for all flag checks;isEnabled()removed from routing layer (#2280)- Beta walkthrough 5-screen flow renders; per-tester signed token works
- Error and empty states use Jupiter/Bandz illustrations (#1110)
Raptor (backend_v2 / api.raxx.app)
- Paper trading fill engine stable: market + limit orders, resting evaluation, expiry sweep, equity MTM, dividend/split adjustments, Founders-gated tax integration
- Idempotency middleware active on Tier-1 endpoints; replay returns correct 201 idempotently; replay events logged separately from audit rows
- Queue is the authoritative writer for customers/sessions; Raptor tables read-only
- OpenAPI 3.1 spec generated, accurate, and linked from docs
- All migrations through 0060 clean on Heroku Postgres prod and staging
- No
ghorherokuCLI shell-outs in any dyno process - Nightly security scan produces output for 7 consecutive nights
raxx-console (console.raxx.app)
- Deploy button shows accurate live deploy status without leaving the dashboard
- Flag promotion flow (mark-promote, promote) works without
heroku config:set - Ghost-reset tool allows operator to re-invite a stuck user without SQL
- Rotation modal (three-stage: verify, distribute, validate+revoke) works end-to-end for HEROKU_API_KEY
- CD freshness alert fires if prod lags main > 24h
Queue (C++ identity service)
- All consumer services read from Queue API (confirmed by QC-8 audit unification soak)
- Stripe webhook receiver deployed to Queue (no live billing at launch, but correct architectural home)
FLAG_QUEUE_V1ON in prod- No direct-DB reads from Raptor/Console/Antlers into Queue Postgres tables
iOS
Deferred. #4020 (disable ios-ci.yml) is the only iOS-related action in this plan.
6. Go/No-Go Checklist for Launch
Tracked as actionable checkboxes in #4166 (filed in Appendix A). Summary above in Wave 9 entry gate. No launch proceeds until every checkbox is TRUE.
7. Handoffs
software-architect: docs/architecture/defense-in-depth-to-production.md is a required input for the Wave 2 WAF design review and the Wave 9 security gate. When it ships, its WAF rule set is the canonical spec for #1735 and phases. Its idempotency-at-rest section confirms or escalates ADJ-1.
Marketing agent: docs/marketing/production-launch-portfolio.md is a required input to Wave 9 go/no-go (#4166). The portfolio defines the market-facing launch-ready bar. If it surfaces a feature gap not covered by v1 engineering, file a card immediately; the adjudicator will re-classify it.
card-groomer: Wave 4 kickoff requires breaking #3483 SC-1 through SC-15 and GAP-1 through GAP-5 into discrete sub-issues. File them at Wave 4 start with area:paper-trading, size:*, epic-linked, and needs-grooming labels. Use the dependency chain in the epic body to set blockers. Tag card-groomer ready for grooming pass on each.
Appendix A — New Cards Filed by This Plan
NEW-PTP-1: v1 launch go/no-go gate — staging walkthrough + checklist
See filing below.
NEW-PTP-2: Flip FLAG_PAPER_TRADING_V1 to prod — post-7-day-soak activation step
See filing below.
Appendix B — Closed Issues (by this plan)
| # | Title | Reason |
|---|---|---|
| #1556 | epic(raptor): migrate Raptor from SQLite to Postgres | Completed 2026-07-03; all sub-cards closed |
| #350 | infra: console PR previews via Heroku review apps | Duplicate of #1890 |