UC 8.1.2
Flow 6 - Level 6 Transition: Country-routed W-2 (Path A) vs. International Contractor (Path B) onboarding, triggered when a trader is promoted to Level 6
| Field | Value |
|---|---|
| BA in Charge | Huyen Dinh |
| Date Created | 2026-10-10 |
| Version | v1 |
| Document References | Zapier Integration V7.pdf (§Flow 6 — Level 6 Transition, Tables A/B) · RFQ_ Stack Trading Prop Tech V7.pdf (§Financial & Transaction Endpoints, §Immutable Ledger / Proof of Payout) |
1. Overview
| Field | Content |
|---|---|
| ID | UC_8.1.2 |
| Use Case | Flow 6: Level 6 Transition (W-2 vs. International) |
| Description | When a trader is promoted to Level 6 (triggered byUC_8.1.1 Stage 5 Path B), the Middleware routes the trader by billing_country into either a US W-2 employment onboarding (Rippling) or an International Contractor retainer transition (Dots/SignWell). |
| Zapier Flow | Flow 6 (Level 6 Transition) — triggered by Flow 4 Stage 5 Path B (Next_Level == 6) |
| Zapier Table | Table A (Forex Level Params —Base_Income, Base_Income_Flex, Base_Income_Type, Title) · Table B (Futures Level Params — same fields) |
| 3rd Party | RipplingDots Typeform (Offer Configurator forms, embedded on a Stack Trading-hosted page)AWS SESPolygon/Ethers.js via Middleware |
Trigger
UC_8.1.1, Stage 5, Path B (Klaviyo promotion branch): Next_Level == 6 — Flow 6 is fired as a mandatory side-effect of Path B, alongside the Promotion_Level_6 Klaviyo event.
Pre-conditions
- The trader is being promoted to Level 6
- The trader's
billing_countryis populated on the PostgreSQLUserstable
Post-conditions
- Path A (US W-2):
comp_track('Standard'/'Flex') andstandard_hoursare set on theUsersrecord;- a Rippling W-2 employment record exists for the trader;
- the trader has signed their W-2 offer;
- completed I-9 Section 2 / E-Verify;
- the trader's payouts are routed to Rippling instead of Dots
- Path B (International):
Requested_Hours(<= 35) has been submitted via the Level_6_Offer_International Typeform and saved to theUsersrecord;- the trader's Dots payout profile is confirmed
Active; [CHR-131]user_employment_profiles.dots_monthly_retaineris set toBase_Income_Flex;- if the promotion occurred mid-month, an immediate one-off Dots transfer for the prorated remainder of the current month has already been triggered (Step 10.4).
- The post-promotion modal tracked by UC_8.1.1 §UI/UX — Modal A/Modal B closes once every required Flow 6 step for the trader's path is complete.
Basic Flow
Step 1 — Country Check (shared by Path A and Path B)
-
The Middleware queries
billing_countrydirectly from the PostgreSQLUserstable to decide which path to route the trader into:- [If
billing_country == 'US'] → Path A (US W-2), Step 2 below. - [Else] → Path B (International), Step 8 below.
- [If
Path A — US W-2
Step 2 — Offer Configurator
-
The Middleware retrieves
Base_IncomeandBase_Income_Flexfor Level 6 from Table A (Forex) or Table B (Futures). -
The system dispatches the
Level_6_Offer_Configuratoremail (SES-29) to the trader via AWS SES. This email contains the CTA link to the embedded Typeform below. -
This form only asks US traders for Track and Hours — it is a completely separate form from the Path B form; the two forms do not share a validation block.
Embedded Typeform — "Level 6: Corporate Seat & W-2 Configuration":
Field Content Form Title Level 6: Corporate Seat & W-2 Configuration Target US W-2 Traders upon reaching Level 6 Hidden Variables Required user_id,base_income,base_income_flexWelcome Screen "Congratulations. You have cleared the evaluation tracks, proven your edge, and secured your seat on the desk. Configure your official W-2 Corporate Offer below to formalize your promotion." Question 1 (Multiple Choice) "Select your Compensation Track:"Option A: "Standard Track: Hourly Rate of $[base_income] + Comprehensive Corporate Health & Welfare Benefits."Option B: "Flex Track: Hourly Rate of $[base_income_flex] (Maximum Cash Flow, No Benefits)." Question 2 (Number) "How many total hours per week do you commit to the desk?"Description/Hint: "This figure is used to generate your official employment schedule and Rippling timesheet." Validation Rule (Track A selected) Minimum 30, Maximum 35.Error Copy: "The Standard Track requires a minimum of 30 hours to legally qualify for corporate health benefits." / "Standard Track hours can not exceed 35 per week." Validation Rule (Track B selected) Minimum 1, Maximum 29. Error Copy: "Flex Track hours cannot exceed 29 per week. For 30+ hours, you must select the Standard Track." / "The Flex Track requires a minimum of 1 hour." Required Question 1 (Track) and Question 2 (Requested_Hours) are bothrequired — the trader cannot submit the form with either field blank. Ending Screen "Offer configuration locked. Our HR system will email your official Rippling onboarding package and employment agreements shortly. Welcome to the team." -
On submit, the Middleware updates the
Usersrecord:comp_track='Standard'(Track A) or'Flex'(Track B), andstandard_hours=Requested_Hours -
[If Track A] → once the trader is hired in Rippling (Step 3 below), Rippling's native platform automatically emails the trader the portal link to complete health and welfare benefits enrollment — the Middleware does not build this enrollment UI or call any separate API for it.
Step 3 — Zero-Entry Onboarding
-
The Middleware calls Rippling's
/events/hr/v1/worker.hire. Rippling itself detects an existing profile via email and Check: IF Employee_Exists → Rehire. ELSE → Create New" framing. -
The
worker.hirepayload includes:Field Value RateBase_Income(if Track A) orBase_Income_Flex(if Track B)Work_ScheduleDaily breakdown of hours per weekday. Since markets are open Monday through Friday, the Middleware divides Requested_Hoursevenly across those five days:hours_per_day = Requested_Hours / 5. Example: a trader entering 20 hours/week is sent to Rippling as 4 hours/day, Monday through Friday.TitleFrom Table A/B for Level 6 -
Once
worker.hiresucceeds, Rippling automatically emails the trader their onboarding invitation and login credentials — this is fully automated on Rippling's side.
Step 4 — Offer Generation
-
The Middleware triggers Rippling's native
W2_Offer_Template(built entirely inside Rippling, not by SotaTek) -
Dynamic fields on the offer, read from Table A/B for Level 6:
Condition Field set Base_Income_Type == 'Hourly'Hourly_Rate=Base_Income(Track A) orBase_Income_Flex(Track B) — pulled directly from Table A/BBase_Income_Type == 'Annual'Base_Salary= the annualizedBase_Income/Base_Income_Flexvalue sent as-is — no hourly-rate calculation is performed(always) Max_Authorized_Hours= 35 (Track A) or 29 (Track B);Job_Titlefrom Table A/B -
The Middleware sends the W2 Offer via Rippling with an "Identity Confirmation" checkbox — this form and the identity confirmation are hosted and executed entirely inside Rippling.
Step 5 — Immutable Ledger Logging
- Once the W2 Offer is signed, the Middleware calls
POST /api/ledger/recordwithtrader_id,metric_category = "W2 Offer Executed",metric_value = "Level 6 W2 Trader Status Achieved",date = Today,receipt_hash = [Rippling Envelope ID]. - This uses the exact same two-step receipt_hash → on-chain tx_hash mechanism in UC_8.1.1 §Stage 1 step 6, and the Middleware independently writes the metric on-chain via Ethers.js/Polygon and stores the real
tx_hash.
Step 6 — Hours Declaration
- Rippling's native Workflow Automator feature — which triggers internal tasks and emails based on HR events — fires the "Trading Hours Declaration" form. This is a native Rippling compliance form built by the client's own team; SotaTek does not build this form.
Step 7 — Compliance Hand-Off
- Rippling handles I-9 Section 2 and E-Verify automatically. If E-Verify fails, Rippling alerts Ops.
Path B — International
Step 8 — Country-Routed Form (Hours Only)
-
The system dispatches the
Level_6_Offer_Internationalemail (SES-30) to the trader via AWS SES. This email contains the CTA link to the embedded Typeform below. The form asks only forRequested_Hours(no Track selection, since international contractors are not eligible for US health benefits)Embedded Typeform — "Level 6: Global Retainer Configuration":
Field Content Form Title Level 6: Global Retainer Configuration Target International Contractors upon reaching Level 6 Hidden Variables Required user_id,base_income_flexWelcome Screen "Congratulations. You have cleared the evaluation tracks and proven your edge. As a Level 6 International Partner, you have unlocked institutional profit splits and a baseline retainer. Let's configure your payout profile." Question 1 (Statement) "Your Base Income Structure: As a senior international contractor, your base income is calculated via the Flex Track. Your initial hourly rate is set at $[base_income_flex] USD. You will continue to receive your performance bonuses on top of this retainer." Question 2 (Number) "How many total hours per week do you commit to the desk?"Description/Hint: "We use this metric to prorate your monthly retainer payout via Dots." Validation Rule Minimum 1, Maximum 35. Error Copy: "Flex Track hours can not exceed 35 per week." / "The Flex Track requires a minimum of 1 hour." Required Question 2 (Requested_Hours) isrequired — the trader cannot submit the form with it blank Ending Screen "Parameters locked. Our Operations team is updating your payout profile to reflect your new retainer. Welcome to the senior desk." -
The flow halts until the form is submitted and
Requested_Hoursis saved to the SQL database.
Step 9 — Dots Payout Validation
-
The Middleware calls the Dots API to verify the contractor's payout profile status.
- [If
Active] → proceed to Step 10.
- [If
Step 10 — International Contractor Notification
- Once Dots returns
Active, the system fires the Level_6_International_Contractor email (SES-13) via AWS SES, providing the trader their operational instructions. - Update
International Base = Base_Income_Flex(the International track always uses the Flex-track income figure, regardless of hours). [CHR-131]There is no Rippling action for Path B — international traders remain contractors. The Middleware calculates the monthly retainer amount based on the trader'sBase_Income_TypeandRequested_Hoursfrom the submitted form, and updates the recurring Dots monthly retainer trigger:- Formula (Hourly): If
Base_Income_Type == 'Hourly':dots_monthly_retainer = Base_Income_Flex * ((Requested_Hours * 52) / 12) - Formula (Annual): If
Base_Income_Type == 'Annual':dots_monthly_retainer = Base_Income_Flex / 12 - It writes/updates the calculated value to
user_employment_profiles.dots_monthly_retainer(Decimal). - An internal cron job runs on the 1st day of every month:
- Queries all users with
dots_monthly_retainer > 0. - For each matching user, calls
POST /v2/transfersvia the Dots API.
- Queries all users with
- Formula (Hourly): If
- Mid-month promotion — immediate prorated payout. Because the Step 10.3 monthly cron only runs on the 1st of the month in advance, a Level 6 promotion that lands mid-month requires an additional one-off payout for the remainder of the current month, on top of saving
dots_monthly_retainerfor future cron runs:-
Adjusted_Retaineris the same full monthly retainer value just calculated in Step 10.3 (Base_Income_Flex * ((Requested_Hours * 52) / 12)for Hourly, orBase_Income_Flex / 12for Annual). -
Proration_Factor: Business Days Only (US/Central) — remaining business days in the current month (from the promotion date to month-end) divided by the total business days in the current month, excluding both weekends (Sat/Sun) and US Federal/Bank holidays. -
The Middleware calculates the prorated amount for the remaining US business days of the current month:
Prorated_Amount = Adjusted_Retainer * Proration_Factor.Example: Trader is promoted to Level 6 on 2026-11-18 (Wednesday, US/Central),
Base_Income_Type = 'Hourly',Base_Income_Flex = 25(USD/hour),Requested_Hours = 40→Adjusted_Retainer = 25 * ((40 * 52) / 12) = 4,333.33(USD/month).Total business days in November 2026: the month has 30 calendar days, 8 of which fall on a weekend (Sat/Sun: 11-07/08, 11-14/15, 11-21/22, 11-28/29) → 22 weekdays. Thanksgiving (Thu 11-26) is a US Federal holiday and is also excluded → 21 total business days in the month.
Remaining business days (11-19 through 11-30): 11-19 (Thu), 11-20 (Fri), 11-23 (Mon), 11-24 (Tue), 11-25 (Wed), 11-27 (Fri), 11-30 (Mon) → 7 remaining business days (11-21/22 and 11-28/29 are weekends, 11-26 is Thanksgiving, all already excluded from the count).
Proration_Factor = 7 / 21 = 0.3333.Prorated_Amount = 4,333.33 * 0.3333 = 1,444.44(USD), dispatched immediately as a one-off Dots payout. Starting 2026-12-01, the monthly cron pays the fullAdjusted_Retainer = 4,333.33. -
It immediately triggers a one-off Dots transfer for
Prorated_AmountviaPOST /v2/transfers— it does not wait for the next 1st-of-month cron run. -
(For comparison, Path A/Rippling needs no equivalent step: the Middleware only passes the selected rate and
Requested_Hoursto the Offer Generation step in Step 4, and Rippling's native in-arrears W-2 payroll handles the partial month itself.)
-
Step 11 — Sync
- The Middleware synchronizes the
Start Date(the effective date of the Level 6 promotion) andTitle(fetched from Table A/B for Level 6) into theUserstable and the Independent Contractor Agreement. This ensures International contractors have the exact same official job title and effective start date as their W-2 counterparts.
Business Rules
BR_8.1.2.1: Post-Signature Lock
- Track A (Full Benefits):
Requested_Hoursmust be entered as a value between 30 and 35 inclusive. 30 is a legal minimum required to qualify for the corporate health benefits package — the trader cannot enter a value lower than 30 (Source: QnA_Level_Promotion.md Section 4.3, Round 4, Q2.2/A2.2). - Track B (Flex Cash):
Requested_Hoursmust be between 1 and 29 inclusive. - Path B (International):
Requested_Hoursmust be between 1 and 35 inclusive. - Lock after signature: once the Offer Configurator form is submitted and the Rippling W-2 contract is generated and signed, the trader's default schedule (
standard_hours) is locked — it cannot be changed dynamically through the dashboard. Any later change requires opening an internal HR support ticket, handled manually by Operations — this is a Day 2 item, not built in the current scope.
BR_8.1.2.3: Base_Income_Type Lock
base_income_type is not user-editable. It is hardcoded by level in Table A/B: 'Hourly' for Levels 6 through 9, automatically switching to 'Annual' once the trader is promoted to Level 10 (Senior Trader 1).
BR_8.1.2.4: Track Switching Ban
Once the W-2 contract (Path A) is signed, the trader cannot switch between the Standard and Flex compensation tracks via the dashboard — no track-switching UI is built. Any future track change is a manual Operations action performed directly inside Rippling.
BR_8.1.2.5: 3rd-Party API Failure Handling (SEV-01 Halt)
Any call this flow makes to a 3rd-party API (Rippling, Dots, or any other external vendor integrated by Flow 6) that fails triggers a SEV-01 Slack alert and an immediate HALT of the flow in #ops-general (C0BR8LRC5MK / Test C0BR6UXRR8D).
Slack Error Message Format:
- Message Content:
[SEV-01] Level 6 Promotion API Failed Trader ID: [user_id] Email: [trader_email] Failed Action: [API endpoint or integration name, e.g., worker.hire on Rippling] Error Detail: [HTTP Status Code - Error Message] Status: The automated Level 6 transition flow has been HALTED. Manual intervention is required to complete the promotion.
BR_8.1.2.6: Rebuy/Termination Impact on Comp Data
If a Level 6+ W-2 trader is terminated (Hard Breach) and subsequently purchases a Rebuy, the Middleware must clear comp_track and standard_hours on the Users record. The trader returns to the Associate Track (no salary or benefits). If the trader reaches Level 6 again, this entire UC_8.1.2 flow runs again from Step 1, including a fresh worker.hire call — Rippling resolves rehire-vs-create-new itself via email/SSN matching, same as the first time.
Changelog
| Date | Version | Updated item | Before | After | Notes |
|---|---|---|---|---|---|
| 2026-10-10 | v1 | Initial document | — | Full SRS for Flow 6 authored | Source: QnA_init_docs.md (37/38 confirmed, A-10/SES-13 pending), QnA_Level_Promotion.md Section 4/4.1/4.2/4.3/7 |
| 2026-10-11 | v1 | Step 6, Step 7.1, Step 8.2, Post-condition Path A | Step 6 was "Suspend Dots Payout Trigger" (clears Users.dots_monthly_retainer), Step 8.2 derived "Close 1099→Create W-2" from Step 6+Step 3, Step 7.1 described Rippling Workflow Automator as a passive HR-event trigger | Step 6 renamed to "Close 1099 Account" (bookkeeping-only flag, does not touch dots_monthly_retainer — that field is never set for Path A traders); Step 8.2 clarified both sides complete independently (W-2 created in Step 3, 1099 closed in Step 6); Step 7.1 clarified Middleware actively calls Rippling API to trigger Workflow Automator, passing Typeform values; added [BLOCKER] notes at Step 5.3/6.2 on the disabled Rippling "Call a public API" action | Source: QnA_STAGE6_CAREER_PATH.md STAGE6-025, STAGE6-027, STAGE6-028 |
| 2026-10-20 | v1 | Post-condition Path B, Step 6, Step 11.3, Changelog 2026-10-11 row (reference text) | Users.dots_monthly_retainer / users.dots_monthly_retainer | user_employment_profiles.dots_monthly_retainer — field moved off the Users table onto its own user_employment_profiles table; column name unchanged | BA update per client direction |
| 2026-10-26 | v1 | Step 10 — removed Suspended/failed branch | Step 10 cited UC_5.4 BR_5.4.8/BR_5.4.9 (Dots suspension webhook listener → payout_status = 'Suspended' → Dots_Profile_Action_Needed email) for the non-Active case | Branch removed — Step 10 now only covers the Active case (proceed to Step 11). The cited BRs no longer exist: CHR-80 (2026-10-21/23) removed the entire Dots suspension webhook listener + payout_status gate from both UC_5.4 (§7 Sub-flow B, BR_5.4.8/BR_5.4.9) and UC_5.8 (P7 pre-condition) | Broken link fix — CHR-80 removed the underlying mechanism this step relied on; no replacement rule defined upstream, so the branch is dropped rather than re-authored without a source |
| 2026-10-27 | v1 | Post-condition Path A/B; Step 6 "Close 1099 Account" removed entirely (all later Path A/B steps renumbered down by one: old 7→6, 8→7, 9→8, 10→9, 11→10, old 12 "Agreement Storage" removed, old 13 "Sync"→11); Step 10 (new) gained sub-step 10.4 | Step 12 "Agreement Storage" (old numbering) had the Middleware store the signed ICA to S3 and save contractor_agreement_s3_uri on Users as part of Flow 6 Path B; Step 11.3 (old numbering) only described the 1st-of-month recurring cron, with no mid-month proration logic; Step 6 said the Middleware "flags the trader's contractor status as inactive/archived on the Users record" (a bookkeeping write) | "Agreement Storage" step removed entirely — the ICA signed via SignWell at Stage 3 KYC (Flow 3E) already covers Levels 1-24, so Flow 6 does not re-sign or re-store it; S3 storage happens at Flow 3E, triggered by SignWell's document-signed webhook, not here. Step 6 "Close 1099 Account" removed entirely (not just corrected to a no-op) — there is no DB write, no Dots API call, and no "1099 status" field at all for this step; dots_payee_id/payout_status are left untouched, and the payout-routing switch from Dots to Rippling happens passively inside Flow 5 (Payouts) every pay cycle, based on billing_country/current_level. All subsequent Path A/B steps renumbered down by one to close the gap. "Sync" step gained sub-step on mid-month proration: a Level 6 promotion landing mid-month must calculate the prorated remainder of the current month (Adjusted_Retainer * Proration_Factor) and trigger an immediate one-off POST /v2/transfers, in addition to saving dots_monthly_retainer for future cron runs | Source: QnA_Level_Promotion.md Section 4.4, Round 5 (Q1/A1 closes STAGE6-OQ-03; Q2/A2 closes STAGE6-OQ-04, overrides Round 3 Section 4.2 Q1/A1; Q4/A4 clarifies STAGE6-028) |
| 2026-10-27 | v1 | Step 10.4 — formula spelled out | Adjusted_Retainer * Proration_Factor was stated with no definition of either term, no worked example, and no Proration_Factor methodology — left ambiguous how to actually compute the mid-month prorated payout | Clarified: Adjusted_Retainer = the same full monthly retainer just computed in Step 10.3 (no "Old" value to subtract, unlike the Level 7+ raise delta formula in UC_8.3.1 BR_8.3.1.6, since this is the trader's first-ever Dots retainer); Proration_Factor = remaining Business-Days-Only (US/Central, excluding weekends and US Federal/Bank holidays) divided by total business days in the current month, same methodology as UC_8.3.1 Step 3.5; added a fully worked numeric example mirroring the one already confirmed in UC_8.3.1 | Root source (QnA_Level_Promotion.md Round 5 Q1/A1) only gave the bare formula without defining terms; cross-referenced UC_8.3.1's already-confirmed Proration_Factor methodology (same underlying business-days convention) to fill the gap rather than inventing a new one |