StackTrading Docs

SRS: Stage 3 KYC & Live Onboarding — UC_5.8: Flow 3H Live Account Provisioning & Risk Setup

FieldValue
BA in Chargelinh.nguyen34
Date Created2026-08-08
Versionv2.2
Last Updated2026-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 ReferencesZapier 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_IDUse Case NameBusiness Description
UC_5.8Flow 3H — Live Account Provisioning & Risk SetupFinal 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

DateVersionUpdated itemBeforeAfterNotes
2026-08-08v1.0Initial creationCreated SRS for UC_5.8 (Flow 3H)First authoring pass
2026-08-10v1.1Q1: 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 fieldQnA STAGE3-014 confirmed 2026-08-10
2026-08-10v1.2Q4: CMR Agreement signing sequence confirmed — AFTER provisioning, not a pre-condition; BR_5.8.14 added; §3 and §4 updated with CMR lock/unlock sequenceCMR sequence unconfirmed (Q4 open)Confirmed: provisioning → credentials email → first RTrader Pro login → Rithmic intercepts + forces CMR signing → feeds unlocked
2026-08-10v1.3Q3: 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 contextis_professional listed only in BR_5.8.5 as CME Professional enforcement; not tracked in DB write-backConfirmed: 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 gateQnA STAGE3-018 confirmed 2026-08-10
2026-08-10v1.4Q5: 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 addedQ5 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-statusQnA STAGE3-019 confirmed 2026-08-10
2026-08-10v1.5Q2: 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-10v1.6Q6: All 7 exceptional flows confirmed; §7 rewritten with confirmed retry/rollback/escalation behavior; BR_5.8.15 (idempotency gate) addedAll Exc-1 to Exc-7 flagged ⚠️ unconfirmedExc-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-10v1.7Re-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-15v1.4Step 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 updatedLive_Onboarding_Level_1; Exc-1 [⚠️ BA to confirm]; Exc-4 DeleteUser [⚠️ BA to confirm]; Exc-5 fire-and-continue BA recommendationTemplate 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-12v1.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-12v1.2 → v1.3§3 P7 added — payout_status = 'Approved' pre-condition (NEW)Flow 3H only checked contract_status + setup_statusAdded 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

FieldContent
IDUC_5.8
Use CaseFlow 3H — Live Account Provisioning & Risk Setup
DescriptionFinal 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 FlowFlow 3H (Live Account Provisioning & Risk Setup)
Backend EndpointPOST /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 TableUsers 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 PartyRithmic 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-trader previously 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' AND setup_status IN ('Complete', 'N/A') are satisfied simultaneously. UC_5.5 / Flow 3E sets contract_status = 'Signed'. UC_5.6 / Flow 3F sets setup_status = 'N/A' (Futures Option A) or UC_5.7 / Flow 3G sets setup_status = 'Complete' (Futures Option B). Forex traders receive setup_status = 'N/A' from Flow 3F directly. The gate fires from either side: if setup_status is set first, Flow 3F/3G re-checks contract_status; if contract_status is set first, Flow 3E re-checks setup_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_Capital is pulled from Table A (Forex) or Table B (Futures) for the trader's Current_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_status is 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_status is 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
P1contract_status = 'Signed' — trader has completed ISDA/Trader Agreement signing (UC_5.5)
P2setup_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)
P3Trader's Current_Level is 1, 2, or 5 — valid live entry levels
P4asset_class is either 'Futures' or 'Forex' — determines gateway routing
P5For Futures traders: fcm_subaccount_id is populated from Ironbeam JSON payload (set during Flow 3B.2 Ironbeam KYC) UPDATED (STAGE3-037 [CHR-46] 2026-08-12): For Futures traders: 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).
P6is_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_version written to Users table
  • credentials_last_rotated_at = NOW(), credentials_claimed_at = NULL
  • ledgers table 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_Credentials email 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 Unassign executed

Futures-specific post-conditions:

  • Trader provisioned on specific fcm_subaccount_id from 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/Locked state 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_Capital injected 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_Capital from Table B; Forex: Level_Starting_Capital = Max_Forex_Notional / 50 from Table A)
  • Max_Contracts_ES_Equiv (Futures only) — contract limit for Risk Group Template
  • Assets_Permitted (Futures only) — asset class whitelist

