Source strategy: docs/marketing/demo-flow-strategy-2026-04-29.md
Audience: product-manager (card filing), ux-designer (wireframes), software-architect (session API + feature-flag design)
Status: v3, 2026-04-29 UTC. All 10 cards filed. BLR delivered (PR #480); Card 10 filed and blocked on privacy attorney sign-off. Epic #482.
What this doc is
A bullet-form checklist of everything that needs a card, a wireframe, or an architecture note, derived from the strategy doc. product-manager files the cards. ux-designer wires the flows. software-architect confirms the session API fits the existing Raptor architecture before implementation starts.
Pages / routes needed
demo.raxx.app — standalone deployment or subdomain routing to Antlers (confirm with software-architect)
Alternatively: raxx.app/demo with a feature-flagged route. Either works; the strategy is routing-agnostic.
Route does NOT require authentication (no passkey prompt at entry)
Route IS accessible pre-login (public, no auth middleware)
Session is gated by a demo session token (server-issued UUID, 30-minute TTL), not a user account
Feature flags needed
Flag
Purpose
Who sets it
demo_enabled
Master kill switch for the demo route
Ops
demo_ticker_set
Controls which tickers appear in the picker (default: SPX, SPY, QQQ)
Product
demo_founders_cta_variant
Switch CTA between "Join Founders" (seats available) and "Start Free" (seats full — no fallback waitlist)
Product, keyed to Founders seat count
demo_conversion_step_2
Enable "second proposal click" as a conversion trigger (off at launch)
Product
demo_backtesting_loop
Enable backtesting loop in the demo (off at launch; post-GA only)
Product
Cards for product-manager to file
Cards are listed in implementation dependency order.
Status: All 10 cards filed as of 2026-04-29 UTC. BLR delivered (PR #480). Card 10 is filed and blocked on privacy attorney sign-off. Epic #482.
Card 1 — Demo session API (#483)
New Raptor endpoint: POST /api/demo/session — issues a UUID session token, stores TTL (30 min) in Redis. No user record created. No PII stored.
Session token scopes two subsequent calls: POST /api/demo/propose and POST /api/demo/paper-fill
IP + browser fingerprint rate-limit: max 3 demo sessions per IP per 24-hour window. On breach, return a 429 with a conversion nudge payload (client renders the sign-up CTA instead of a generic error)
On session expiry: token invalidated server-side. Client receives a 401 on any subsequent demo API call and renders the "session expired" nudge (see Card 5)
No GDPR surface required — no PII is stored; session token is non-identifying by design. Confirm with software-architect that the Redis key shape aligns with existing session patterns.
Card 2 — Demo proposal endpoint (#486)
POST /api/demo/propose — accepts a weekly dollar goal (integer, USD), seed capital amount (integer, USD), and a ticker symbol (one of the allowed picker set), returns 2-3 candidate structures
Runs against a static historical chain snapshot (not live data). The snapshot is a frozen JSON file refreshed by an operator script (weekly or monthly cadence — separate ops card)
Proposal output shape must match the real /api/propose response shape so the UI component is shared, not forked
Session token required in request header; 401 if absent or expired
Card 3 — Demo paper-fill endpoint (#487)
POST /api/demo/paper-fill — accepts a proposal ID from Card 2's response; returns a simulated fill receipt (entry price from the static snapshot, Greeks, premium received, max loss, timestamp)
Fill is NOT written to the paper-trade ledger (no DB write). Fill receipt is returned in the response and stored client-side only (sessionStorage or React state — cleared on session expiry)
Session token required; 401 if absent or expired
On success: triggers the conversion moment (see Card 5). The conversion trigger is fired client-side when the fill receipt renders.
Card 4 — Demo Antlers UI (#488, blocked on ux-designer) (requires ux-designer mockup before engineering starts)
Dependency: ux-designer must produce wireframes for the full demo flow — especially the slider component and the ticker picker — before feature-developer picks this card up. The feasibility readout (Card 4a below) is a meaningful interactive component that needs design spec before implementation.
New Antlers route: /demo (or demo.raxx.app/ — routing TBD with software-architect)
Step 1: Two sliders (see Card 4a for feasibility readout spec)
Seed capital slider — "How much would you start with?" Default: $25,000 (PDT threshold anchor)
Weekly/daily goal slider — "What's your target?" Default: $500/week
Feasibility readout updates in real time as sliders move (see Card 4a)
Step 2: Ticker picker — row of labeled chips (SPX, SPY, QQQ at launch). Each chip shows the ticker symbol + a one-line plain-English explainer. SPX selected by default. One-click to change.
Step 3: Proposal cards (2-3 results). Each card shows: structure type, strikes, width, delta, premium, historical win-rate. User clicks a card to expand detail.
Step 4: Proposal detail. P/L diagram (pre-rendered against strikes from proposal). "Paper it" CTA button.
Step 5: Fill receipt. Entry price, delta, premium received, max loss, timestamp. Conversion overlay fires here (see Card 5).
Step 6 (read-only ledger snippet): Single-row ledger showing the just-filled trade. Read-only. No navigation to full ledger (no account).
"Direction C / Confidence Engine" visual system applies throughout. No demo-specific divergence from design tokens.
No authentication UI anywhere in the demo flow. No passkey prompt. No login link in the primary viewport (a subtle "Already have an account? Sign in" link in the footer is acceptable).
Card 4a — Feasibility readout component (#489, blocked on ux-designer) (requires ux-designer mockup; flag for ux-designer before filing)
This is a meaningful UX component. ux-designer must design the readout states and copy treatment before feature-developer implements it.
Real-time feasibility readout that responds to both sliders
Constraint logic to implement:
Seed < $25,000: surface PDT rule note (FINRA Rule 4210) with plain-English explanation. Language must steer toward swing/weekly options, NOT say "you can't trade"
Return-on-capital ratio is high (exact threshold TBD with software-architect — suggest >50% annualized implied): surface a "high return implies higher risk" plain-English note
Large seed + low goal + conservative profile: surface "this looks more like a traditional income portfolio — test this strategy" nudge
Moderate-to-high goal + options selected: surface "options can reach this target; risk rises with probability — test this strategy"
Every readout state ends with "Test this strategy" or "See the historical data" — never "You should" or "We recommend"
NOT financial advice. NOT a compliance questionnaire. Copy must be reviewed against legal/compliance posture before launch.
Thresholds are configurable via a config value (not hard-coded) so they can be tuned without a code deploy
Card 5 — Conversion overlay + CTA logic (#490)
Overlay fires once, after fill receipt renders (Step 5 above)
Overlay is dismissible ("Keep exploring the demo"). If dismissed, it does not fire again in the same session.
Primary CTA: "Create account" → routes to standard Raxx signup flow (raxx.app/signup or equivalent)
Passes demo_goal_amount (the weekly number from the slider) as a query param or sessionStorage key so onboarding can pre-fill it
Passes demo_seed_capital, demo_proposal_ticker, and demo_proposal_structure_type so onboarding can show "you were looking at this"
Conditional CTA variant (keyed to demo_founders_cta_variant flag):
Seats available: "Founders get 3 months free — join the list" → Founders signup flow
Seats full: "Start free — upgrade when you're ready" → standard Free signup flow. No waitlist. No "next cohort" promise. Founders offer is simply gone.
Secondary conversion triggers (off at launch; gated by feature flags):
Second proposal click: variant copy "Comparing structures? Sign up to save your ledger"
Session 25-minute mark: "5 minutes left in your demo. Create an account to keep going."
Card 6 — Demo analytics instrumentation (#491)
PostHog events to fire (Antlers + Raptor):
demo_session_started — on token issuance
demo_seed_capital_set — on slider move / final value (log amount, not PII)
demo_goal_entered — on weekly goal slider set (log amount, not PII)
demo_ticker_selected — on ticker chip click (log ticker symbol)
demo_proposal_clicked — on card expand (log proposal index: 1, 2, or 3)
demo_paper_fill_completed — on fill receipt render
demo_conversion_overlay_shown — on overlay display
demo_conversion_cta_clicked — on "Create account" click
demo_conversion_dismissed — on "Keep exploring" click
demo_session_expired — on 401 from session expiry
Microsoft Clarity session replay active on /demo route (already in analytics stack per epic #204)
Funnel in PostHog: demo_session_started → demo_goal_entered → demo_paper_fill_completed → demo_conversion_cta_clicked. Primary conversion metric is this funnel's bottom-of-funnel rate. Target baseline: 3% at launch; flag if below 1%.
Shell or Python script in scripts/ops/ that refreshes the demo's static chain snapshot for each ticker in the picker set (SPX, SPY, QQQ at launch)
Source: the same Alpaca historical data endpoint used for backtesting (no new vendor)
Output: a versioned JSON file per ticker (e.g., data/demo/spx-chain-snapshot-2026-04-25.json) committed or uploaded to a static store
Cadence: run weekly by default; run ad-hoc before any marketing campaign that drives traffic to demo
The demo proposal endpoint reads from the latest snapshot file; no fallback to live data
Ops card: add to scheduled recurring tasks (note: project_scheduled_recurring_tasks.md in memory — this is an addition to the existing schedule)
Card 8 — Founders-window conditional (#492) (feature flag wiring)
product-manager needs a way to flip demo_founders_cta_variant when the Founders cohort hits 250 seats
When flipped: CTA drops to standard Free — no waitlist, no "next cohort" promise. The Founders offer is simply closed.
Options: (a) manual flag flip when PM gets the alert, or (b) automated: Raptor checks remaining Founders seats on every demo session start and returns a flag payload with the session token
Recommend (b) for correctness; (a) is acceptable for MVP given manual cohort monitoring
Confirm with software-architect which pattern fits the existing Founders seat-count data model (per founders-trial-engine design doc)
Card 9 — demo.raxx.app subdomain + routing (#485)
DNS: add demo CNAME to Cloudflare pointing at the appropriate Antlers deployment or Heroku app
Confirm with software-architect whether demo runs as a separate Antlers deploy or a feature-flagged route in the primary Antlers build
Either approach is valid; separate deploy gives blast radius isolation (a broken demo doesn't take down raxx.app); same deploy reduces ops overhead
noindex meta tag on all demo pages (demo is a conversion tool, not an SEO surface)
Status: Blocked. Do not file until business-legal-researcher delivers its analysis.
The question being researched: what does an email-gated "continue session" flow look like that complies with CAN-SPAM, GDPR, and applicable privacy rules — without requiring email-list management infrastructure or an identity provider?
Once BLR delivers, this card will specify:
- What can legally be stored (email address, duration, purpose limitation)
- What copy is required (opt-in language, data use disclosure)
- What the session-continuation UX is allowed to do vs. what requires full account creation
UX designer notes
The demo flow is linear (6 steps including the dual-slider opening, no branching). Wireframes should reflect a step-progress indicator or visual flow so the visitor knows they're 3/6 of the way through, not stuck.
Step 1 (dual sliders + feasibility readout) is the most design-intensive moment. The sliders need to feel like a financial tool, not a form. The feasibility readout must update smoothly and not feel like a warning label. This needs a careful design pass before engineering starts. Flag this for ux-designer explicitly.
The ticker picker (Step 2) should look like a row of chips or cards — not a dropdown. Each chip: ticker symbol large, one-line explainer small beneath it. Selected state should be visually distinct. This component is quick to implement once the design is clear, but it needs a spec.
Step 5 (fill receipt) is the highest-stakes design moment. The receipt must communicate: this is real (prices are real historical fills, not fake numbers), this is paper (no money moved), and this is the beginning of the audit trail. Copy: "Paper filled. This would have entered your ledger." or similar. Confirm copy with messaging.md voice rules.
The conversion overlay in Step 5 must NOT feel like a modal paywall. It should feel like an invitation. Dismissible without friction. Two options only: "Create account" and "Keep exploring." No countdown. No urgency theater.
The read-only ledger snippet (Step 6) is a dessert, not a gate. The user has already done the thing; the ledger is proof. It should be minimal — one row — and have a subtle "Your account would show this forever" or equivalent framing pointing toward sign-up.
Architecture notes (for software-architect)
Demo session token must not be compatible with the real account session token. Different key prefix in Redis, different TTL semantics, different auth middleware path.
The demo proposal and paper-fill endpoints should share response schema with their authenticated equivalents so Antlers components can be reused without forking.
No DB writes in the demo path. Redis only (session token + TTL). If Redis is unavailable, the demo returns a maintenance-mode page; it should not fail open (no fallback to in-memory sessions that circumvent rate-limiting).
The static chain snapshot file path should be configurable via an environment variable (not hardcoded) so it can be updated without a code deploy. The snapshot set must cover all tickers in the picker (SPX, SPY, QQQ at launch).
The proposal endpoint accepts a ticker parameter; validate it against an allowlist (the configured picker set) — do not pass arbitrary tickers to the proposal engine from an unauthenticated path.
GDPR implications: no PII stored, no cookies created beyond the session token (which is non-identifying). Confirm with the existing privacy posture before launch.
The feasibility readout thresholds (PDT floor, ROC warning threshold) should be sourced from a config value, not hard-coded, so product can tune them without a deploy.
Dependency map
Card 1 (session API) → Card 2 (propose endpoint) → Card 3 (paper-fill endpoint)
Card 4 (Antlers UI) → depends on Card 2 + Card 3 response shapes being stable; requires ux-designer wireframes first
Card 4a (feasibility readout) → requires ux-designer design spec; implement alongside Card 4
Card 5 (conversion overlay) → depends on Card 4
Card 6 (analytics) → can be filed in parallel with Card 4; instrumentation added during Card 4 implementation
Card 7 (snapshot script) → independent; can ship before Card 2 and seed the snapshot file
Card 8 (Founders flag wiring) → depends on Card 5 being designed; confirm with founders-trial-engine architecture
Card 9 (DNS / routing) → independent of code; can be prepped in parallel
Card 10 (#493 — session continuation) → BLOCKED on privacy attorney sign-off (BLR delivered PR #480; attorney engagement TBD)
What is NOT in scope for these cards
The standard account-creation flow that the demo conversion CTA routes to — that is existing Antlers work, not demo work
Founders promo mechanics (trial timer, feedback form, referral links) — those are epic #204 cards, already in flight
Live market data for the demo — out of scope by strategy decision; demo uses static historical snapshot only
Backtesting loop in the demo — deferred to post-GA; flag as a future card but do not file now
Session continuation / email gating — filed as #493; blocked on privacy attorney sign-off; BLR analysis complete (PR #480)