SRS: Stage 3 KYC & Live Onboarding — UC_5.8: Flow 3H Live Account Provisioning & Risk Setup
| Field | Value |
|---|---|
| BA in Charge | linh.nguyen34 |
| Date Created | 2026-08-08 |
| Version | v2.2 |
| Last Updated | 2026-08-25 — Q8–Q18 applied: Step 2.1 field alias note (fcm_subaccount_id = rithmic_subaccount_id); §9 NFR Latency updated to async design (HTTP 202, background worker, Zapier 10s timeout); §10 Connections & Credentials tab disabled state; BR_5.8.2 Current_Level IN (1,2,5) validation gate; §4 Post-conditions ledger fire-and-continue note; §5 Step 1 Level 2 single-row clarification; §6 Alt-2 no-re-run note for Flow 3H on feed upgrades; §5 Users table sim_data_cancel_pending + sim_data_valid_until schema; Exc-8 ERR-DECOM-01 queue specs (Redis, 5 retries, exponential backoff, Saga partial retry); §7 Sub-step 7.1 5-second S3 timeout. |
| Document References | Zapier Integration V7.pdf (Flow 3H lines 1264–1332; Appendix A Table A lines 2952–3004; Appendix B Table B lines 3005–3031; Flow 3F lines 1222–1240; Flow 3G lines 1251–1263) · RFQ_ Stack Trading Prop Tech V7.pdf (POST /provisioning/live-trader lines 1115–1167; Rithmic Live FCM Gateway lines 258–260; Forex Gateway lines 264–280; Platform Entitlement lines 1147–1157; Ledger Init lines 1158–1167; POST /api/ledger/record §Immutable Ledger; Certificate endpoint; Public Ledger Feed) · RFQ_ Website and Dashboard Implementation V7.pdf (Connections & Credentials tab lines 593–594; Market Data Management lines 596–632) · CR-20260720-001 (TradeSea replaces NinjaTrader — affects Platform Entitlement step in Flow 3H) · User Journey Certificate Dynamic Text Mapping |
UC Index
| UC_ID | Use Case Name | Business Description |
|---|---|---|
| UC_5.8 | Flow 3H — Live Account Provisioning & Risk Setup | Final automation step of Stage 3 onboarding. Triggered when both contract_status = 'Signed' AND setup_status IN ('Complete', 'N/A') are simultaneously true. Provisions the trader's real-money DMA account: routes to Ironbeam FCM sub-account (Futures via Rithmic) or Stack Trading Omnibus corporate account (Forex via MT5/TraderEvolution). Injects Level_Starting_Capital, initialises the virtual ledger, applies professional market data or firm-paid standard data, writes encrypted credentials to the Users table, logs an immutable on-chain ledger entry, sends the Live_Onboarding_Credentials Go Live email, and triggers Flow 10 (Pod Mentorship Onboarding). |
Changelog
| Date | Version | Updated item | Before | After | Notes |
|---|---|---|---|---|---|
| 2026-08-08 | v1.0 | Initial creation | — | Created SRS for UC_5.8 (Flow 3H) | First authoring pass |
| 2026-08-10 | v1.1 | Q1: Endpoint name conflict resolved — /provision-live-user (zapier_v7_full.txt line 1297) confirmed as documentation error; POST /provisioning/live-trader is canonical | ⚠️ Source conflict flag (CRITICAL) | Confirmed by client 2026-08-10: RFQ Prop Tech Spec is the official API Contract; Zapier doc had Row Title copied into Path field | QnA STAGE3-014 confirmed 2026-08-10 |
| 2026-08-10 | v1.2 | Q4: CMR Agreement signing sequence confirmed — AFTER provisioning, not a pre-condition; BR_5.8.14 added; §3 and §4 updated with CMR lock/unlock sequence | CMR sequence unconfirmed (Q4 open) | Confirmed: provisioning → credentials email → first R | Trader Pro login → Rithmic intercepts + forces CMR signing → feeds unlocked |
| 2026-08-10 | v1.3 | Q3: is_professional field confirmed as Middleware-internal output, NOT a Zapier input; Step 2.6 response JSON updated; Step 4 DB write-back table updated; BR_5.8.5 updated with two write-point context | is_professional listed only in BR_5.8.5 as CME Professional enforcement; not tracked in DB write-back | Confirmed: Middleware internally enforces + returns is_professional: true in response; Zapier writes to DB at Step 4. Also confirmed: Flow 3E (contract signing) sets is_professional = True in DB as a contract execution gate | QnA STAGE3-018 confirmed 2026-08-10 |
| 2026-08-10 | v1.4 | Q5: CR-20260727-005 banner behavior scoped INTO UC_5.8 (not a separate Dashboard UC); BR_5.8.14 updated with GET /bps/trader/market-data-status endpoint, trigger condition, and JSON response structure; AC-5.8-13 added | Q5 open — scope undecided; BR_5.8.14 referenced GET /market-data-status (incomplete path) | Confirmed: UC_5.8 owns the Rithmic feed-lock state machine. Banner trigger: account_status == 'Active_L[X]_DMA' AND rithmic_status.CME == false. Endpoint: GET /bps/trader/market-data-status | QnA STAGE3-019 confirmed 2026-08-10 |
| 2026-08-10 | v1.5 | Q2: data_selections confirmed as canonical API parameter name; Market_Data_Selections is Zapier's internal variable, mapped to data_selections in POST body; source resolution note added to Step 2; example payload added | ⚠️ Field name conflict flag open (Q2) | data_selections is the API Contract name (v7_full.txt). Zapier internal variable Market_Data_Selections is mapped to this key before the HTTP POST is sent. | QnA STAGE3-020 confirmed 2026-08-10 |
| 2026-08-10 | v1.6 | Q6: All 7 exceptional flows confirmed; §7 rewritten with confirmed retry/rollback/escalation behavior; BR_5.8.15 (idempotency gate) added | All Exc-1 to Exc-7 flagged ⚠️ unconfirmed | Exc-1/2/3: CloudWatch Sev-1 Slack alert; Break-Glass Runbook for Exc-2/3. Exc-4: open question on DeleteUser rollback. Exc-5: fire-and-continue recommended (queue-and-retry). Exc-6: manual admin recovery. Exc-7: confirmed idempotency gate required (account_status + platform_username check). | QnA STAGE3-021 confirmed 2026-08-10 |
| 2026-08-10 | v1.7 | Re-audit v10 applied: §9 NFR updated (Idempotency confirmed BR_5.8.15; Atomicity updated with Exc rollback behaviors; CR-08 + CR-11 citations added); §11 AC updated (7 new ACs added: AC-5.8-14 idempotency double-trigger, AC-5.8-15 credentials_claimed_at, AC-5.8-16/17/18/19 Level 2/5 capital values, AC-5.8-20 GET /platform-credentials post-write-back) | §9 NFR: Idempotency row had [⚠️ guard not documented]; Atomicity had [⚠️ rollback not documented]; no CR-08/CR-11 citations; §11 had 13 ACs (missing idempotency, capital boundary, credentials-tab, Level 2/5) | §9 NFR: fully reflects confirmed state per STAGE3-021; §11: 20 ACs total (7 new) | audited-v10.md re-audit 2026-08-10 |
| 2026-08-15 | v1.4 | Step 5 SES template rename (H-12); Exc-1 auto-retry confirmed (H-13); Exc-4 DeleteUser mandatory (H-14); Exc-5 BullMQ async + 24h SLA (H-15); §9 NFR Atomicity updated | Live_Onboarding_Level_1; Exc-1 [⚠️ BA to confirm]; Exc-4 DeleteUser [⚠️ BA to confirm]; Exc-5 fire-and-continue BA recommendation | Template renamed to Live_Onboarding_Credentials (STAGE3-060/H-12); 3× Exp Backoff + SEV1 Slack + Break-Glass (STAGE3-061/H-13); DeleteUser mandatory on Ledger fail (STAGE3-062/H-14); BullMQ/Redis async, HTTP 200 immediate, hourly retry, 24h SLA (STAGE3-063/H-15) | H-12 through H-15 confirmed 2026-08-15 |
| 2026-08-12 | v1.2 → v1.3 | §3 P5 updated — fcm_subaccount_id source changed | "From Ironbeam JSON payload set during Flow 3B.2" | "Assigned from pre-provisioned bulk pool at Veriff APPROVED" — Flow 3B.2 deprecated (STAGE3-037 [CHR-46]/039). §2 Trigger payload note also updated. | STAGE3-037 [CHR-46] / [CHR-46] confirmed 2026-08-12 |
| 2026-08-12 | v1.2 → v1.3 | §3 P7 added — payout_status = 'Approved' pre-condition (NEW) | Flow 3H only checked contract_status + setup_status | Added payout_status = 'Approved' as P7 — prevents provisioning a trader whose Dots account was suspended after contract signing. Complements Dots suspension webhook listener in UC_5.4 BR_5.4.8. | STAGE3-038 [CHR-44] confirmed 2026-08-12 |
Glossary
For all shared project terminology, refer to: Project Glossary.
UC_5.8 — Flow 3H: Live Account Provisioning & Risk Setup
1. Overview
| Field | Content |
|---|---|
| ID | UC_5.8 |
| Use Case | Flow 3H — Live Account Provisioning & Risk Setup |
| Description | Final automation in Stage 3. Triggered by dual aggregation gate: contract_status = 'Signed' (set by UC_5.5 / Flow 3E) AND setup_status IN ('Complete', 'N/A') (set by UC_5.6/UC_5.7). Whichever condition fires last triggers Flow 3H. The flow (1) queries Table A (Forex) or Table B (Futures) for the trader's Current_Level; (2) routes to the correct execution gateway (Rithmic Live FCM for Futures, MT5/TraderEvolution Forex Omnibus for Forex); (3) calls POST /provisioning/live-trader — a 6-step Middleware operation that creates the sub-account, forces Professional status (Futures only), calculates risk, injects Level_Starting_Capital, and initialises the virtual ledger; (4) applies market data (Professional premium if market_data_billable = True, else firm-paid Standard as Professional); (5) writes encrypted credentials back to the Users table and sets account_status = 'Active_L[N]_DMA'; (6) calls POST /api/ledger/record for immutable on-chain logging; (7) sends the Live_Onboarding_Credentials credentials email; (8) triggers Flow 10 (Pod Mentorship Onboarding). |
| Zapier Flow | Flow 3H (Live Account Provisioning & Risk Setup) |
| Backend Endpoint | POST /provisioning/live-trader (main provisioning — 6-step Middleware logic) · POST /api/ledger/record (immutable ledger logging) · GET /platform-credentials (Dashboard credential display) · GET /bps/trader/market-data-status (Rithmic CMR agreement status check — used to determine feed-lock banner state) |
| Zapier Table | Users table (contract_status, setup_status, asset_class, Current_Level, platform_selection, market_data_billable, fcm_subaccount_id, platform_username, platform_password_ciphertext, license_key_ciphertext, cipher_version, credentials_last_rotated_at, credentials_claimed_at, account_status) · ledgers table (user_id, level_id, virtual_equity, allocated_capital, mapped_account_id, is_active, last_sync) |
| 3rd Party | Rithmic API (Futures: Ironbeam FCM sub-account assignment, Risk Group Template, Professional Market Data) · MT5 Manager API (Forex: Sub Account creation, Omnibus assignment) · TraderEvolution Admin API (Forex: Group assignment, symbol/position/liquidation params) · YourBourse Bridge (Forex: trade routing, position limits, Contest Plugin) · AWS SES (Live_Onboarding_Credentials email) · TradeSea (Futures platform entitlement — per CR-20260720-001 replacing NinjaTrader 8) |
CR-20260720-001 (ACTIVE, HIGH): TradeSea replaces NinjaTrader 8 as the Futures trading platform. The Platform Entitlement step in
POST /provisioning/live-traderpreviously called the NinjaTrader Enterprise Prop API to provision the "Multi-Broker" entitlement. This must now call the TradeSea equivalent. Exact TradeSea API call is not yet documented in Customer supplies; source states "TradeSea → Rithmic API for account provisioning" — the integration flow remains the same gateway (Rithmic) but the platform entitlement call is TradeSea-specific. (Source: CR-20260720-001 CR_summary.md)
Scope note — dual aggregation gate: Flow 3H fires exactly once per trader when both
contract_status = 'Signed'ANDsetup_status IN ('Complete', 'N/A')are satisfied simultaneously. UC_5.5 / Flow 3E setscontract_status = 'Signed'. UC_5.6 / Flow 3F setssetup_status = 'N/A'(Futures Option A) or UC_5.7 / Flow 3G setssetup_status = 'Complete'(Futures Option B). Forex traders receivesetup_status = 'N/A'from Flow 3F directly. The gate fires from either side: ifsetup_statusis set first, Flow 3F/3G re-checkscontract_status; ifcontract_statusis set first, Flow 3E re-checkssetup_status. (Source: Zapier Integration V7.pdf lines 1224–1264)
Scope note — entry levels only: Traders enter the live phase at Level 1, 2, or 5 only.
Level_Starting_Capitalis pulled from Table A (Forex) or Table B (Futures) for the trader'sCurrent_Level. (Source: Zapier Integration V7.pdf lines 1269–1290)
Scope note — NinjaTrader references in source: v7_full.txt lines 1109–1114 and 1147–1157 describe Platform Entitlement for NinjaTrader 8. These are superseded by CR-20260720-001 (TradeSea). All NinjaTrader-specific API calls in those lines apply to TradeSea per the CR.
2. Trigger
Internal Webhook from Zapier aggregation check, fired when both conditions are true simultaneously:
contract_status = 'Signed'(written by UC_5.5 / Flow 3E at ISDA/Trader Agreement signing completion)setup_status IN ('Complete', 'N/A')(written by UC_5.6 / Flow 3F for Option A or Forex; written by UC_5.7 / Flow 3G for Futures Option B)
Which flow fires the trigger:
- If
setup_statusis set last (by Flow 3F or 3G): Flow 3F/3G performs the aggregation check —IF contract_status == 'Signed' → trigger Flow 3H via internal Webhook. (Source: Zapier Integration V7.pdf lines 1238 and 1261) - If
contract_statusis set last (by Flow 3E): Flow 3E performs the aggregation check —IF setup_status == 'Complete' OR setup_status == 'N/A' → trigger Flow 3H via internal Webhook. (Source: Zapier Integration V7.pdf lines 1224)
Payload to Flow 3H: user_id, asset_class, Current_Level, platform_selection, market_data_billable, fcm_subaccount_id (Futures only — assigned from pre-provisioned bulk pool at Veriff APPROVED; from Ironbeam JSON payload set during Flow 3B.2 deprecated per STAGE3-037 [CHR-46]/039).
3. Pre-conditions
| # | Condition |
|---|---|
| P1 | contract_status = 'Signed' — trader has completed ISDA/Trader Agreement signing (UC_5.5) |
| P2 | setup_status IN ('Complete', 'N/A') — trader has completed Level 1 Setup (UC_5.6) and paid for market data add-ons if applicable (UC_5.7) |
| P3 | Trader's Current_Level is 1, 2, or 5 — valid live entry levels |
| P4 | asset_class is either 'Futures' or 'Forex' — determines gateway routing |
| P5 | fcm_subaccount_id is populated from Ironbeam JSON payload (set during Flow 3B.2 Ironbeam KYC)fcm_subaccount_id is assigned from the pre-provisioned bulk pool at the time of Veriff APPROVED (no longer from an inbound Ironbeam JSON via the deprecated Flow 3B.2). |
| P6 | is_professional = True already set at contract signing (Flow 3E) for Futures traders |
🔄 CR — STAGE3-038 [CHR-44]: payout_status = 'Approved' added as mandatory P7 pre-condition. Prevents provisioning a trader whose Dots account was suspended after contract signing.
| P7 | payout_status = 'Approved' — trader's Dots payout profile must be Active and Payable. (NEW — STAGE3-038 [CHR-44] 2026-08-12) If the trader's Dots account was suspended after contract signing (payout_status = 'Suspended'), Flow 3H MUST NOT proceed — funding a trader with a broken payout profile is incorrect. This check prevents the case where a Dots suspension between contract signing and market data setup is silently bypassed. |
CMR Agreement signing is NOT a pre-condition for Flow 3H. Per QnA STAGE3-017 (confirmed 2026-08-10): traders cannot sign CMR agreements until they have platform credentials to log into R|Trader Pro. Flow 3H must provision the account and generate credentials first. CMR signing occurs post-provisioning as a separate activation step — see §4 Post-conditions and BR_5.8.14.
4. Post-conditions
On success (both asset classes):
account_status = 'Active_L' + Current_Level + '_DMA'(e.g.,Active_L1_DMA,Active_L2_DMA,Active_L5_DMA)platform_username,platform_password_ciphertext,license_key_ciphertext,cipher_versionwritten to Users tablecredentials_last_rotated_at = NOW(),credentials_claimed_at = NULLledgerstable record inserted:user_id,level_id = Current_Level,virtual_equity = Level_Starting_Capital,allocated_capital = Level_Starting_Capital,mapped_account_id = [FCM sub-account ID or Forex Omnibus ID],is_active = true,last_sync = NOW()- Immutable on-chain ledger entry logged via
POST /api/ledger/record Live_Onboarding_Credentialsemail sent to trader with credentials- Flow 10 (Pod Mentorship Onboarding) triggered
Q12 (confirmed 2026-08-25): Step 3 (
POST /api/ledger/record) is fire-and-continue (see Exc-5). Ledger failure does NOT block Step 5 credentials email — credentials delivery depends only on Step 4 (DB write-back) succeeding. Ledger failure is queued for BullMQ/Redis hourly retry independently.
- SIM Decommissioning Protocol initiated asynchronously (Step 7): SIM trade history archived to PostgreSQL + S3 Glacier → SIM Non-Pro market data unsubscribed (rights cached through end of calendar month) → Rithmic Paper Gateway
Unassignexecuted
Futures-specific post-conditions:
- Trader provisioned on specific
fcm_subaccount_idfrom Ironbeam, assigned to predefined Rithmic Risk Group Template - CME Subscriber Status hardcoded to
'Professional'at Rithmic level - IF
market_data_billable = True: Professional Market Data + selected add-ons (NYMEX/CBOT/COMEX) active via Rithmic - IF
market_data_billable = False: Standard Data (Firm Covered) provisioned as Professional - CMR feed lock applied automatically by Rithmic: Live market data feeds are in
Disabled/Lockedstate immediately after provisioning. Feeds unlock only after trader's first login to R|Trader Pro triggers native CMR/exchange agreement signing. Dashboard warning banner displayed during lock period (per CR-20260727-005). See BR_5.8.14.
Forex-specific post-conditions:
- Sub Account ID
ST_LIVE_[user_id]created in MT5/TraderEvolution - Assigned to TraderEvolution Group or MT5 Group
- Symbol permissions, position limits, auto liquidate parameters (max loss and target profit freeze) configured
Level_Starting_Capitalinjected as Account Balance to Omnibus corporate account sub-account
5. Basic Flow
Step 1 — Matrix Lookup
Action (Zapier): Query Table A (Forex) or Table B (Futures) using the trader's Current_Level (1, 2, or 5).
Output:
Level_Starting_Capital— capital injection amount (Futures:Futures_Capitalfrom Table B; Forex:Level_Starting_Capital = Max_Forex_Notional / 50from Table A)Max_Contracts_ES_Equiv(Futures only) — contract limit for Risk Group TemplateAssets_Permitted(Futures only) — asset class whitelist
Table B (Futures) entry level values:
| Level | Title | Futures_Capital | Profit_Target | Market_Loss | Max_Contracts_ES_Equiv | Assets_Permitted |
|---|---|---|---|---|---|---|
| 1 | Associate Trader | $1,250 | $1,875 | $1,250 | 8 Micros | Micros Only (MES, MNQ, M2K) |
| 2 | Associate Trader | $2,500 | $3,750 | $2,500 | 16 Micros | Micros Only (MES, MNQ, M2K) |
Q13 (confirmed 2026-08-25): Level 2 has 1 entry row only. The second row visible in zapier_v7_full.txt lines 2959–2960 is the Level 2 → Level 3 promotion threshold, NOT a second entry option. No selection mechanism needed.
| 5 | Associate Trader | $11,250 | $14,100 | $10,500 | 7 Minis | All Asset Classes |
(Source: Zapier Integration V7.pdf Appendix B Table B lines 3014–3018)
Table A (Forex) entry level values:
| Level | Title | Max_Forex_Notional | Level_Starting_Capital (÷50) | Profit_Target | Market_Loss |
|---|---|---|---|---|---|
| 1 | Associate Trader | $25,000 | $500 | $1,875 | $1,250 |
| 2 | Associate Trader | $75,000 | $1,500 | $5,625 | $3,750 |
| 5 | Associate Trader | $750,000 | $15,000 | $70,500 | $52,500 |
(Source: Zapier Integration V7.pdf Appendix A Table A lines 2958–2966; Level_Starting_Capital formula: Zapier Integration V7.pdf line 1370)
Step 2 — Live Account Execution (POST /provisioning/live-trader)
Action (Zapier): Call Middleware Hub endpoint POST /provisioning/live-trader.
Source resolution (Q1 — confirmed 2026-08-10):
zapier_v7_full.txtline 1297 incorrectly showsPOST /provision-live-user— this is a documentation error where the Zapier author copied the Row Title (function name) from the RFQ table into the Endpoint Path field. TheRFQ_ Stack Trading Prop Tech V7.pdf(official Middleware Hub API Contract) is authoritative: canonical path isPOST /provisioning/live-trader. (Source: QnA STAGE3-014)
Source resolution (Q2 — confirmed 2026-08-10):
zapier_v7_full.txtline 1298 refers to this field asMarket_Data_Selections— this is Zapier's internal variable name for the data held in Zapier's own automation context. When Zapier constructs the HTTP POST body to Middleware, it mapsMarket_Data_Selections→data_selections.data_selectionsis the canonical API Contract parameter name that the Node.js backend expects. UC_5.8 already uses the correct name throughout. (Source: QnA STAGE3-020)
Input:
| Field | Value | Notes |
|---|---|---|
user_id | Trader's user_id | From Zapier payload |
risk_group | "Live_W2" | Fixed value per RFQ_ Stack Trading Prop Tech V7.pdf line 1116 |
data_selections | Selected add-on feeds (e.g., ["CME_Bundle", "NYMEX_Bundle"]) | Mapped from Zapier internal variable Market_Data_Selections (zapier_v7_full.txt line 1298). API Contract parameter name is data_selections (v7_full.txt). |
fcm_subaccount_id | Specific Ironbeam FCM sub-account ID | Futures only — drawn from pre-provisioned bulk pool (Flow 3B path deprecated per STAGE3-037 [CHR-46]); optional for Forex |
Example payload:
{
"user_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"risk_group": "Live_W2",
"data_selections": ["CME_Bundle", "NYMEX_Bundle"],
"fcm_subaccount_id": "FCM-100293"
}(Source: QnA STAGE3-020 confirmed 2026-08-10)
Internal Logic (Node.js — 6 steps):
Step 2.1 — Gateway Routing:
- IF
asset_class = 'Futures': Route to Rithmic Live FCM Gateway (Ironbeam). Provision the specificfcm_subaccount_idpassed in payload. Assign to predefined Rithmic Risk Group Template. - IF
asset_class = 'Forex': Route to MT5/TraderEvolution Forex Omnibus corporate account at Forex.com / Interactive Brokers. Create Sub Account ID:ST_LIVE_[user_id].
Q8 field alias (confirmed 2026-08-25):
fcm_subaccount_id(the API parameter name Zapier passes toPOST /provisioning/live-trader) andrithmic_subaccount_id(the DB column name in PostgreSQL Users table) refer to the same physical value — the Ironbeam sub-account ID. Middleware mapsfcm_subaccount_idfrom the request body torithmic_subaccount_idin DB. No schema change needed; alias confirmed.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1117–1128)
Step 2.2 — Sub Account Creation:
- Futures: Provision
fcm_subaccount_idon Rithmic Live FCM Gateway. Assign to predefined Risk Group Template. Capital Injection: pushLevel_Starting_Capitalas Account Balance via Rithmic Administration API. - Forex: Create Sub Account
ST_LIVE_[user_id]. Assign to TraderEvolution Group or MT5 Group. Establish symbol permissions, position limits, auto liquidate parameters (max loss freeze and target profit freeze). Capital Injection: pushLevel_Starting_Capitalvia MT5 Manager API or TraderEvolution Admin API. (Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1123–1140)
Step 2.3 — Professional Status Forced (Futures Only):
Override any previous data selections. Hardcode CME Subscriber Status to 'Professional' for all Rithmic Live accounts. 100% of live Futures traders are classified as Professional.
(Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1141–1146)
Step 2.4 — Risk Calculation & Platform Entitlement:
- Market Data:
- IF
market_data_billable = True: Provision Professional Market Data + selected add-ons (NYMEX, CBOT, COMEX) via Rithmic API. - ELSE: Provision Standard Data (Firm Covered) as Professional. (Source: Zapier Integration V7.pdf lines 1282–1285)
- IF
- Platform Entitlement (TradeSea — per CR-20260720-001): If
platform_selection = 'TradeSea', call TradeSea platform entitlement API to provision the account. [⚠️ Exact TradeSea API call not documented in source — NinjaTrader Enterprise Prop API superseded by CR-20260720-001; TradeSea equivalent to be confirmed with client.] (Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1147–1157 — original NinjaTrader logic; CR-20260720-001 override applies)
Step 2.5 — Ledger Initialization:
INSERT into ledgers table:
user_id = payload.user_idlevel_id = Current_Levelvirtual_equity = Level_Starting_Capitalallocated_capital = Level_Starting_Capitalmapped_account_id = [Specific FCM Sub Account ID (Futures) OR Forex Omnibus Account ID (Forex)]is_active = truelast_sync = NOW()(timestamp of initial ledger creation) (Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1158–1165; V7 ledger spec 2026-08-13)
Step 2.6 — Return Credentials: Middleware returns to Zapier:
{
"live_username": "[username]",
"live_password": "[password]",
"license_key": "[license_key]",
"is_professional": true
}is_professional is internally enforced by Middleware (hardcoded for all Futures live accounts per Step 2.3 — not a Zapier input parameter). It is returned in the response payload for Zapier to write back to the DB in Step 4. (QnA STAGE3-018, confirmed 2026-08-10)
(Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1115–1122)
Step 3 — Immutable Ledger Logging (POST /api/ledger/record)
Action (Zapier): Call Middleware Hub endpoint POST /api/ledger/record.
| Field | Value |
|---|---|
trader_id | payload.user_id |
metric_category | "Associate Track Passed" |
metric_value (Futures) | "Live Account Funded (Level Target Notional Equivalent)" |
metric_value (Forex) | "Live Account Funded (Level Target Notional)" |
date | Today |
receipt_hash | PostgreSQL Ledger ID |
(Source: Zapier Integration V7.pdf lines 1305–1314)
Step 4 — Database Write-Back (Credentials)
Action (Zapier): UPDATE Users table WHERE user_id = payload.user_id.
| Field | SET Value |
|---|---|
platform_username | response.platform_username |
platform_password_ciphertext | response.platform_password_ciphertext |
license_key_ciphertext | response.license_key_ciphertext |
cipher_version | response.cipher_version |
credentials_last_rotated_at | NOW() |
credentials_claimed_at | NULL |
is_professional | response.is_professional (True for all Futures live accounts — written here from Middleware response; first set by Flow 3E at contract signing as a contract execution gate) |
account_status | 'Active_L' + Current_Level + '_DMA' (e.g. Active_L1_DMA) |
(Source: Zapier Integration V7.pdf lines 1316–1325; QnA STAGE3-018 confirmed 2026-08-10)
Step 5 — Go Live Email
Action (Zapier): Send Live_Onboarding_Credentials email (Credentials delivery) to the trader.
The email delivers platform login credentials. See SES-26 — Go Live Credentials in list_email.md for full email template spec.
Source conflict note resolved (H-12 / STAGE3-060 confirmed 2026-08-15): Zapier Integration V7.pdf line 1328 originally named this template
Live_Onboarding_Level_1. RFQ_ Website and Dashboard Implementation V7.pdf line 708 describedLive_Onboarding_Level_1as a compliance onboarding pack link email (matching UC_5.3 context). Client has confirmed the credential delivery email at Flow 3H is renamed toLive_Onboarding_Credentials. (Source: STAGE3-060 / H-12 confirmed 2026-08-15)
(Source: Zapier Integration V7.pdf line 1328; STAGE3-060 / H-12 confirmed 2026-08-15)
Step 6 — Pod Invite (Flow 10 Trigger)
Action (Zapier): Trigger Flow 10 (Pod Mentorship Onboarding).
Flow 10 is out of scope for this UC. (Source: Zapier Integration V7.pdf lines 1330–1331)
Step 7 — SIM Account Decommissioning Protocol (Async — Middleware)
Trigger: Middleware Hub receives the Go-Live Success signal from Flow 3H. This step runs asynchronously and independently of Step 6 — it does NOT block the Go-Live email or Flow 10 trigger.
Purpose: Eliminate ongoing platform seat fees ($25.00/month) and Non-Pro market data fees (up to $54.00/month) from the trader's now-inactive SIM account on Rithmic Paper Gateway.
Mandatory sequence — all 3 sub-steps MUST execute in order:
Sub-step 7.1 — Data Sync & Archive (MUST complete before Sub-step 7.3)
- Middleware calls Rithmic Paper Gateway API to export: full trade log history, performance metrics snapshots, final P&L snapshot.
- Data written to PostgreSQL (permanent record, queryable for "Historical Performance" tab).
- Compressed copy (JSON/CSV) pushed to S3 Glacier (cold storage — long-term audit archive). S3 push timeout: 5 seconds (S3 Standard bucket with fast API response; Glacier transition handled by S3 Lifecycle policy, not middleware). If S3 unreachable after 5s → immediately enqueue ERR-DECOM-01 retry (no additional wait at push step). (Q18, confirmed 2026-08-25)
- Sub-step 7.3 (Unassign) is blocked until Middleware receives
Sync_Successconfirmation from both PostgreSQL write and S3 Glacier push. If either fails → ERR-DECOM-01 (see §7 Exc-8).
Sub-step 7.2 — Terminate SIM Market Data Subscription
- Middleware sends unsubscribe request for Non-Pro CME data packages on Paper Gateway for this trader's
user_id. - Same-month cache rule (client-confirmed): Non-Pro data rights already paid for the current calendar month remain valid through the end of that month (Rithmic monthly billing cycle — no pro-rata refund). Middleware MUST cache this state:
sim_data_valid_until = last_day_of_current_calendar_month. Schema:sim_data_valid_until DATE(not TIMESTAMP) on Users table — billing is calendar-month-bound, sub-day precision not needed. (Q16, confirmed 2026-08-25) - On CASE-REBUY-01 reuse (trader re-buys SIM challenge in same month):
sim_data_valid_untilis NOT cleared — existing value remains intact (intra-month entitlement preserved). It is overwritten only when a new full Non-Pro CME subscription starts at the beginning of a new billing month. - This cached entitlement is used for CASE-REBUY-01 (see §6 Alt-6) — if the trader re-buys a SIM challenge in the same calendar month, the existing Non-Pro data rights are reused with no additional data charge.
- If unsubscribe API call fails → ERR-DECOM-02 (see §7 Exc-9).
Sub-step 7.3 — Unassign SIM Sub-Account (requires Sync_Success from 7.1)
- Middleware executes
Unassigncommand on Rithmic Paper Gateway for the trader's SIM sub-account. - This severs the physical link between the SIM sub-account and the trader's
user_id, freeing the active user slot on the paper gateway server. - Eliminates the $25.00/month platform seat fee from the next Rithmic billing cycle.
(Source: client confirmed 2026-08-24)
6. Alternative Flows
Alt-1 — Forex path (setup_status = 'N/A'):
Forex traders always receive setup_status = 'N/A' from Flow 3F (no market data payment required). Flow 3H fires as soon as both gate conditions are met. Steps 1–6 execute identically except: gateway routes to MT5/TraderEvolution Forex Omnibus (not Rithmic); Step 2.3 (Professional Status) is skipped; metric_value uses "Live Account Funded (Level Target Notional)".
Alt-2 — Futures Standard Market Data (market_data_billable = False):
Triggered when setup_status = 'N/A' set by Flow 3F (Option A — no premium add-ons). Step 2.4 provisions Standard Data (Firm Covered) as Professional via Rithmic. Add-on feeds (NYMEX/CBOT/COMEX) are NOT provisioned. Trader may upgrade later via Dashboard "Manage Add-ons" (UC_5.7 scope).
Q14 (confirmed 2026-08-25): Flow 3H is a one-time provisioning event. For post-live feed upgrades (adding NYMEX/CBOT/COMEX after
Active_L[N]_DMA), Flow 3H does NOT re-run. All subsequent feed additions/removals go through UC_5.7POST /toggle-market-data, which activates/deactivates feeds on Rithmic directly.
Alt-3 — Futures Professional Market Data (market_data_billable = True):
Triggered when setup_status = 'Complete' set by Flow 3G (Option B — premium add-ons confirmed and paid). Step 2.4 provisions Professional Market Data + selected add-ons (NYMEX/CBOT/COMEX) via Rithmic.
Alt-4 — contract_status fires last:
If setup_status was already 'Complete' or 'N/A' when Flow 3E sets contract_status = 'Signed', Flow 3E's aggregation check triggers Flow 3H immediately. No difference in Flow 3H logic.
Alt-5 — Level 2 or Level 5 entry:
Level_Starting_Capital, Max_Contracts_ES_Equiv, and Assets_Permitted are sourced from the corresponding Table A/B row. Level 2: $2,500 Futures / $1,500 Forex. Level 5: $11,250 Futures / $15,000 Forex. All other Flow 3H steps are identical.
Alt-6 — CASE-REBUY-01: Trader rebuys SIM challenge in same calendar month as decommissioning: Triggered when a trader fails their live account and purchases a new SIM challenge during the same calendar month that their previous SIM account was decommissioned via Step 7.
- Middleware checks
sim_data_valid_untilfor the trader'suser_id. - If
TODAY <= sim_data_valid_until(i.e., the cached Non-Pro data entitlement is still valid for the current billing cycle): the new SIM challenge account reuses the existing Non-Pro CME data rights — no new data subscription is created, no duplicate charge for the current billing month. - If
TODAY > sim_data_valid_until(new calendar month): standard new subscription is initiated. sim_data_valid_untilis NOT cleared on re-buy — the value set during decommissioning Sub-step 7.2 persists intact. It is overwritten only when a new full Non-Pro CME subscription starts at the beginning of a new billing month. (Q16, confirmed 2026-08-25)- Rationale: Rithmic bills Non-Pro data monthly with no pro-rata refunds. Rights already paid for the current month are valid through month-end regardless of account decommissioning. (Source: client confirmed 2026-08-24)
7. Exceptional Flows
Exc-1 — POST /provisioning/live-trader returns non-200:
account_status remains at pre-Flow-3H state (contract_status = 'Signed', setup_status IN ('Complete', 'N/A')). platform_username / credentials NOT written to DB. Email NOT sent.
Retry behavior (confirmed — H-13 / STAGE3-061 2026-08-15): Middleware Hub auto-retries POST /provisioning/live-trader up to 3× with Exponential Backoff before escalating. If all 3 retries fail: SEV1 Slack alert fires to Ops + Break-Glass Runbook: Manual Account Provisioning activated. Manual provisioning via Ops Console (RBAC + audit log).
(Source: STAGE3-061 / H-13 confirmed 2026-08-15)
🔄 CR — STAGE3-024 [CHR-45]: Rithmic retry behavior confirmed — weekday: hourly batch. Weekend (Fri 4pm CT – Sun 4pm CT): batch + retry at Sunday 3:45pm CT. CloudWatch Sev-1 Slack alert. Break-Glass Runbook.
Exc-2 — Rithmic API fails to provision sub-account (Futures Step 2.1/2.2): Sub-account not created at Rithmic/Ironbeam FCM level. Virtual ledger NOT initialised. Credentials NOT returned. Flow 3H halts at Step 2. Retry behavior (confirmed — STAGE3-024 [CHR-45] 2026-08-11): Rithmic has known maintenance windows: brief weekday windows and a weekend window from Friday 4pm CT to Sunday 4pm CT (logins and potentially account creation both down).
- Weekday failure: Batch and retry hourly until provisioning completes.
- Weekend failure (Fri 4pm CT – Sun 4pm CT): Batch failed request and schedule a single retry run at Sunday 3:45pm CT — timed to complete before the Sunday 4pm CT maintenance end window. CloudWatch Sev-1 Slack #risk-ops alert applies. Escalation (confirmed — STAGE3-021): If retry batching does not resolve the issue, activate Break-Glass Runbook: Manual Account Provisioning / Promotion. Ops manually provisions the account via Ops Console (internal endpoint with RBAC authorization + audit logging). (Source: QnA STAGE3-021; STAGE3-024 [CHR-45] confirmed 2026-08-11)
🔄 CR — STAGE3-024 [CHR-45]: MT5/TraderEvolution retry behavior confirmed — exponential backoff 1m→3m→5m→15m→30m→1h→hourly. Break-Glass Runbook as final escalation.
Exc-3 — MT5/TraderEvolution API fails to create sub-account (Forex Step 2.1/2.2):
ST_LIVE_[user_id] not created. Forex-specific retry behavior — both platforms are intended to run 24/7 with no scheduled downtime windows.
Retry behavior (confirmed — STAGE3-024 [CHR-45] 2026-08-11): On any API failure, apply exponential backoff retry: 1 min → 3 min → 5 min → 15 min → 30 min → 1 hour → continue every 1 hour until resolved. Notify support team on first failure; ensure logging captures sufficient detail to diagnose root cause.
Escalation (confirmed — STAGE3-021): If retry batching does not resolve, Break-Glass Runbook applies identically to Exc-2 — Ops manually provisions via Ops Console after connectivity is restored.
(Source: QnA STAGE3-021; STAGE3-024 [CHR-45] confirmed 2026-08-11)
Exc-4 — Ledger INSERT fails (Step 2.5):
Trading account exists at platform level (Rithmic sub-account or MT5/TraderEvolution sub-account created and funded) but ledgers table INSERT into PostgreSQL fails. virtual_equity and allocated_capital NOT initialised. System is in distributed transaction failure state: exchange holds a live, funded account with no corresponding System of Record entry — capital leakage and billing phantom risk.
Middleware MUST evaluate asset_class and execute the appropriate compensation transaction immediately (Try-Catch in Node.js):
Path A — Futures (Rithmic / Ironbeam FCM): Rithmic Live FCM Gateway does NOT permit physical deletion of sub-accounts. User IDs must persist permanently for regulatory reporting and exchange audit. Hard Delete is impossible.
Mandatory compensation sequence:
- Suspend Trading: Call Rithmic API to set account state to
Admin Only/ Suspend Trading — immediately freezes order entry, cancels all working orders, closes any open positions. Prevents any capital movement on the phantom account. - Unassign sub-account: Execute
Unassigncommand on Rithmic Live FCM Gateway to detach the sub-account from the trader's User ID. Sub-account returns toIronbeam_Account_Poolfor reuse. Stops $25/month platform seat fee. - SEV-1 incident: Fire AWS CloudWatch Alarm → Slack
#risk-opsalert: "Futures Provisioning Rollback — Ledger INSERT failed, sub-account unassigned. Manual verification required forfcm_subaccount_id = [id]". - Retry / frontend feedback: Middleware returns error response to caller. Frontend displays "Retry" button or Flow 3H is placed in retry queue for re-provisioning from scratch (new sub-account draw from pool on next attempt).
Path B — Forex (MT5 / TraderEvolution): MT5 and TraderEvolution run on bare-metal servers with flat monthly server cost (no per-sub-account fee — BR_5.8.22). Physical Hard Delete is supported and is the correct cleanup action to prevent server bloat.
Mandatory compensation sequence:
- Hard Delete sub-account: Call MT5 Manager API (
DELETE /account/{account_id}) or TraderEvolution Admin API equivalent to permanently purge the sub-account from the NY4 server. Sub-account was just created — no trade history exists, so Sync Verification (Exc-11) is NOT required before deletion. - Revoke YourBourse Bridge config (if applicable): If YourBourse Bridge routing configuration was applied during Step 2.2, call YourBourse Bridge API to revoke symbol routing assignments and position limit configs for the deleted sub-account.
- SEV-1 incident: Fire AWS CloudWatch Alarm → Slack
#risk-opsalert: "Forex Provisioning Rollback — Ledger INSERT failed, sub-account hard deleted. Manual verification required foruser_id = [id]". - Retry / frontend feedback: Middleware returns error response to caller. Frontend displays "Retry" button or Flow 3H is placed in retry queue for re-provisioning from scratch.
(Source: CR-20260824-003 — asset-class compensation transaction branch, client confirmed 2026-08-24; Rithmic audit constraint: RFQ_ Stack Trading Prop Tech V7.pdf lines 258–260; MT5/TE flat server cost: BR_5.8.22 / CR-20260824-002)
Exc-5 — POST /api/ledger/record fails (Step 3):
Immutable on-chain log (Polygon PoS via Alchemy RPC) not written. Platform account is live; credentials are ready for write-back at Step 4.
Confirmed behavior (H-15 / STAGE3-063 2026-08-15): POST /api/ledger/record is asynchronous — the endpoint responds HTTP 200 immediately and queues the blockchain write job on BullMQ / Redis. A BullMQ worker processes the job and retries hourly until the Tx Hash is written. SLA: Tx Hash must be written within 24 hours of the initial call. If Tx Hash is still missing after 24 hours, a #devops Slack alert fires for manual investigation. Step 3 failure NEVER blocks Steps 4–6 (credentials delivery and email) — the async architecture guarantees fire-and-continue semantics by design.
(Source: STAGE3-063 / H-15 confirmed 2026-08-15)
Exc-6 — Credentials DB write fails (Step 4):
platform_username, platform_password_ciphertext, license_key_ciphertext, cipher_version NOT written. is_professional NOT written (Flow 3H write-point). account_status NOT updated to Active_L[N]_DMA. Trader cannot access credentials via Dashboard Connections & Credentials tab despite platform account being live at exchange level.
Escalation (confirmed): No automated recovery path defined in source. Recovery depends on System Admin manual intervention via Ops Console.
(Source: QnA STAGE3-021)
Exc-7 — Flow 3H double-trigger (idempotency):
Race condition between Flow 3E and Flow 3F/3G gate checks could fire Flow 3H twice for the same user_id, risking duplicate platform sub-account creation.
Confirmed gate check required: Per Global Webhook Security Directive and Production Readiness Checklist, idempotency guards are mandatory. Consistent with Flow 1 precedent (IF Status IN ('Active_Challenge', 'Active_DMA', 'Guest'): REJECT). Zapier MUST check:
- IF
account_statusis alreadyActive_L[N]_DMA→ HALT - IF
platform_usernameis already populated → HALT
Both conditions indicate Flow 3H has already executed successfully. See BR_5.8.15. (Source: QnA STAGE3-021; Global Webhook Security Directive; Production Readiness Checklist)
Exc-8 — ERR-DECOM-01: Data Sync / Archive failure (Step 7.1):
One or both targets (PostgreSQL write OR S3 Glacier push) fail to return Sync_Success confirmation.
- Middleware enters retry queue for the failed target(s). Queue specs (confirmed Q17 — 2026-08-25): Redis Queue (shared BullMQ stack). 5 retries with exponential backoff + jitter: 30s → 5m → 30m → 2h → 6h. Exhaustion window: 24h — on exhaustion, Slack SEV-1 alert to
#risk-ops+ Freshdesk L2 ticket for manual review. Partial retry via Saga Pattern: if PostgreSQL succeeded but S3 failed → retry S3 step only (no re-write to DB — state tracked per sub-step to avoid duplicate DB writes). - Sub-step 7.3 (Rithmic Paper Gateway
Unassign) is blocked untilSync_Successis confirmed from BOTH PostgreSQL AND S3 Glacier. - Sub-step 7.2 (market data unsubscribe) is NOT blocked and may proceed independently.
- If retry queue exhausts (max 5 retries): Middleware raises a Slack
#risk-opsSEV-1 alert + Freshdesk L2 ticket for Ops manual intervention to complete the archive before Unassign is permitted. - Rationale: Running
Unassignbefore archiving would permanently delete trade history from Rithmic Paper Gateway — an irreversible data loss. Archive completeness is a hard prerequisite. (Source: client confirmed Q17 2026-08-25)
Exc-9 — ERR-DECOM-02: Unassign succeeded but SIM market data cancel API fails (Step 7.2):
Rithmic Paper Gateway Unassign in Sub-step 7.3 executes successfully (seat fee eliminated), but the Non-Pro CME market data unsubscribe API call in Sub-step 7.2 fails (connection error, timeout, or Rithmic API rejection).
- Middleware applies a local lock on the trader's
user_id: recordssim_data_cancel_pending = trueto prevent billing leakage tracking gaps. Schema:sim_data_cancel_pending BOOLEAN NOT NULL DEFAULT FALSEon Users table — set toTRUEwhen cancel is pending; reset toFALSEafter cancellation is processed. (Q15, confirmed 2026-08-25) - Middleware sends a Slack alert to
#risk-opswith the trader'suser_idand failure reason. - Ops must manually cancel the data subscription via the Rithmic admin portal.
- The local
sim_data_valid_untilcache remains valid (set from the initial unsubscribe attempt timestamp) — CASE-REBUY-01 (Alt-6) continues to function correctly during the Ops resolution window. (Source: client confirmed 2026-08-24; Q15 schema confirmed 2026-08-25)
Exc-10 — LIVE Account Termination: Asset-Class Conditional Branch (CR-20260824-002):
When a LIVE trader account is terminated (Reset, Rebuy, Failsafe expiry, or POST /system/set-account-state state="Terminated"), Middleware MUST check asset_class before executing the account cleanup path:
IF asset_class == 'Futures':
→ Execute Rithmic Unassign Flow (see Exc-2 retry behavior for provisioning; Unassign = inverse)
ELSE IF asset_class IN ('Forex_MT5', 'Forex_TE'):
→ Execute MT5/TE Hard Delete Flow (see Exc-11/Exc-12)Rithmic Unassign (Futures):
- Rithmic DB does not permit physical deletion of sub-accounts. Keep Rithmic User ID intact (all entitlements, invoice history, CME subscriber agreements preserved).
- Unassign the failed sub-account from the User ID (stops $25/month platform seat fee).
- Failed sub-account remains in Rithmic DB but detached from the trader.
- On next Pass SIM: a new sub-account is drawn from
Ironbeam_Account_Pooland assigned to the existing User ID.
MT5/TE Hard Delete (Forex):
- Bare-metal server — terminated sub-accounts must be deleted to prevent server bloat. Hard Delete is recommended and incurs no additional cost (flat server fee, no per-user variable fee per BR_5.8.22).
- Mandatory 3-step sequence: see Exc-11 and Exc-12 for failure handling.
(Source: CR-20260824-002 client confirmed 2026-08-24)
Exc-11 — MT5/TE Hard Delete: Sync Verification Failure (Step 1 of 3): Middleware initiates LIVE account termination for a Forex trader. Before Hard Delete can proceed, Middleware MUST verify:
- ✅ PostgreSQL:
trade_history+pnl_snapshotstables contain all records formt5_account_id/te_account_id. - ✅ AWS S3 Glacier: corresponding object key exists in the audit bucket (Object Lock, immutable cold storage).
If either check fails (sync not complete):
- Hard Delete (Step 3) is BLOCKED — do NOT delete the sub-account.
- Middleware enters retry queue with exponential backoff (same mechanism as BullMQ/Redis used for async jobs).
- SEV-1 Slack alert to
#risk-ops: "Forex Hard Delete Blocked — Sync Verification Failed formt5_account_id = [id]". - Ops must confirm sync completion before clearing the block.
- Sub-account remains active on server until sync is confirmed. No data loss risk.
(Source: CR-20260824-002 client confirmed 2026-08-24)
Exc-12 — MT5/TE Hard Delete: Full 3-Step Sequence (Happy Path + Rollback): Once Sync Verification (Step 1) succeeds (both PostgreSQL and S3 Glacier ✅):
Step 1 — Sync Verification: ✅ (confirmed, see Exc-11 for failure path)
Step 2 — Provision new sub-account:
- Call MT5 Manager API or TraderEvolution Admin API to create a new sub-account.
- Map new sub-account ID to
user_idin PostgreSQL (mt5_account_id/te_account_idupdated). - New sub-account is ready but NOT yet active for trading (Flow 3H provisioning chain must complete).
- Step 2 is independent of Step 3 — if Step 3 fails, the new sub-account remains operational (trader has no downtime).
Step 3 — Hard Delete old sub-account:
- Executes ONLY after Step 1 ✅.
- Call MT5 Manager API (
DELETE /account/{account_id}) or TraderEvolution Admin API equivalent. - Old sub-account permanently deleted from physical server.
- Write audit log:
deleted_account_id,deleted_at,sync_verified_at,s3_key,operator = 'system'.
Rollback if Step 3 fails:
- Old sub-account still exists — no data loss.
- SEV-1 Slack alert to
#risk-ops: "Hard Delete Failed — manual cleanup required formt5_account_id = [id]". - Trader uses new sub-account (Step 2 already succeeded) — no trader-facing impact.
(Source: CR-20260824-002 client confirmed 2026-08-24)
8. Business Rules
| Rule ID | Description | Source |
|---|---|---|
| BR_5.8.1 | Flow 3H fires only when BOTH contract_status = 'Signed' AND setup_status IN ('Complete', 'N/A') are simultaneously true. The gate is checked by both Flow 3F/3G (on setup completion) and Flow 3E (on contract signing). | Zapier Integration V7.pdf lines 1224, 1238, 1261 |
| BR_5.8.2 | Entry levels for live phase are Level 1, 2, or 5 only. Level_Starting_Capital sourced from Table A (Forex) or Table B (Futures) for Current_Level. Validation gate (confirmed Q11 — 2026-08-25): Middleware MUST validate Current_Level IN (1, 2, 5) before executing POST /provisioning/live-trader. If Current_Level is any other value → reject with HTTP 400 Bad Request immediately. Any value outside {1, 2, 5} indicates a data integrity error or malicious input — must NOT proceed with wrong capital allocation. | Zapier Integration V7.pdf lines 1269–1290; Q11 confirmed 2026-08-25 |
🔄 CR — STAGE3-037 [CHR-46] ([CHR-46]):
fcm_subaccount_idsource changed from Ironbeam inbound JSON payload (Flow 3B.2) to pre-provisioned bulk pool (Ironbeam_Account_Pooltable). Flow 3B.2 / UC_5.3 deprecated. Outbound PII bundle handoff added to UC_5.2 BR_5.2.10.
| BR_5.8.3 | Futures: fcm_subaccount_id is assigned from a pre-provisioned bulk pool managed by Ironbeam (not created dynamically at runtime). Ironbeam proactively replenishes this pool to stay ahead of trader velocity — SotaTek does not trigger pool expansion. Node.js Middleware automatically draws an unused sub-account from this pool and assigns it to the trader at Veriff APPROVED. SotaTek must build local DB tracking — a dedicated table (e.g. Ironbeam_Account_Pool) recording which sub-accounts have been assigned and which remain available. Assignment logic MUST use a transaction lock to prevent race conditions from assigning the same sub-account to two traders simultaneously. Ironbeam notifies the total number of newly created sub-accounts when new accounts are provisioned; the recommended approach is local tracking per Ironbeam (2026-08-13). Querying unassigned accounts directly on Rithmic is also theoretically possible — Ironbeam is investigating this further and will follow up. fcm_subaccount_id is then passed in the Flow 3H payload for Rithmic provisioning and assigned to the predefined Risk Group Template (risk_group = "Live_W2"). Note: "Live_W2" is a Rithmic Risk Group Template name — a platform-level config label, NOT an indicator of W-2 employment status. Independent Contractor status applies at Levels 1–5; W-2 only at Level 6+. (QnA STAGE3-009 confirmed 2026-08-09; Ironbeam clarification 2026-08-13) | RFQ_ Stack Trading Prop Tech V7.pdf lines 1115–1127; QnA STAGE3-009; Ironbeam clarification 2026-08-13 |
| BR_5.8.4 | Forex: Sub Account ID format is ST_LIVE_[user_id]. Assigned to TraderEvolution Group or MT5 Group. Symbol permissions, position limits, and auto liquidate parameters established at creation. | RFQ_ Stack Trading Prop Tech V7.pdf lines 1128–1140 |
| BR_5.8.5 | Futures only: CME Subscriber Status hardcoded to 'Professional' for ALL Rithmic Live accounts. 100% of live Futures traders are classified Professional with no opt-out. is_professional field lifecycle: (1) First written to DB by Flow 3E (contract signing) as a contract execution gate; (2) Middleware enforces Professional classification internally during POST /provisioning/live-trader (Step 2.3) and returns is_professional: true in the response payload; (3) Zapier writes it again to DB at Flow 3H Step 4 (DB write-back). Zapier does NOT pass is_professional as an input parameter — it is Middleware-owned. (QnA STAGE3-018, confirmed 2026-08-10) | RFQ_ Stack Trading Prop Tech V7.pdf lines 1141–1146; QnA STAGE3-018 |
| BR_5.8.6 | Market data: IF market_data_billable = True → Professional Market Data + add-ons (NYMEX/CBOT/COMEX) via Rithmic. IF market_data_billable = False → Standard Data (Firm Covered) as Professional. Futures only. | Zapier Integration V7.pdf lines 1282–1285 |
| BR_5.8.7 | Virtual ledger INSERT at Flow 3H: user_id = payload.user_id, level_id = Current_Level, virtual_equity = Level_Starting_Capital, allocated_capital = Level_Starting_Capital, mapped_account_id = [FCM sub-account ID or Forex Omnibus ID], is_active = true, last_sync = NOW(). The ledgers table is the System of Record for all live trader financial state; last_sync is updated on every subsequent P&L pull from the execution core (Flow 27/28 scope). | RFQ_ Stack Trading Prop Tech V7.pdf lines 1158–1165; V7 ledger spec 2026-08-13 |
| BR_5.8.8 | Immutable ledger: metric_category = "Associate Track Passed". Futures metric_value = "Live Account Funded (Level Target Notional Equivalent)". Forex metric_value = "Live Account Funded (Level Target Notional)". | Zapier Integration V7.pdf lines 1308–1314 |
| BR_5.8.9 | account_status format: 'Active_L' + Current_Level + '_DMA'. Valid at live entry: Active_L1_DMA, Active_L2_DMA, Active_L5_DMA. | Zapier Integration V7.pdf line 1325 |
| BR_5.8.10 | credentials_claimed_at is set to NULL at provisioning. Tracks when trader first claims credentials. | Zapier Integration V7.pdf line 1324 |
| BR_5.8.11 | Platform Entitlement: NinjaTrader 8 Enterprise Prop API call superseded by TradeSea equivalent per CR-20260720-001. Exact TradeSea API not yet documented in source. | CR-20260720-001 CR_summary.md; original: RFQ_ Stack Trading Prop Tech V7.pdf lines 1147–1157 |
| BR_5.8.12 | Live_Onboarding_Credentials email sent only after credentials are written to DB (Step 4 must succeed before Step 5). Template name confirmed: Live_Onboarding_Credentials (renamed from Live_Onboarding_Level_1 per H-12/STAGE3-060). | STAGE3-060 / H-12 confirmed 2026-08-15; Zapier Integration V7.pdf line 1328 — implied sequencing |
| BR_5.8.13 | Forex capital formula: Level_Starting_Capital = Max_Forex_Notional / 50. Level 1: $500. Level 2: $1,500. Level 5: $15,000. | Zapier Integration V7.pdf line 1370 |
| BR_5.8.15 | Idempotency gate (Exc-7): Zapier MUST check before executing Flow 3H: (1) IF account_status is already Active_L[N]_DMA → HALT; (2) IF platform_username IS NOT NULL → HALT. Either condition indicates Flow 3H has already completed for this user_id. Consistent with Flow 1 precedent: IF Status IN ('Active_Challenge', 'Active_DMA', 'Guest'): REJECT. Mandated by Global Webhook Security Directive and Production Readiness Checklist. (QnA STAGE3-021, confirmed 2026-08-10) | QnA STAGE3-021; Global Webhook Security Directive; Production Readiness Checklist |
| BR_5.8.16 | SIM Decommissioning sequence is mandatory and ordered. Sub-step 7.3 (Rithmic Paper Gateway Unassign) MUST NOT execute until Sync_Success is confirmed from both PostgreSQL write AND S3 Glacier push in Sub-step 7.1. Running Unassign before archiving would permanently destroy Rithmic Paper Gateway trade history — irreversible data loss. | client confirmed 2026-08-24 |
| BR_5.8.17 | Non-Pro market data same-month cache rule. When Middleware unsubscribes Non-Pro CME data in Sub-step 7.2, it MUST record sim_data_valid_until = last_day_of_current_calendar_month on the trader's record. Non-Pro data rights already paid for the current Rithmic billing month remain valid through month-end regardless of decommissioning (no pro-rata refund from Rithmic). This cached entitlement enables CASE-REBUY-01. | client confirmed 2026-08-24 |
| BR_5.8.18 | CASE-REBUY-01 — Rebuy same-month data reuse. If a trader rebuys a SIM challenge within the same calendar month that their SIM account was decommissioned, Middleware MUST check sim_data_valid_until. If TODAY <= sim_data_valid_until, the new SIM account reuses existing Non-Pro CME data rights — no new data subscription is created and no additional data charge is applied for the current billing month. | client confirmed 2026-08-24 |
| BR_5.8.19 | Dashboard Clean Slate after Go-Live. Upon account_status = Active_L[N]_DMA, the main Dashboard view MUST reset to a fresh DMA-account state: SIM performance metrics, challenge P&L widgets, and challenge-phase progress indicators are cleared from the primary view. The main dashboard renders only Live account data. | client confirmed 2026-08-24 |
| BR_5.8.20 | Historical Performance tab — read-only SIM archive access. Archived SIM challenge trade history (stored in PostgreSQL by Sub-step 7.1) MUST be accessible to the trader via a "Historical Performance" or "Archived Challenge Accounts" tab on the Dashboard. This data is read-only — traders may view past challenge records but cannot modify or interact with the SIM account. | client confirmed 2026-08-24 |
| BR_5.8.21 | Asset-class conditional branch at LIVE account termination (CR-20260824-002). Every termination endpoint (POST /system/set-account-state state="Terminated", Flow 7 Post-Termination, Reset/Rebuy flows) MUST evaluate asset_class before executing account cleanup: IF asset_class == 'Futures' → Rithmic Unassign flow; ELSE IF asset_class IN ('Forex_MT5', 'Forex_TE') → MT5/TE Hard Delete 3-step flow. No cross-path execution allowed. | CR-20260824-002 client confirmed 2026-08-24 |
| BR_5.8.22 | Forex flat server cost — no double-billing risk on Hard Delete (CR-20260824-002). Stack Trading pays a flat monthly server cost for MT5 and TraderEvolution white-label platforms — no per-user variable fee, no per-sub-account charge. Creating, deleting, or re-provisioning a Forex sub-account within a month generates no incremental billing. Hard Delete is the recommended cleanup approach. The Intra-Month Delta Reconciliation protocol (CR-20260824-001, UC_5.6 BR_5.6.12) is Futures-only — it does NOT apply to Forex. | CR-20260824-002 client confirmed 2026-08-24 |
| BR_5.8.23 | MT5/TE Hard Delete mandatory 3-step sequence (CR-20260824-002). For Forex LIVE account termination: (1) Sync Verification — confirm trade_history + pnl_snapshots written to PostgreSQL AND object key exists in AWS S3 Glacier audit bucket; Step 3 is blocked until both checks ✅. (2) Provision new sub-account on MT5/TE, map to user_id in PostgreSQL. (3) Hard Delete old sub-account via MT5 Manager API / TraderEvolution Admin API — only after Step 1 ✅. Rollback if Step 3 fails: old sub-account intact (no data loss); alert Ops Slack SEV-1. Steps 1–3 are strictly sequential. | CR-20260824-002 client confirmed 2026-08-24 |
🔄 CR — STAGE3-019 + STAGE3-035: CMR banner trigger condition confirmed (
account_status == Active_L[X]_DMA AND rithmic_status.CME == false). Endpoint confirmed as GET /bps/trader/market-data-status. Banner update: "Refresh Status" button (Option 1, priority) + 60s slow-poll (Option 2).
BR_5.8.14: CMR Agreement Signing — Post-Provisioning Activation Step (Futures Only)
CMR (Customer/Exchange) Agreement signing occurs after Flow 3H provisioning completes. It is not a pre-condition for this flow. UC_5.8 owns the Rithmic feed-lock state machine — the banner logic is scoped here, not in a separate Dashboard UC. (QnA STAGE3-019, confirmed 2026-08-10)
Sequence (confirmed — QnA STAGE3-017, 2026-08-10):
| Step | Actor | Action |
|---|---|---|
| 1 | Flow 3H | Provisions Rithmic sub-account, generates platform_username + platform_password, sends Live_Onboarding_Credentials credentials email |
| 2 | Rithmic | Automatically places live market data feeds in Disabled/Locked state upon account creation |
| 3 | Trader | Downloads R |
| 4 | Rithmic (native) | Intercepts first login session; forces trader to digitally sign CMR agreements for all subscribed exchanges (CME, COMEX, CBOT, NYMEX) |
| 5 | Rithmic (native) | Immediately unlocks live market data feeds upon successful agreement signing |
Rationale: Traders cannot sign CMR agreements without active platform credentials — they must log into R|Trader Pro to sign, and R|Trader Pro requires platform_username + platform_password that only exist after provisioning.
Feed-lock status check — GET /bps/trader/market-data-status:
Middleware Hub provides this endpoint to query Rithmic's active signature status directly for all subscribed exchanges (CME, CBOT, NYMEX, COMEX). (Source: RFQ_ Stack Trading Prop Tech V7.pdf)
Response structure:
{
"rithmic_status": {
"CME": false,
"CBOT": false,
"NYMEX": false,
"COMEX": false
}
}false = exchange agreement not yet signed (feeds locked). true = signed and feeds active.
Dashboard banner trigger condition:
IF account_status == 'Active_L[X]_DMA' AND rithmic_status.CME == falseIndicates: account successfully provisioned but trader has not yet completed CMR agreement signing on R|Trader Pro. (Source: Zapier Integration V7.pdf)
During the lock period:
- Dashboard displays a warning alert banner: "Action Required: Your live market data feeds are currently paused. You must log into R|Trader Pro and digitally sign your exchange agreements to enable your data." (per CR-20260727-005 + QnA STAGE3-008)
- Banner remains visible until
GET /bps/trader/market-data-statusreturns all subscribed exchange values astrue. - Stack Trading web platform does NOT track the CMR signing event in real time — Rithmic handles it natively at the gateway level.
Banner update UX — how the frontend clears the banner (confirmed — QnA STAGE3-035, 2026-08-12):
Rithmic does NOT support real-time webhooks for CMR agreement signing events. The backend must actively poll GET /bps/trader/market-data-status to retrieve signature status — no broker-driven push is available. The frontend is responsible for triggering the status check.
To prevent excessive API load, high-frequency polling is explicitly prohibited. Two permitted patterns:
| Option | Mechanism | Priority |
|---|---|---|
| Option 1 — Manual action (priority) | Add a "Refresh Status" or "I have signed" button to the banner. When clicked, frontend calls GET /bps/trader/market-data-status immediately. If all subscribed exchange statuses return true, banner is removed. | Primary — best UX |
| Option 2 — Slow poll (secondary) | While the banner is visible, frontend polls GET /bps/trader/market-data-status at a 60-second interval. Polling stops as soon as banner is dismissed (all exchanges true) or the page is unloaded. | Only if auto-removal is required; must not run when banner is not visible |
Both options are cumulative — Option 1 button can coexist with Option 2 background poll. Option 1 is the minimum required implementation.
(Source: QnA STAGE3-035 confirmed 2026-08-12; QnA STAGE3-004 + STAGE3-017 + STAGE3-019 confirmed 2026-08-10; CR-20260727-005 Dashboard Data-Feed Lock Banner; RFQ_ Stack Trading Prop Tech V7.pdf; Zapier Integration V7.pdf)
9. Non-Functional Requirements
| NFR | Requirement |
|---|---|
| Security | Platform credentials stored encrypted (platform_password_ciphertext, license_key_ciphertext) with cipher_version tracking. credentials_claimed_at enables credential access audit. |
| Idempotency | Flow 3H must not double-provision a trader on the same user_id. Gate check: Zapier MUST verify account_status != Active_L[N]_DMA AND platform_username IS NULL before executing. See BR_5.8.15. (QnA STAGE3-021, confirmed 2026-08-10) |
| Atomicity | Sub-account creation, capital injection, and ledger init are internal steps of a single Middleware call. Exc-2/3 (platform API failure): Break-Glass Runbook — manual provisioning via Ops Console after connectivity restored. No automated rollback. Exc-4 (Ledger INSERT fail): Middleware MUST evaluate asset_class and execute asset-class compensation transaction — Futures (Rithmic): Suspend Trading → Unassign (physical delete prohibited for regulatory audit); Forex (MT5/TE): Hard Delete API → revoke YourBourse Bridge config (no Sync Verification required — account just created). Both paths: SEV-1 CloudWatch → Slack #risk-ops. Re-provisioning from scratch is the recovery path. (CR-20260824-003, supersedes H-14/STAGE3-062 DeleteUser). Exc-5 (POST /api/ledger/record failure): async by design — BullMQ/Redis queue, HTTP 200 immediate, hourly retry, 24h SLA for Tx Hash write; failure NEVER blocks Steps 4–6 (H-15/STAGE3-063). |
| Audit | POST /api/ledger/record produces immutable on-chain record. credentials_last_rotated_at tracks every credential rotation. All timestamps conform to CR-08 (UTC / ISO 8601 / millisecond precision). |
| Compliance | 100% of live Futures traders are classified CME Professional (BR_5.8.5). No opt-out. |
| Latency | POST /provisioning/live-trader MUST be implemented as async: receive → validate → write Processing status → return HTTP 202 Accepted immediately → background worker calls Rithmic/MT5/TE APIs asynchronously. This prevents Zapier's 10-second hard timeout from firing during platform provisioning. No fixed p95 SLA defined in spec — background worker completes provisioning and updates DB asynchronously. Zapier polls or receives callback on completion. (Q9, confirmed 2026-08-25) |
| Display | Level_Starting_Capital displayed on Dashboard conforms to CR-11 (max 2 decimal places, comma thousands separator). |
10. Screen / UI References
Connections & Credentials Tab (Dashboard — Settings & Profile Module):
- Location: Dashboard → Settings & Profile → "Connections & Credentials" tab
- Data Source:
GET /platform-credentials(authenticated) - Returns:
Platform,Login,Connection_String,Connection_Guide_URL - Middleware evaluates
platform_selectionto return platform-specific connection guide (PDF or Notion link) - Trader accesses this tab after receiving the
Live_Onboarding_Credentialsemail - Pre-provisioning state (Q10, confirmed 2026-08-25): Tab is in Disabled state (not hidden, not empty placeholder text). During
Pending_Compliancecomputed state, the Dashboard applies a frosted glass overlay + sidebar menu block across all trader-facing tabs. Once Flow 3H completes andaccount_statustransitions toActive_L[N]_DMA, the Dashboard unlocks and the tab displays live credentials via one-time Claim flow. (Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 593–594; Q10 confirmed 2026-08-25)
Market Data Management Panel:
- "Data Feed Status" badge: Green "Active" or Grey "Paused" based on
market_data_flagsstate - "Reactivate" button: enabled if
status = Inactive_Hold; callsPOST /toggle-market-datawithenable_data: true - "Manage Add-ons" button: calls
GET /market-data-products, thenPOST /execute-checkout(Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 596–632)
Dashboard Clean Slate (post Go-Live — BR_5.8.19):
- Upon
account_status = Active_L[N]_DMA, the main Dashboard view resets to a fresh DMA-account state. - SIM challenge performance metrics, challenge P&L widgets, and challenge-phase progress indicators are removed from the primary view.
- Only Live DMA account data is displayed on the main dashboard.
Historical Performance Tab / Archived Challenge Accounts (BR_5.8.20):
- Provides read-only access to archived SIM challenge trade history stored in PostgreSQL by Sub-step 7.1.
- Accessible via a dedicated tab labeled "Historical Performance" or "Archived Challenge Accounts" on the Dashboard.
- Data is read-only — traders may view past challenge records but cannot trade or interact with the decommissioned SIM account. (Source: client confirmed 2026-08-24)
[⚠️ Flow 3H is a backend-only automation. No trader-facing UI exists during provisioning itself. Figma wireframes for the Connections & Credentials tab and Go Live email are not referenced in source documents reviewed.]
11. Acceptance Criteria
| AC_ID | Criterion | Test Type |
|---|---|---|
| AC-5.8-01 | Given Futures trader with contract_status = 'Signed' and setup_status = 'Complete', when Flow 3H fires, then account_status = 'Active_L[N]_DMA' is set and credentials are populated in Users table | Integration |
| AC-5.8-02 | Given Forex trader with contract_status = 'Signed' and setup_status = 'N/A', when Flow 3H fires, then Sub Account ST_LIVE_[user_id] is created in MT5/TraderEvolution with Level_Starting_Capital injected | Integration |
| AC-5.8-03 | Given any live provisioning success, then ledgers row exists with level_id = Current_Level, virtual_equity = Level_Starting_Capital, allocated_capital = Level_Starting_Capital, mapped_account_id populated, is_active = true, last_sync IS NOT NULL | Integration |
| AC-5.8-04 | Given any live provisioning, when provisioning completes, then POST /api/ledger/record is called with metric_category = "Associate Track Passed" and correct asset-class-specific metric_value | Integration |
| AC-5.8-05 | Given Futures trader with market_data_billable = True, when provisioned, then Professional Market Data + selected add-ons are active on Rithmic | Integration |
| AC-5.8-06 | Given Futures trader with market_data_billable = False, when provisioned, then only Standard Data (Firm Covered as Professional) is active — no NYMEX/CBOT/COMEX add-ons | Integration |
| AC-5.8-07 | Given Flow 3H completes, when Live_Onboarding_Credentials email is triggered, then trader receives credentials email | E2E |
| AC-5.8-08 | Given Flow 3H completes, then Flow 10 (Pod Mentorship Onboarding) is triggered | Integration |
| AC-5.8-09 | Given Level 1 Futures entry, then Level_Starting_Capital = $1,250 and Max_Contracts_ES_Equiv = 8 Micros | Integration |
| AC-5.8-10 | Given Level 1 Forex entry, then Level_Starting_Capital = $500 ($25,000 / 50) | Integration |
| AC-5.8-11 | Given Futures trader is provisioned, then CME Subscriber Status = 'Professional' at Rithmic level regardless of prior setting | Integration |
| AC-5.8-12 | Given POST /provisioning/live-trader returns non-200, then account_status is NOT updated to Active_L[N]_DMA and credentials are NOT written | Integration |
| AC-5.8-13 | Given a provisioned Futures live account where Rithmic data feeds are in locked state pending CMR agreement signatures, when the frontend queries GET /bps/trader/market-data-status, then Middleware returns "rithmic_status": { "CME": false } (and/or other affected exchanges with false) to signal the dashboard to render the compliance lock banner | Integration |
| AC-5.8-14 | Given Flow 3H is triggered twice for the same user_id (race condition), then second invocation detects account_status = Active_L[N]_DMA OR platform_username IS NOT NULL and HALTS — no re-provisioning, no duplicate sub-account, no duplicate ledger INSERT | Integration |
| AC-5.8-15 | Given Flow 3H completes successfully, then credentials_claimed_at = NULL in Users table | Integration |
| AC-5.8-16 | Given Level 2 Futures entry, then Level_Starting_Capital = $2,500 and Max_Contracts_ES_Equiv = 16 Micros | Integration |
| AC-5.8-17 | Given Level 5 Futures entry, then Level_Starting_Capital = $11,250 and Max_Contracts_ES_Equiv = 7 Minis | Integration |
| AC-5.8-18 | Given Level 2 Forex entry, then Level_Starting_Capital = $1,500 ($75,000 / 50) | Integration |
| AC-5.8-19 | Given Level 5 Forex entry, then Level_Starting_Capital = $15,000 ($750,000 / 50) | Integration |
| AC-5.8-20 | Given Flow 3H Step 4 DB write-back completes (account_status = Active_L[N]_DMA, platform_username populated), then GET /platform-credentials returns non-null Platform, Login, Connection_String, Connection_Guide_URL matching trader's platform_selection | Integration |
| AC-5.8-21 | Given feed-lock banner is visible and trader clicks "Refresh Status" / "I have signed" button, when frontend calls GET /bps/trader/market-data-status and all subscribed exchange statuses return true, then banner is dismissed immediately | UI / Integration |
| AC-5.8-22 | Given feed-lock banner is visible and Option 2 slow-poll is active, when GET /bps/trader/market-data-status returns all subscribed exchanges true on any 60-second poll tick, then banner is dismissed and polling stops | UI / Integration |
| AC-5.8-23 | Given POST /provisioning/live-trader returns non-200, when all 3 auto-retry attempts with Exponential Backoff fail, then SEV1 Slack alert fires and Break-Glass Runbook is activated; account_status remains at pre-Flow-3H state, credentials NOT written, email NOT sent | Integration |
| AC-5.8-24 | Given Ledger INSERT fails (Step 2.5) after Futures sub-account creation succeeds (Rithmic), then Middleware MUST (1) Suspend Trading on the sub-account via Rithmic API, (2) Unassign sub-account from User ID — sub-account returns to pool, (3) fire SEV-1 CloudWatch → Slack #risk-ops alert; User ID is NOT deleted (Rithmic prohibits physical deletion for regulatory audit) (Source: CR-20260824-003) | Integration |
| AC-5.8-24b | Given Ledger INSERT fails (Step 2.5) after Forex sub-account creation succeeds (MT5/TE), then Middleware MUST (1) Hard Delete the sub-account via MT5 Manager API / TraderEvolution Admin API (no Sync Verification required — account just created, no trade history), (2) revoke YourBourse Bridge config if applied, (3) fire SEV-1 CloudWatch → Slack #risk-ops alert; no phantom sub-account left on server (Source: CR-20260824-003) | Integration |
| AC-5.8-25 | Given POST /api/ledger/record is called (Step 3), then Middleware returns HTTP 200 immediately (async); BullMQ/Redis worker retries hourly until Tx Hash is written; if Tx Hash is still missing after 24 hours, #devops Slack alert fires; Steps 4–6 are NOT blocked by Step 3 failure | Integration |
| AC-5.8-26 | Given Flow 3H Go-Live success, when Step 7 SIM Decommissioning runs, then Sub-step 7.3 (Unassign) does NOT execute until Sync_Success is confirmed from BOTH PostgreSQL write AND S3 Glacier push in Sub-step 7.1 | Integration |
| AC-5.8-27 | Given Step 7.1 data sync/archive fails (ERR-DECOM-01), then Middleware enters retry queue for the failed target(s), Sub-step 7.3 remains blocked, and a Slack #risk-ops alert fires if retry queue exhausts | Integration |
| AC-5.8-28 | Given Step 7.3 Unassign succeeds but Step 7.2 market data cancel API fails (ERR-DECOM-02), then Middleware sets sim_data_cancel_pending = true, sends Slack #risk-ops alert, and sim_data_valid_until cache remains intact for CASE-REBUY-01 | Integration |
| AC-5.8-29 | Given trader rebuys a SIM challenge in the same calendar month as decommissioning (CASE-REBUY-01), when Middleware checks sim_data_valid_until and TODAY <= sim_data_valid_until, then the new SIM account reuses existing Non-Pro CME data rights with no additional data charge for the current billing month | Integration |
| AC-5.8-30 | Given account_status = Active_L[N]_DMA, then the main Dashboard view resets to a clean DMA state (SIM metrics cleared); and archived SIM challenge history is accessible read-only via "Historical Performance" / "Archived Challenge Accounts" tab | UI / Integration |
| AC-5.8-31 | Given a Futures LIVE account is terminated, then Middleware executes Rithmic Unassign (keeps User ID, unassigns sub-account from pool); and given a Forex LIVE account is terminated (asset_class IN ('Forex_MT5', 'Forex_TE')), then Middleware executes MT5/TE Hard Delete 3-step — no cross-path execution | Integration |
| AC-5.8-32 | Given Forex LIVE account termination is triggered, when Sync Verification (Step 1) is incomplete (PostgreSQL OR S3 Glacier not confirmed ✅), then Hard Delete (Step 3) is BLOCKED; SEV-1 Slack alert fires to #risk-ops; sub-account remains on server; no data deleted | Integration |
| AC-5.8-33 | Given Forex LIVE account termination — Sync Verification ✅ — when Step 2 (provision new sub-account) completes and Step 3 (Hard Delete old sub-account) fails, then old sub-account still exists; SEV-1 Slack alert fires; trader's new sub-account (Step 2) is operational — no trader-facing downtime | Integration |
| AC-5.8-34 | Given Forex LIVE account termination completes (all 3 steps ✅), then audit log contains deleted_account_id, deleted_at, sync_verified_at, s3_key, operator = 'system' | Integration |
| AC-5.8-35 | Given Exc-4 (Ledger INSERT fails after Forex sub-account creation), then Middleware calls Hard Delete on MT5/TE API; no Sync Verification required (account just created, no trade history); YourBourse Bridge config revoked if applicable; SEV-1 Slack #risk-ops alert fires; no phantom sub-account left on server (Source: CR-20260824-003) | Integration |
Update History
| Date | Version | Updated Section | Before | After | Reason |
|---|---|---|---|---|---|
| 2026-08-19 | v1.5 → v1.6 | §2 3rd Party · BR_5.8.14 table row 1 · §9 Connections tab spec | Live_Onboarding_Level_1 (3 occurrences) | Live_Onboarding_Credentials | Stale template name removed — confirmed renamed per H-12/STAGE3-060 2026-08-15 |
| 2026-08-12 | v1.1 → v1.2 | BR_5.8.14 — banner update UX (how frontend removes feed-lock banner); AC-5.8-21/22 added | Banner removal mechanism not specified — [MISSING] | Rithmic does NOT push real-time webhooks for CMR signing. Frontend must trigger GET /bps/trader/market-data-status to check status. Priority: Option 1 — manual "Refresh Status" / "I have signed" button on banner. Option 2 — slow poll every 60 s while banner is visible (secondary). | QnA STAGE3-035 confirmed 2026-08-12 |
| 2026-08-12 | v1.0 → v1.1 | §7 Exc-2 (Rithmic retry) + Exc-3 (MT5/TE retry) | Break-Glass Runbook only — no batch/retry specifics | Exc-2: Rithmic weekday failures → hourly batch retry; weekend (Fri 4pm CT – Sun 4pm CT) → batch + retry at Sunday 3:45pm CT. Exc-3: MT5/TE exponential backoff 1→3→5→15→30→60 min, then hourly. Break-Glass Runbook remains as final escalation. | STAGE3-024 [CHR-45] confirmed 2026-08-11 |
| 2026-08-10 | v1.6 → v1.7 | §9 NFR — Idempotency row | [⚠️ Explicit guard not documented in source — see Exc-7.] | Confirmed guard: account_status != Active_L[N]_DMA AND platform_username IS NULL check before executing (BR_5.8.15) | STAGE3-021 confirmed idempotency gate required (audited-v10 re-audit) |
| 2026-08-10 | v1.6 → v1.7 | §9 NFR — Atomicity row | [⚠️ Rollback behavior not documented.] | Break-Glass Runbook for Exc-2/3 (Ops Console manual provisioning); fire-and-continue + hourly retry queue for Exc-5 | STAGE3-021 confirmed exceptional flow behaviors (audited-v10 re-audit) |
| 2026-08-10 | v1.6 → v1.7 | §9 NFR — Audit row | No CR-08 citation | Added: "All timestamps conform to CR-08 (UTC / ISO 8601 / millisecond precision)" | CR-08 applies to credentials_last_rotated_at and all ledger timestamps — missing citation identified in audited-v10 Rule B check |
| 2026-08-10 | v1.6 → v1.7 | §9 NFR — new Display row | Not present | Added Display row: Level_Starting_Capital display conforms to CR-11 (2 decimal, comma thousands) | CR-11 applies to monetary value display — missing citation identified in audited-v10 Rule B check |
| 2026-08-10 | v1.6 → v1.7 | §11 AC — AC-5.8-14 (new) | Not present | Given Flow 3H triggered twice for same user_id → second invocation detects Active_L[N]_DMA or non-null platform_username → HALT, no re-provisioning | Idempotency gate confirmed in STAGE3-021 / BR_5.8.15 — but no explicit AC existed in UC; identified in audited-v10 |
| 2026-08-10 | v1.6 → v1.7 | §11 AC — AC-5.8-15 (new) | Not present | Given Flow 3H completes → credentials_claimed_at = NULL | Missing AC identified in audited-v6 generated list; finally applied in v1.7 |
| 2026-08-10 | v1.6 → v1.7 | §11 AC — AC-5.8-16/17/18/19 (new) | Only Level 1 capital values tested (AC-5.8-09/10) | Added Level 2 Futures ($2,500 / 16 Micros), Level 5 Futures ($11,250 / 7 Minis), Level 2 Forex ($1,500), Level 5 Forex ($15,000) | Coverage gap identified in audited-v10: AC-5.8-09/10 only covered Level 1 entries |
| 2026-08-10 | v1.6 → v1.7 | §11 AC — AC-5.8-20 (new) | Not present | Given Step 4 write-back completes → GET /platform-credentials returns non-null Platform/Login/Connection_String/Connection_Guide_URL matching trader's platform_selection | Integration trace gap identified in audited-v6 and confirmed unresolved in audited-v10 |
| 2026-08-22 | v1.6 → v1.7 | All sections — CHR tag standardization | Bare STAGE3 codes without CHR tags; date-based CR refs | A38: CR-20260813-001 → [CHR-46] (2 occurrences). B13: STAGE3-037 → STAGE3-037 [CHR-46] (5 occurrences). B14: STAGE3-038 → STAGE3-038 [CHR-44] (3 occurrences). B12: STAGE3-024 → STAGE3-024 [CHR-45] (7 occurrences). C7/C8 [BA-CR-45] not found in file — skipped. | CHR_Tag_Change_Plan_20260822_v4.md |
| 2026-08-22 | v1.7 → v1.8 | §5 Step 5 — Go Live Email cross-reference | See \list_email.md` for full email template spec.` | See [SES-26 — Go Live Credentials](/docs/BA/Common_rule/list_email.md#ses-26--go-live-credentials) in \list_email.md` for full email template spec.` | SES-26 entry created in list_email.md 2026-08-22 — UC_5.8 Step 5 now links directly to the SES ID. |
| 2026-08-24 | v1.9 → v2.0 | §7 Exc-10/11/12 (new) · §8 BR_5.8.21/22/23 (new) · §11 AC-5.8-31 to AC-5.8-35 (new) · Header version | Not present | Exc-10: asset-class conditional branch at LIVE termination (Futures=Unassign, Forex=Hard Delete 3-step). Exc-11: MT5/TE Sync Verification failure handling (blocks Hard Delete, SEV-1 alert). Exc-12: full MT5/TE Hard Delete 3-step sequence with rollback. BR_5.8.21: mandatory asset-class branch logic. BR_5.8.22: Forex flat server cost — no double-billing, Intra-Month Delta Protocol is Futures-only. BR_5.8.23: MT5/TE mandatory 3-step sequence contract. ACs 5.8-31 to 5.8-35 covering branch execution, sync block, step-3 rollback, audit log, Exc-4 rollback for Forex. | CR-20260824-002 client confirmed 2026-08-24 |
| 2026-08-24 | v1.8 → v1.9 | §5 Step 7 (new) · §6 Alt-6 (new) · §7 Exc-8/9 (new) · §8 BR_5.8.16–20 (new) · §10 Dashboard Clean Slate + Historical Performance tab · §11 AC-5.8-26 to AC-5.8-30 (new) · §4 Post-conditions · Header version | Not present | Step 7: async SIM Decommissioning Protocol (3 ordered sub-steps: Data Sync & Archive → S3 Glacier, SIM Non-Pro market data unsubscribe with same-month cache, Rithmic Paper Gateway Unassign). Alt-6 (CASE-REBUY-01): same-month Non-Pro data reuse on Rebuy. Exc-8 (ERR-DECOM-01): archive failure blocks Unassign + retry queue + Slack #risk-ops. Exc-9 (ERR-DECOM-02): Unassign success but data cancel fails → local lock + Slack #risk-ops. BRs 5.8.16–5.8.20: decommissioning sequence, same-month cache, Rebuy reuse, Dashboard Clean Slate, Historical Performance tab. ACs 5.8-26 to 5.8-30. Dashboard UI section updated with Clean Slate and Historical Performance tab behavior. | client confirmed 2026-08-24 |
| 2026-08-24 | v2.0 → v2.1 | §7 Exc-4 (asset-class branch rewrite) · §11 AC-5.8-24 split | Exc-4: single DeleteUser for both asset classes | Split: Futures → Suspend+Unassign; Forex → Hard Delete + YourBourse revoke. AC-5.8-24 → 24 (Futures) + 24b (Forex). AC-5.8-35 updated | CR-20260824-003 confirmed 2026-08-24 |
| 2026-08-25 | v2.1 → v2.2 | Q8–Q18 all applied (see Changelog row) | Multiple open tags and unconfirmed specs in §4/§5/§6/§7/§8/§9/§10 | All confirmed — field alias, async NFR, disabled tab state, BR_5.8.2 validation gate, ledger fire-and-continue, Level 2 single row, Alt-2 no-rerun note, sim_data_cancel_pending/sim_data_valid_until schema, ERR-DECOM-01 queue specs, 5s S3 timeout | Client confirmed 2026-08-25 |
| 2026-08-25 | v2.1 → v2.2 | Q8: Step 2.1 fcm_subaccount_id = rithmic_subaccount_id alias note; Q9: §9 NFR Latency — async endpoint design (HTTP 202, background worker, Zapier 10s timeout); Q10: §10 Connections & Credentials tab disabled state during Pending_Compliance; Q11: BR_5.8.2 Current_Level IN (1,2,5) validation gate + HTTP 400; Q12: §4 Post-conditions ledger fire-and-continue note; Q13: §5 Step 1 Level 2 single-row clarification; Q14: §6 Alt-2 Flow 3H no-re-run note for post-live feed upgrades; Q15: Exc-9 sim_data_cancel_pending BOOLEAN NOT NULL DEFAULT FALSE schema; Q16: Sub-step 7.2 sim_data_valid_until DATE schema + NOT cleared on CASE-REBUY-01; Q17: Exc-8 ERR-DECOM-01 Redis Queue 5 retries (30s→5m→30m→2h→6h) + 24h exhaustion + Saga partial retry; Q18: Sub-step 7.1 5-second S3 push timeout + immediate ERR-DECOM-01 enqueue on timeout | Multiple [⚠️ open] tags and unconfirmed specs across §4, §5, §6, §7, §8, §9, §10 | All Q8–Q18 confirmed answers applied. | Client confirmed 2026-08-25 |