Table B (Futures) entry level values:

LevelTitleFutures_CapitalProfit_TargetMarket_LossMax_Contracts_ES_EquivAssets_Permitted
1Associate Trader$1,250$1,875$1,2508 MicrosMicros Only (MES, MNQ, M2K)
2Associate Trader$2,500$3,750$2,50016 MicrosMicros 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:

LevelTitleMax_Forex_NotionalLevel_Starting_Capital (÷50)Profit_TargetMarket_Loss
1Associate Trader$25,000$500$1,875$1,250
2Associate Trader$75,000$1,500$5,625$3,750
5Associate 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.txt line 1297 incorrectly shows POST /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. The RFQ_ Stack Trading Prop Tech V7.pdf (official Middleware Hub API Contract) is authoritative: canonical path is POST /provisioning/live-trader. (Source: QnA STAGE3-014)

Source resolution (Q2 — confirmed 2026-08-10): zapier_v7_full.txt line 1298 refers to this field as Market_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 maps Market_Data_Selectionsdata_selections. data_selections is 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:

FieldValueNotes
user_idTrader's user_idFrom Zapier payload
risk_group"Live_W2"Fixed value per RFQ_ Stack Trading Prop Tech V7.pdf line 1116
data_selectionsSelected 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_idSpecific Ironbeam FCM sub-account IDFutures 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 specific fcm_subaccount_id passed 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 to POST /provisioning/live-trader) and rithmic_subaccount_id (the DB column name in PostgreSQL Users table) refer to the same physical value — the Ironbeam sub-account ID. Middleware maps fcm_subaccount_id from the request body to rithmic_subaccount_id in 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_id on Rithmic Live FCM Gateway. Assign to predefined Risk Group Template. Capital Injection: push Level_Starting_Capital as 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: push Level_Starting_Capital via 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)
  • 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_id
  • level_id = Current_Level
  • virtual_equity = Level_Starting_Capital
  • allocated_capital = Level_Starting_Capital
  • mapped_account_id = [Specific FCM Sub Account ID (Futures) OR Forex Omnibus Account ID (Forex)]
  • is_active = true
  • last_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.

FieldValue
trader_idpayload.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)"
dateToday
receipt_hashPostgreSQL 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.

FieldSET Value
platform_usernameresponse.platform_username
platform_password_ciphertextresponse.platform_password_ciphertext
license_key_ciphertextresponse.license_key_ciphertext
cipher_versionresponse.cipher_version
credentials_last_rotated_atNOW()
credentials_claimed_atNULL
is_professionalresponse.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 described Live_Onboarding_Level_1 as a compliance onboarding pack link email (matching UC_5.3 context). Client has confirmed the credential delivery email at Flow 3H is renamed to Live_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_Success confirmation 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_until is 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 Unassign command 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.7 POST /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_until for the trader's user_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_until is 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:

  1. 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.
  2. Unassign sub-account: Execute Unassign command on Rithmic Live FCM Gateway to detach the sub-account from the trader's User ID. Sub-account returns to Ironbeam_Account_Pool for reuse. Stops $25/month platform seat fee.
  3. SEV-1 incident: Fire AWS CloudWatch Alarm → Slack #risk-ops alert: "Futures Provisioning Rollback — Ledger INSERT failed, sub-account unassigned. Manual verification required for fcm_subaccount_id = [id]".
  4. 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:

  1. 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.
  2. 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.
  3. SEV-1 incident: Fire AWS CloudWatch Alarm → Slack #risk-ops alert: "Forex Provisioning Rollback — Ledger INSERT failed, sub-account hard deleted. Manual verification required for user_id = [id]".
  4. 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_status is already Active_L[N]_DMA → HALT
  • IF platform_username is 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 until Sync_Success is 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-ops SEV-1 alert + Freshdesk L2 ticket for Ops manual intervention to complete the archive before Unassign is permitted.
  • Rationale: Running Unassign before 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: records sim_data_cancel_pending = true to prevent billing leakage tracking gaps. Schema: sim_data_cancel_pending BOOLEAN NOT NULL DEFAULT FALSE on Users table — set to TRUE when cancel is pending; reset to FALSE after cancellation is processed. (Q15, confirmed 2026-08-25)
  • Middleware sends a Slack alert to #risk-ops with the trader's user_id and failure reason.
  • Ops must manually cancel the data subscription via the Rithmic admin portal.
  • The local sim_data_valid_until cache 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_Pool and 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_snapshots tables contain all records for mt5_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 for mt5_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_id in PostgreSQL (mt5_account_id / te_account_id updated).
  • 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 for mt5_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 IDDescriptionSource
