Raxx · internal docs

internal · gated

ADR 0115 — Persona-Routed Beta Walkthrough Scenarios

Status: Accepted Date: 2026-06-26 UTC Deciders: Kristerpher (operator) via #3855 design card Scope: Raptor (beta_walkthrough.py), Antlers (WalkthroughScreenClient.tsx), beta_walkthrough_progress, beta_walkthrough_paper_trades tables, feature_flags.yaml


Context

The beta activation walkthrough serves all full-track testers a single frozen SPX Iron Condor scenario. The operator has defined three intent buckets that each require a different scenario and builder. Before implementation can start, eight design questions must be answered — flag topology, intent-bucket storage, builder strategy for Covered Call and Vertical Spread, route structure, fixture schema, and paper-trade table approach.


Decision

One new independent flag (FLAG_WALKTHROUGH_PERSONA_ROUTING) gates this feature. It does not extend FLAG_BETA_WALKTHROUGH_SELF_SELECT. The two flags compose via a matrix (see beta-walkthrough-persona-routing.md §3.Q1).

intent_bucket is stored as a dedicated nullable TEXT column on beta_walkthrough_progress with a CHECK constraint ('income' | 'covered_call' | 'directional' | 'unknown'). It is not serialised into persona_answers.

Route structure is uniform: /screen/2 and /screen/3 return scenario-specific payloads driven by the stored intent_bucket. No new route segments.

Covered Call builder is a self-contained static guide in the walkthrough route handler. It does not call strategy_templates_v2. The guide enforces otm_only and min_dte inline.

Vertical Spread builder reuses /screen/simple/1 with a VS-specific payload when intent_bucket = 'directional'. No new route. No new fixture file needed (static inline data).

Paper trade table: the existing legs_json column stores all leg data for CC and VS fills. A new strategy_type TEXT NOT NULL DEFAULT 'iron_condor' column tags the shape. IC-specific named columns are left NULL for CC/VS fills; this is documented and intentional.

Survey (screen 5) is uniform across all three paths. No branching. intent_bucket is accessible via join to the progress row for offline analysis.

All resolutions are detailed in docs/architecture/beta-walkthrough-persona-routing.md.


Language choice rationale

This ADR does not introduce a new service. The feature extends an existing Raptor (Python / Flask) route file and an existing Antlers (TypeScript / Next.js) component. No language-tier classification is required.


Consequences

Positive

Negative / risks

Neutral


Alternatives considered

Alt A — extend persona_answers JSONB to store intent_bucket

Rejected: persona_answers is NULL for testers who chose the self-select track. Reading a routing key from a JSON blob on every hot-path request is fragile and slower than a column lookup. A dedicated column with a CHECK constraint is safer and more explicit.

Alt B — scenario-prefixed routes (/screen/cc/2, /screen/ic/2)

Rejected: adds route proliferation and requires frontend URL-routing logic. The frontend already renders whatever the API returns. Uniform route + payload branching by intent_bucket is simpler and keeps the frontend dumb.

Alt C — route CC through strategy_templates_v2

Rejected: creates a flag dependency. If FLAG_STRATEGY_TEMPLATES_V2 is OFF (which it is by default), the CC walkthrough path would silently break. The walkthrough must be self-contained.

Alt D — new table per strategy type

Rejected: over-engineered for a pre-launch beta exercise. legs_json + strategy_type on the existing table is sufficient.


Security / GDPR checklist


Revisit when