Raxx · internal docs

internal · gated ↑ index

Founders Gate — Test Matrix and Run Guide

SC-FG7 (#2197, epic #492). Last updated: 2026-05-16 UTC.


Overview

The founders gate limits signup to a fixed cohort size. When the cohort fills (threshold=250 Founder seats) the signup form and landing page CTAs are hidden; visitors see a waitlist CTA instead. The gate is controlled by FLAG_FOUNDERS_GATE and is fail-open: any Queue outage allows signup to proceed.

This document describes the full test matrix, file locations, and how to run each suite locally.


Test file locations

Backend (pytest)

File Scope
backend_v2/tests/test_founders_gate_fg7_2197.py SC-FG7 combined integration tests: threshold transition, fail-open, flag OFF
backend_v2/tests/test_founders_gate_sc_fg2_2192.py SC-FG2 unit + integration: founders_gate_service + POST /api/auth/register/options
backend_v2/tests/test_founders_gate_state_sc_fg3_2193.py SC-FG3 unit + integration: GET /api/auth/founders-gate-state + rate limit

Frontend (Jest)

Antlers (frontend/trademaster_ui/)

File Scope
src/pages/Signup/__tests__/FoundersGateFG7.test.js SC-FG7: threshold boundary + 60s poll transition + fail-open (SignupPage)
src/pages/Signup/__tests__/SignupPage.test.js (AC-FG describe block) SC-FG4: gate hide/show on SignupPage
src/pages/Signup/__tests__/FoundersGateClosed.test.js SC-FG4: FoundersGateClosed component render
src/api/__tests__/foundersGateAPI.test.js SC-FG4: foundersGateAPI client unit tests

getraxx landing (frontend/getraxx-landing/)

File Scope
src/__tests__/HeroSectionFoundersGate.test.jsx SC-FG5: HeroSection CTA hide/show
src/__tests__/useFoundersGate.test.js SC-FG5: useFoundersGate hook unit tests

Test matrix

Threshold transition

ID Scenario Count Expected — signup (POST) Expected — probe (GET) Test file(s)
T1 Last open seat 249 202 {"open": true} test_founders_gate_fg7_2197.py::TestThresholdTransition::test_T1*, FoundersGateFG7.test.js::FG7-T1
T2 Cohort full 250 403 founders_gate_closed {"open": false} test_founders_gate_fg7_2197.py::TestThresholdTransition::test_T2*, FoundersGateFG7.test.js::FG7-T2
T3 Mid-session open→closed Cache expires, new Queue call, both endpoints reflect closed test_founders_gate_fg7_2197.py::TestThresholdTransition::test_T3*, FoundersGateFG7.test.js::FG7-T3
T4 Mid-session closed→open Second poll restores open state FoundersGateFG7.test.js::FG7-T4

Fail-open (Queue outage — ADR-0094)

ID Failure mode Expected — signup Expected — probe Test file(s)
F1 URLError / timeout 202 {"open": true} test_founders_gate_fg7_2197.py::TestFailOpenOnQueueOutage::test_F1*, FoundersGateFG7.test.js::FG7-F1
F2 HTTPError 5xx 202 {"open": true} test_founders_gate_fg7_2197.py::TestFailOpenOnQueueOutage::test_F2*, FoundersGateFG7.test.js::FG7-F2
F3 Missing QUEUE_INTERNAL_BASE_URL 202 test_founders_gate_fg7_2197.py::TestFailOpenOnQueueOutage::test_queue_missing_base_url_signup_returns_202

Flag OFF behavior

ID Scenario Expected — signup Expected — probe Queue calls
O1 FLAG_FOUNDERS_GATE=false 202 {"open": true} 0

Test file: test_founders_gate_fg7_2197.py::TestFlagOff, FoundersGateFG7.test.js::FG7-O1

Response shape invariants

ID Invariant Test file
S1 Probe body is exactly {"open": <bool>} — no count/threshold test_founders_gate_fg7_2197.py::TestResponseShapeInvariants::test_probe_response_contains_only_open_field
S2 Probe never exposes count or threshold (ADR-0094 info-leak avoidance) test_founders_gate_fg7_2197.py::TestResponseShapeInvariants::test_probe_response_does_not_expose_count_or_threshold
S3 Signup 403 body has error, message, waitlist_url test_founders_gate_fg7_2197.py::TestResponseShapeInvariants::test_signup_403_body_has_required_fields
S4 waitlist_url in 403 matches FOUNDERS_WAITLIST_URL env var test_founders_gate_fg7_2197.py::TestResponseShapeInvariants::test_signup_403_waitlist_url_matches_env_var

How to run locally

Backend tests (all founders gate)

python -m pytest backend_v2/tests/test_founders_gate_fg7_2197.py \
                 backend_v2/tests/test_founders_gate_sc_fg2_2192.py \
                 backend_v2/tests/test_founders_gate_state_sc_fg3_2193.py \
                 -v

Run only SC-FG7:

python -m pytest backend_v2/tests/test_founders_gate_fg7_2197.py -v

Run just the fail-open class:

python -m pytest backend_v2/tests/test_founders_gate_fg7_2197.py::TestFailOpenOnQueueOutage -v

Frontend tests — Antlers (SC-FG7 + SC-FG4)

npm --prefix frontend/trademaster_ui run test:auth

Or run only the FG7 file:

npm --prefix frontend/trademaster_ui test -- --watchAll=false \
  src/pages/Signup/__tests__/FoundersGateFG7.test.js

Frontend tests — getraxx landing (SC-FG5)

npm --prefix frontend/getraxx-landing test -- --watchAll=false \
  src/__tests__/HeroSectionFoundersGate.test.jsx \
  src/__tests__/useFoundersGate.test.js

Full CI smoke (backend + frontend)

./scripts/ci/run_smoke.sh

Feature flag

FLAG_FOUNDERS_GATE (defined in backend_v2/api/feature_flags.yaml).

When false: gate is bypassed entirely. Queue is never called. Signup always allowed. Probe always returns {"open": true}.


Seeding Founder seat counts in a test environment

These tests use mocks — no real Queue DB is needed. The urlopen patch injects the desired count/threshold/open values directly into the service. If you need a live-stack test with a real Queue, seed the founder_cohort_members table in Queue's database to 249 or 250 rows and point QUEUE_INTERNAL_BASE_URL at the live Queue instance.


ADR references