BR_5.8.1Flow 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.2Entry 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_id source changed from Ironbeam inbound JSON payload (Flow 3B.2) to pre-provisioned bulk pool (Ironbeam_Account_Pool table). 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):

StepActorAction
1Flow 3HProvisions Rithmic sub-account, generates platform_username + platform_password, sends Live_Onboarding_Credentials credentials email
2RithmicAutomatically places live market data feeds in Disabled/Locked state upon account creation
3TraderDownloads R
4Rithmic (native)Intercepts first login session; forces trader to digitally sign CMR agreements for all subscribed exchanges (CME, COMEX, CBOT, NYMEX)
5Rithmic (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 == false

Indicates: 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-status returns all subscribed exchange values as true.
  • 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:

OptionMechanismPriority
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

NFRRequirement
SecurityPlatform credentials stored encrypted (platform_password_ciphertext, license_key_ciphertext) with cipher_version tracking. credentials_claimed_at enables credential access audit.
IdempotencyFlow 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)
AtomicitySub-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).
AuditPOST /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).
Compliance100% of live Futures traders are classified CME Professional (BR_5.8.5). No opt-out.
LatencyPOST /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)
DisplayLevel_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_selection to return platform-specific connection guide (PDF or Notion link)
  • Trader accesses this tab after receiving the Live_Onboarding_Credentials email
  • Pre-provisioning state (Q10, confirmed 2026-08-25): Tab is in Disabled state (not hidden, not empty placeholder text). During Pending_Compliance computed state, the Dashboard applies a frosted glass overlay + sidebar menu block across all trader-facing tabs. Once Flow 3H completes and account_status transitions to Active_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_flags state
  • "Reactivate" button: enabled if status = Inactive_Hold; calls POST /toggle-market-data with enable_data: true
  • "Manage Add-ons" button: calls GET /market-data-products, then POST /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_IDCriterionTest Type
AC-5.8-01Given 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 tableIntegration
AC-5.8-02Given 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 injectedIntegration
AC-5.8-03Given 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 NULLIntegration
AC-5.8-04Given 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_valueIntegration
AC-5.8-05Given Futures trader with market_data_billable = True, when provisioned, then Professional Market Data + selected add-ons are active on RithmicIntegration
AC-5.8-06Given Futures trader with market_data_billable = False, when provisioned, then only Standard Data (Firm Covered as Professional) is active — no NYMEX/CBOT/COMEX add-onsIntegration
AC-5.8-07Given Flow 3H completes, when Live_Onboarding_Credentials email is triggered, then trader receives credentials emailE2E
AC-5.8-08Given Flow 3H completes, then Flow 10 (Pod Mentorship Onboarding) is triggeredIntegration
AC-5.8-09Given Level 1 Futures entry, then Level_Starting_Capital = $1,250 and Max_Contracts_ES_Equiv = 8 MicrosIntegration
AC-5.8-10Given Level 1 Forex entry, then Level_Starting_Capital = $500 ($25,000 / 50)Integration
AC-5.8-11Given Futures trader is provisioned, then CME Subscriber Status = 'Professional' at Rithmic level regardless of prior settingIntegration
AC-5.8-12Given POST /provisioning/live-trader returns non-200, then account_status is NOT updated to Active_L[N]_DMA and credentials are NOT writtenIntegration
AC-5.8-13Given 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 bannerIntegration
AC-5.8-14Given 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 INSERTIntegration
AC-5.8-15Given Flow 3H completes successfully, then credentials_claimed_at = NULL in Users tableIntegration
AC-5.8-16Given Level 2 Futures entry, then Level_Starting_Capital = $2,500 and Max_Contracts_ES_Equiv = 16 MicrosIntegration
AC-5.8-17Given Level 5 Futures entry, then Level_Starting_Capital = $11,250 and Max_Contracts_ES_Equiv = 7 MinisIntegration
AC-5.8-18Given Level 2 Forex entry, then Level_Starting_Capital = $1,500 ($75,000 / 50)Integration
AC-5.8-19Given Level 5 Forex entry, then Level_Starting_Capital = $15,000 ($750,000 / 50)Integration
AC-5.8-20Given 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_selectionIntegration
AC-5.8-21Given 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 immediatelyUI / Integration
AC-5.8-22Given 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 stopsUI / Integration
AC-5.8-23Given 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 sentIntegration
AC-5.8-24Given 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-24bGiven 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-25Given 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 failureIntegration
AC-5.8-26Given 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.1Integration
AC-5.8-27Given 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 exhaustsIntegration
AC-5.8-28Given 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-01Integration
AC-5.8-29Given 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 monthIntegration
AC-5.8-30Given 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" tabUI / Integration
AC-5.8-31Given 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 executionIntegration
AC-5.8-32Given 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 deletedIntegration
AC-5.8-33Given 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 downtimeIntegration
AC-5.8-34Given 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-35Given 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

