← All findingssource · memory/project_debate_persona_lockdown.md
The actual production pick chain (corrected mental model after the user pointed out my earlier description was wrong):
sport-data-service (data SoT)
↑ ↑
│ │
sports-scout-service data-hydrator
(own collectors; (assembler + FIX 1-5 lockdown)
ML pick generation) │
│ │
└────────────────┐ │
↓ ↓
snapshot.scout.player_props
(picks from scout, surfaced by hydrator)
│
↓
debate-service-v2 orchestrator
- extractPropsFromSnapshot
- lockdown pre-filter (drops Out/Doubtful/Questionable)
- AnalyzeProps → sport-agents /analyze
│
↓
sport-agents /api/v1/analyze (multi-persona)
- Koerner (Projection Modeler) ─┐
- Levitan (Sharp Process) ├─ each reads
- Raybon (Stat Hunter) │ Lockdown signals
- (judge synthesizer) ─┘ per pick
│
↓
verdicts → UI
Two corrections to the earlier mental model:
-
sports-scout-service does NOT call data-hydrator. They are PARALLEL SDS consumers. sports-scout-service has its own collectors (sport_data_service_client.py, injury_collector, roster_collector, etc.) and runs its own ML pipeline. data-hydrator pulls sports-scout-service's outputs (likely via ml-scout-service) and includes them as
snap.scout.player_props. -
sport-agents /analyze is MULTI-PERSONA. Three analyst personas (Koerner: projection modeler / Levitan: sharp process / Raybon: stat hunter) + judge synthesizer. Each persona has its own system prompt + methodology and emits AGREE/DISAGREE + confidence
- reasoning. Judge synthesizes into final verdict.
What shipped (2 commits, end-to-end)
sport-agents commit e7be3cf
api/server.py:Pick.prop_diagnostic: Optional[dict]field.core/debate_engine.py: per-pick prompt block renders a**Lockdown signals**section showing:active_status(informational — drops happen upstream in debate-v2)recent_vs_baseline_flagwhen not stable (with season_avg)role_anchor_adjustedwhen true (with current vs historical minutes)minutes_source_confidencewhen not stable (especiallydiverge_low_confidence)- line_edges entry for the pick's exact line (quality + z-score) Each signal only rendered when its value is non-default so noise stays low for clean players.
debate-v2 commit d7525b2
internal/sportagents/client.go:Pick.PropDiagnostic(json.RawMessage).AnalyzePropssignature gainspropDiagnostics map[string]json.RawMessage(player_id → raw diagnostic, same pattern asplayerMemory).- Per-pick attachment in the conversion loop.
internal/orchestrator/orchestrator.go:buildPropDiagnosticMap(snap)walkssnap.Players.Players[*].PropDiagnosticinto the map.- Phase 5 call passes the map.
Why each persona interprets differently (sport-agents prompt design)
Each persona's existing system prompt reflects their methodology. The Lockdown signals are presented as DATA (not commandments), so each persona reads them through their lens:
- Koerner (proprietary projection models, regression analysis,
historical baselines): heavily weights
role_anchor_adjusted+recent_vs_baseline_flag— these touch projection drift. - Levitan (sharp process, market edge, line analysis): weighs
line_edges.qualityandline_z_score— these speak to his mean-relative-edge thinking. He'll DISAGREE strongly on ano_edgequality line. - Raybon (situational splits, rate-based metrics): weighs
minutes_source_confidence+ recency signals — these align with his split-aware analysis.
The judge sees all persona verdicts AND has the same lockdown context
(via the picks_dicts passed through to run_judge), so it can
arbitrate based on which persona's reasoning best matches the
lockdown signals.
What's still NOT in this chain
- sports-scout-service still doesn't read prop_diagnostic. Its ML models can emit picks that violate lockdown gates (the picks reaching debate-v2 are filtered, but the ML pipeline itself is unchanged). Making sports-scout-service lockdown-aware would reduce wasted compute (don't generate picks that get dropped) but isn't required for production-pick correctness — the filter + debate gates handle it.
line_edgesno_edgequality is currently INFORMATIONAL in the debate prompt (personas see it; can ignore it). debate-v2's pre-filter only drops active-status violations. A separate follow-up could also dropno_edge-only picks before debate.
See also: project_methodology_lockdown (FIX 1-4 origin), feedback_active_tonight_gate (FIX 5), project_wnba_lockdown_live (data-layer end-to-end for WNBA), project_wnba_sport_agents_playbook (WNBA picker adapter).