Add full multi-step decision workflow for SINGLE_UNCAPPED and DOUBLE_UNCAPPED
outcomes, replacing the previous stub that fell through to basic single/double
advancement. The decision tree follows the same interactive pattern as X-Check
resolution with 5 phases: lead runner advance, defensive throw, trail runner
advance, throw target selection, and safe/out speed check.
- game_models.py: PendingUncappedHit model, 5 new decision phases
- game_engine.py: initiate_uncapped_hit(), 5 submit methods, 3 result builders
- handlers.py: 5 new WebSocket event handlers
- ai_opponent.py: 5 AI decision stubs (conservative defaults)
- play_resolver.py: Updated TODO comments for fallback paths
- 80 new backend tests (2481 total): workflow (49), handlers (23), truth tables (8)
- Fix GameplayPanel.spec.ts: add missing Pinia setup, fix component references
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix critical encoding mismatch where calculate_on_base_code() returned
bit-field encoding (3=R1+R2, 4=R3) but runner_advancement.py charts
expected sequential encoding (3=R3, 4=R1+R2). Values 3 and 4 were
swapped, causing wrong groundball results for R1+R2 and R3-only scenarios.
Add comprehensive test coverage:
- 1184 invariant tests (structural correctness across all outcomes × base codes)
- 49 hit truth table tests (SINGLE_1/2, DOUBLE_2/3, TRIPLE, HOMERUN)
- 33 walk truth table tests (WALK, HBP with stat flag verification)
- 42 simple out truth table tests (STRIKEOUT, LINEOUT, POPOUT, WP, PB)
- 88 groundball truth table tests (GB_A/B/C × infield back/in/corners_in × locations)
Total: 2401 unit tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runner highlights and cards:
- Pills: red-500 ring, red-50 background when selected
- Full cards: red gradient (red-900 to red-950), red-600 border
- Pulse glow: red animation (rgba(239, 68, 68))
- Hardcoded red color (#ef4444) for runner pill borders
Catcher highlights and cards:
- Pill: blue-500 ring, blue-50 background when selected
- Full card: blue gradient (blue-900 to blue-950), blue-600 border
- Pulse glow: blue animation (rgba(59, 130, 246))
Updated tests to expect new colors
All 15 RunnersOnBase tests passing
All 16 RunnerCard tests passing
- When catcher pill is clicked, display lead runner (3B > 2B > 1B priority) + catcher side-by-side
- Maintains consistent layout whether runner or catcher is selected
- Add leadRunnerBase computed to find highest priority runner
- Add displayedRunnerBase computed to show selected OR lead runner
- Update template to use displayedRunnerPlayer for consistent rendering
All 15 RunnersOnBase tests passing
- Swap base order to 3B, 2B, 1B (left to right, closer to baseball diamond)
- Auto-select lead runner on mount (priority: 3B > 2B > 1B)
- Make catcher pill clickable to show catcher card only
- Add 'catcher' as a selection option alongside runner bases
- Update expanded view to handle catcher-only display (centered, single card)
- Add toggleCatcher() function
- Update tests for new base order and auto-selection behavior
All 15 RunnersOnBase tests passing
All 16 RunnerCard tests passing
- Replace .border-l-4.border-gray-600 checks with .catcher-pill
- Update isExpanded prop references to isSelected
- Adjust expanded view tests for new side-by-side layout
- matchup-card-blue = runner full card
- matchup-card = catcher full card
- Fix deselection test to check isSelected prop (Transition keeps DOM during animation)
All 15 RunnersOnBase tests passing
All 16 RunnerCard tests passing
Backend changes:
- Add PendingXCheck model for interactive x-check state
- Extend decision_phase/pending_decision validators with 4 new phases
- Add initiate_x_check() to roll dice and present chart to player
- Add submit_x_check_result() to process player selection
- Add resolve_x_check_from_selection() to resolve from player input
- Add WebSocket handlers for x-check workflow
- Modify resolve_manual_play() to route X_CHECK to interactive flow
- All 986 unit tests passing
Frontend changes:
- Extend DecisionPhase type with x-check/DECIDE phases
- Add XCheckData, DecideAdvanceData, DecideThrowData, DecideSpeedCheckData interfaces
- Add PendingXCheck to GameState
- Add 4 new client→server WebSocket events
Next: Implement XCheckWizard component and GameplayPanel integration
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>