DateVersionUpdated SectionBeforeAfterReason
2026-08-19v1.5 → v1.6§2 3rd Party · BR_5.8.14 table row 1 · §9 Connections tab specLive_Onboarding_Level_1 (3 occurrences)Live_Onboarding_CredentialsStale template name removed — confirmed renamed per H-12/STAGE3-060 2026-08-15
2026-08-12v1.1 → v1.2BR_5.8.14 — banner update UX (how frontend removes feed-lock banner); AC-5.8-21/22 addedBanner 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-12v1.0 → v1.1§7 Exc-2 (Rithmic retry) + Exc-3 (MT5/TE retry)Break-Glass Runbook only — no batch/retry specificsExc-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-10v1.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-10v1.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-5STAGE3-021 confirmed exceptional flow behaviors (audited-v10 re-audit)
2026-08-10v1.6 → v1.7§9 NFR — Audit rowNo CR-08 citationAdded: "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-10v1.6 → v1.7§9 NFR — new Display rowNot presentAdded 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-10v1.6 → v1.7§11 AC — AC-5.8-14 (new)Not presentGiven Flow 3H triggered twice for same user_id → second invocation detects Active_L[N]_DMA or non-null platform_username → HALT, no re-provisioningIdempotency gate confirmed in STAGE3-021 / BR_5.8.15 — but no explicit AC existed in UC; identified in audited-v10
2026-08-10v1.6 → v1.7§11 AC — AC-5.8-15 (new)Not presentGiven Flow 3H completes → credentials_claimed_at = NULLMissing AC identified in audited-v6 generated list; finally applied in v1.7
2026-08-10v1.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-10v1.6 → v1.7§11 AC — AC-5.8-20 (new)Not presentGiven Step 4 write-back completes → GET /platform-credentials returns non-null Platform/Login/Connection_String/Connection_Guide_URL matching trader's platform_selectionIntegration trace gap identified in audited-v6 and confirmed unresolved in audited-v10
2026-08-22v1.6 → v1.7All sections — CHR tag standardizationBare STAGE3 codes without CHR tags; date-based CR refsA38: 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-22v1.7 → v1.8§5 Step 5 — Go Live Email cross-referenceSee \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-24v1.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 versionNot presentExc-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-24v1.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 versionNot presentStep 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-24v2.0 → v2.1§7 Exc-4 (asset-class branch rewrite) · §11 AC-5.8-24 splitExc-4: single DeleteUser for both asset classesSplit: Futures → Suspend+Unassign; Forex → Hard Delete + YourBourse revoke. AC-5.8-24 → 24 (Futures) + 24b (Forex). AC-5.8-35 updatedCR-20260824-003 confirmed 2026-08-24
2026-08-25v2.1 → v2.2Q8–Q18 all applied (see Changelog row)Multiple open tags and unconfirmed specs in §4/§5/§6/§7/§8/§9/§10All 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 timeoutClient confirmed 2026-08-25
2026-08-25v2.1 → v2.2Q8: 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 timeoutMultiple [⚠️ open] tags and unconfirmed specs across §4, §5, §6, §7, §8, §9, §10All Q8–Q18 confirmed answers applied.Client confirmed 2026-08-25

On this page