OPERATOR_EXPERIENCE.md
5 tested operator journeys with acceptance criteria. Every journey has a persona, a trigger, a time budget, and a definition of done.
Journey 1: OpB 30-Second Phone Dashboard
Persona: OpB -- co-owner, not a trader, needs truth fast. Trigger: Phone buzzes with a Discord alert, or OpB just wants to check in. Time budget: 30 seconds from unlock to confidence.
What OpB Sees
A single mobile-optimized screen with 5 numbers:
| Metric | Source | Format | Color Rule |
|---|---|---|---|
| Equity | Broker API | $XXX,XXX.XX |
Green if up today, red if down |
| Daily PnL | Broker API | +$X,XXX.XX or -$X,XXX.XX |
Green/red |
| Kill-switch status | Risk Manager (Redis) | NORMAL / WARN / THROTTLE / NO_NEW / FLATTEN |
Green/yellow/orange/red/black |
| Open positions | Broker API | Count (e.g., 7 positions) |
Neutral |
| Last heartbeat | Redis stream | 12s ago |
Green if <60s, yellow if <120s, red if >120s |
Below the 5 numbers: a single "FLATTEN ALL" button (requires confirmation tap).
Acceptance Criteria
- [ ] Page loads in <2 seconds on 4G mobile
- [ ] All 5 metrics update without manual refresh (WebSocket or 5s polling)
- [ ] OpB can determine "is everything OK?" without scrolling
- [ ] "FLATTEN ALL" button works and triggers
emergency_flatten()via API - [ ] If API is unreachable, page shows "CONNECTION LOST" in red (not stale data)
- [ ] No financial jargon -- labels are plain English ("Today's Gain/Loss", not "Daily PnL")
Test Script
- Open dashboard on phone
- Verify equity matches Alpaca dashboard (within $1 due to timing)
- Trigger a
WARNtier escalation; verify dashboard turns yellow within 10 seconds - Kill the daemon process; verify heartbeat turns red within 2 minutes
- Tap "FLATTEN ALL"; verify confirmation dialog appears; confirm; verify positions closed
Journey 2: OpA 5-Minute Sunday Night Screen
Persona: OpA -- systematic-risk background, limited evening/weekend hours, values correctness. Trigger: Sunday night before the trading week. 5 minutes to assess readiness.
What OpA Reviews
A structured checklist page with pass/fail indicators:
WEEKLY READINESS CHECK
======================
[PASS] Data feeds: 6/6 healthy (FRED, Alpaca, CFTC, LBMA, EIA, OpenBB)
[PASS] Kill-switch: NORMAL (no escalation this week)
[PASS] Reconciliation: 0 critical discrepancies in last 7 days
[PASS] Heartbeat: 14,400 beats, 0 gaps > 60s
[WARN] Strategy decay: real_rate_gold 6m Sharpe = 0.42 (below 0.5 threshold)
[PASS] Audit chain: 1,247 entries, integrity verified
[PASS] Disk/memory: 42% disk, 3.1 GB RAM
WEEK AHEAD
==========
- Monday: EIA report @ 10:30 ET (inventory_surprise strategy active)
- Wednesday: FOMC minutes @ 14:00 ET (no auto-trading during release)
- Friday: COT data release (cot_positioning strategy will update)
LAST WEEK SUMMARY
=================
- Weekly PnL: +$1,234.56 (+0.62%)
- Trades executed: 14 (12 filled, 2 rejected by risk)
- Max drawdown: 0.8% (limit: 3.0%)
- Best strategy: tsmom (+0.4%)
- Worst strategy: gold_silver_ratio (-0.1%)
Acceptance Criteria
- [ ] Page loads in <3 seconds
- [ ] All data is live (not cached from Friday)
- [ ] Strategy decay warnings are highlighted when any strategy's 6m Sharpe drops below 50% of in-sample
- [ ] "Week Ahead" section auto-populates from known economic calendar
- [ ] OpA can drill into any metric by clicking (detail view, not a separate page)
- [ ] Weekly PnL matches sum of daily PnL from broker
- [ ] Page works in dark mode (OpA reviews at night)
Test Script
- Open readiness page on laptop (Sunday evening)
- Verify all data feed statuses are current (last fetch < 24 hours)
- Check that kill-switch state matches Redis
- Verify weekly PnL against Alpaca account history
- Trigger a simulated reconciliation discrepancy; verify it shows as
[FAIL] - Verify strategy decay alert appears for any strategy below threshold
Journey 3: Weekly Auto-Digest (Email/Discord)
Persona: Both operators. Trigger: Automated, fires every Sunday at 18:00 ET. Time budget: 60-second read.
Digest Content
QGTM Weekly Digest -- Week of Apr 6-12, 2026
=============================================
PORTFOLIO: $158,234.56 (+$1,234.56 / +0.79%)
Kill-switch: NORMAL all week
Positions: 7 open (5 long, 2 short)
Max intraday drawdown: 0.8% (Mon)
STRATEGIES (ranked by contribution):
1. tsmom +$523.12 (6 trades, 83% hit rate)
2. xsmom +$312.45 (4 trades, 75% hit rate)
3. vol_risk_parity +$198.99 (2 trades, 100% hit rate)
4. gold_silver_ratio -$89.00 (2 trades, 0% hit rate)
RISK EVENTS: None
DATA QUALITY:
- FRED: 100% (all series updated)
- COT: 100% (Friday release received)
- Alpaca: 99.8% (2 bars missing for SLV on Tue)
SYSTEM HEALTH:
- Uptime: 100%
- Heartbeat gaps > 60s: 0
- Audit chain: verified, 312 new entries
Next week: FOMC minutes Wed, Quad witching Fri
Acceptance Criteria
- [ ] Digest fires automatically without manual trigger
- [ ] Sent to both Discord webhook and email (if configured)
- [ ] All numbers match the data seen in the Sunday night screen
- [ ] Strategy contribution sums to total weekly PnL (within rounding)
- [ ] If digest generation fails, an alert is sent instead of silence
- [ ] Digest includes a direct link to the full dashboard
Test Script
- Trigger manual digest generation via CLI or API
- Verify output matches live broker data
- Verify Discord webhook receives the digest
- Simulate a strategy with zero trades; verify it shows as "0 trades, N/A hit rate"
- Simulate a week with a kill-switch event; verify it appears under RISK EVENTS
Journey 4: Engineer Onboarding (1 Week)
Persona: New engineer joining the team. Trigger: First day on the project. Time budget: 5 working days to productive contribution.
Day-by-Day Plan
Day 1: Understand
- [ ] Read DESIGN_PRINCIPLES.md (15 min)
- [ ] Read STRUCTURE_AUDIT.md (30 min)
- [ ] Read STRUCTURE_TARGET.md (30 min)
- [ ] Clone repo, run make setup (installs venv, pre-commit hooks, test data)
- [ ] Run pytest -- all tests pass
- [ ] Run mkdocs serve -- browse the doc site
Day 2: Explore
- [ ] Read qgtm_core/types.py and qgtm_core/config.py
- [ ] Read qgtm_strategies/base.py and one strategy (e.g., tsmom.py)
- [ ] Read qgtm_execution/oms.py -- understand signal-to-order flow
- [ ] Read qgtm_risk/manager.py -- understand kill-switch tiers
- [ ] Run one backtest: python -m qgtm_backtest.runner --strategy tsmom
Day 3: Trace - [ ] Follow a signal through the system: strategy -> OMS -> broker -> audit log - [ ] Find the correlation ID for a specific order in structlog output - [ ] Find the same event in the audit log JSONL file - [ ] Identify the OTel trace for the same signal cycle
Day 4: Modify - [ ] Add a parameter to an existing strategy (e.g., change lookback window) - [ ] Write a test for the change - [ ] Run the backtest with the modified parameter - [ ] Submit a PR; verify CODEOWNERS triggers the right reviewer
Day 5: Ship
- [ ] Add a new API endpoint (e.g., /api/v1/strategies/{id}/performance)
- [ ] Write integration test
- [ ] Deploy to paper environment
- [ ] Verify endpoint returns correct data from paper account
Acceptance Criteria
- [ ] Engineer can independently run backtests by end of Day 2
- [ ] Engineer can trace a signal end-to-end by end of Day 3
- [ ] Engineer can submit a working PR by end of Day 4
- [ ] Engineer can deploy to paper by end of Day 5
- [ ] No tribal knowledge required -- all steps are documented
Test Script
Give the onboarding guide to a developer unfamiliar with the codebase. Time each day. Identify any step that requires asking a question not answered by docs.
Journey 5: Auditor Visit (1 Day)
Persona: External compliance auditor. Trigger: Annual audit or regulatory inquiry. Time budget: 1 business day to complete review.
Hour-by-Hour Plan
Hour 1-2: Risk Controls Inventory
- Review kill-switch tiers and escalation logic in qgtm_risk/manager.py
- Verify two-person reset requirement (approver parameter in reset_kill_switch())
- Review position limits (RiskLimits in qgtm_core/types.py)
- Check pre-trade risk checks in check_signal() and check_order()
- Evidence: kill-switch history log, risk limit configuration
Hour 3-4: Audit Trail Verification
- Run audit.verify_chain() on the production audit log
- Verify Merkle chain integrity (SHA-256 hashing, no gaps)
- Sample 10 random entries and trace them to broker records
- Verify S3 Object Lock compliance mode is enabled
- Evidence: chain verification output, S3 bucket policy
Hour 5-6: Data Lineage
- Review PIT join enforcement (qgtm_data/pit.py)
- Verify COT report lag is correctly applied (constants.py:54)
- Trace a feature from raw data source to strategy signal
- Review backtest methodology (walk-forward, PBO, deflated Sharpe)
- Evidence: PIT join code, backtest result with PBO probability
Hour 7-8: Governance
- Review CODEOWNERS for risk-critical path coverage
- Verify branch protection rules (2-person review on risk paths)
- Review change log for recent risk-critical changes
- Check that DESIGN_PRINCIPLES.md exists and is current
- Evidence: GitHub branch protection settings, recent PR reviews
Acceptance Criteria
- [ ] Auditor can verify Merkle chain integrity in <5 minutes (single command)
- [ ] Auditor can trace any order from signal to fill in <10 minutes
- [ ] All risk limits are documented and match the running configuration
- [ ] S3 Object Lock compliance mode is verifiable
- [ ] Auditor receives a pre-prepared evidence package (not ad-hoc exports)
- [ ] No data access requires production SSH -- everything available via API or doc site
Pre-Visit Package
Prepare before the auditor arrives:
audit_chain_verification.txt-- output ofverify_chain()with entry count and hashrisk_limits_config.json-- currentRiskLimitsserializedkill_switch_history.json-- last 12 months of tier changescodeowners_audit.txt-- list of risk-critical files and their reviewersbacktest_methodology.pdf-- walk-forward, PBO, deflated Sharpe explanations3_bucket_policy.json-- Object Lock configuration proof