strat-gameplay-webapp/.claude/implementation/NEXT_SESSION.md
Cal Corum 69782f54c9 CLAUDE: Update NEXT_SESSION.md with latest commit hash
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 22:53:19 -05:00

761 lines
30 KiB
Markdown

# Next Session Plan - Phase 3 Week 7 in Progress
**Current Status**: Phase 3 - Week 7 (~62% Complete)
**Last Commit**: `9cae63a` - "CLAUDE: Implement Week 7 Task 7 - WebSocket manual outcome handlers"
**Date**: 2025-10-30
**Remaining Work**: 38% (3 of 8 tasks remaining, Task 7 complete!)
---
## Quick Start for Next AI Agent
### 🎯 Where to Begin
1. Read this entire document first
2. Review `@.claude/implementation/WEEK_7_PLAN.md` for comprehensive task details
3. Start with **Task 4: Runner Advancement Logic** (next logical step)
4. Run tests after each change: `export PYTHONPATH=. && pytest tests/unit/config/ -v`
### 📍 Current Context
**Week 7 Tasks 1-3 and 7 are complete!**
- **Task 1**: Async decision workflow with asyncio Futures ✅
- **Task 2**: Defensive/offensive decision validators with 54 tests passing ✅
- **Task 3**: Result chart abstraction + PD auto mode with 21 tests passing ✅
- **Task 7**: WebSocket manual outcome handlers with 12 tests passing ✅
**Next up**: Implement runner advancement logic (Task 4)! This is the CRITICAL component that uses hit locations from Task 3 to determine where runners go based on outcome + game situation (Infield In/Back charts, tag-ups, force plays, etc.). This is where the advancement charts from the user images come into play.
**Note**: Task 7 completed out of order because Task 4 requires advancement chart images from user.
**IMPORTANT CONTEXT**: In this session, we clarified major architectural points:
- **Manual Mode (SBA + PD manual)**:
- Server rolls dice for fairness and auditing (NOT players!)
- Players read PHYSICAL cards based on server dice
- Players submit outcomes via WebSocket
- System validates and processes with server-rolled dice
- **PD Auto Mode**: System uses digitized ratings to auto-generate outcomes for faster/AI play. This is NEW functionality enabling AI vs AI games.
- **Decision Modifiers**: Do NOT change the base outcome (GROUNDBALL_C stays GROUNDBALL_C). They affect RUNNER ADVANCEMENT based on hit location and defensive positioning.
---
## What We Just Completed ✅
### 1. Validator Bug Fixes (Commit `c0051d2`)
- **File**: `app/core/validators.py`
- **Issue**: Validator checking wrong on_base_codes for "runner on third"
- **Fix**: Updated to use `state.is_runner_on_third()` helper method
- **Changes**:
- Fixed infield depth validation (corners_in/infield_in require runner on third)
- Updated DefensiveDecision Pydantic model: infield depths `['infield_in', 'normal', 'corners_in']`
- Updated DefensiveDecision Pydantic model: outfield depths `['in', 'normal']` (removed 'back')
- Removed 4 invalid double_play depth tests (depth doesn't exist)
- Added 4 proper corners_in/infield_in tests
- **Testing**: All 54 validator tests passing ✅
- **Impact**: Validators now correctly check game state using helper methods
### 2. Result Chart Abstraction & PD Auto Mode (Commit `9245b4e`) - Week 7 Task 3
- **Files**:
- `app/config/result_charts.py` (+400 lines)
- `app/models/game_models.py` (+55 lines)
- `tests/unit/config/test_result_charts.py` (+492 lines, NEW)
- **Core Implementation**:
- **ResultChart abstract base class**: Defines `get_outcome(roll, state, batter, pitcher) -> tuple[outcome, location]`
- **calculate_hit_location() helper**:
- 45% pull, 35% center, 20% opposite field distribution
- RHB pulls left (3B, SS, LF), LHB pulls right (1B, 2B, RF)
- Groundballs → infield positions (1B, 2B, SS, 3B, P, C)
- Flyouts → outfield positions (LF, CF, RF)
- **PlayOutcome.requires_hit_location()**: Returns True for groundballs and flyouts only
- **Manual Mode Support**:
- **ManualResultChart**: Passthrough class (raises NotImplementedError)
- Manual mode doesn't use result charts - players submit via WebSocket
- **ManualOutcomeSubmission model**: Validates PlayOutcome enum + hit location
- Validates outcome is valid PlayOutcome value
- Validates hit location in ['1B', '2B', 'SS', '3B', 'LF', 'CF', 'RF', 'P', 'C']
- Location is optional (only needed for certain outcomes)
- **PD Auto Mode Implementation**:
- **PdAutoResultChart**: Full auto-generation for PD games
- `_select_card()`: Coin flip (50/50) to choose batting or pitching card
- `_build_distribution()`: Creates cumulative distribution from rating percentages
- `_select_outcome()`: Rolls 1d100 to select outcome from distribution
- Maps rating fields to PlayOutcome enum:
- Common: homerun, triple, doubles, singles, walks, strikeouts
- Batting-specific: lineouts, popouts, flyout variants, groundout variants
- Pitching-specific: uncapped singles/doubles (SINGLE_UNCAPPED, DOUBLE_UNCAPPED)
- Calculates hit location using handedness and pull rates
- Proper error handling when card data missing
- **Testing**: 21 comprehensive unit tests (all passing ✅)
- Helper function tests (calculate_hit_location)
- PlayOutcome helper tests (requires_hit_location)
- ManualResultChart tests (NotImplementedError)
- PdAutoResultChart tests:
- Coin flip distribution (~50/50 over 1000 trials)
- Handedness matchup selection
- Cumulative distribution building
- Outcome selection from probabilities
- Hit location calculation for groundballs
- Error handling for missing cards
- Statistical distribution verification
- ManualOutcomeSubmission validation tests
- **Impact**:
- ✅ Foundation for both manual and auto play modes
- ✅ Hit locations ready for Task 4 runner advancement
- ✅ PD auto mode enables AI vs AI games
- ⏳ Integration with PlayResolver deferred (Phase 6)
- ⏳ Terminal client manual outcome command deferred (Phase 8)
### 3. WebSocket Manual Outcome Handlers (Current Session) - Week 7 Task 7
- **Files**:
- `app/websocket/handlers.py` (+240 lines - 2 new event handlers)
- `app/core/game_engine.py` (+147 lines - resolve_manual_play method)
- `app/models/game_models.py` (+1 line - pending_manual_roll field)
- `terminal_client/commands.py` (+128 lines - roll_manual_dice, submit_manual_outcome)
- `terminal_client/repl.py` (updated do_roll_dice, do_manual_outcome)
- `tests/unit/websocket/test_manual_outcome_handlers.py` (+432 lines, NEW)
- **Core Implementation**:
- **roll_dice WebSocket Handler**:
- Server rolls dice using dice_system.roll_ab()
- Stores ab_roll in state.pending_manual_roll
- Broadcasts dice results to all players in game room
- Events: `dice_rolled` (broadcast), `error` (validation failures)
- **submit_manual_outcome WebSocket Handler**:
- Validates ManualOutcomeSubmission model (outcome + optional location)
- Checks for pending_manual_roll (prevents submission without roll)
- Validates hit_location required for groundballs/flyouts
- Calls game_engine.resolve_manual_play() to process
- Events: `outcome_accepted`, `outcome_rejected`, `play_resolved`, `error`
- **GameEngine.resolve_manual_play()**:
- Accepts server-rolled ab_roll for audit trail
- Uses player-submitted outcome for resolution
- Validates hit_location when required
- Same orchestration as resolve_play() (save, update, advance inning)
- Tracks rolls for batch saving at inning boundaries
- **Terminal Client Commands**:
- `roll_dice` - Roll dice and display results
- `manual_outcome <outcome> [location]` - Submit manual outcome
- Both integrated into REPL for testing
- **Testing**: 12 comprehensive unit tests (all passing ✅)
- roll_dice tests (4):
- Successful roll and broadcast
- Missing game_id validation
- Invalid game_id format validation
- Game not found error handling
- submit_manual_outcome tests (8):
- Successful submission and play resolution
- Missing game_id validation
- Missing outcome validation
- Invalid outcome value validation
- Invalid hit_location validation
- Missing required hit_location validation
- No pending roll error handling
- Walk without location (valid case)
- **Key Architectural Decisions**:
- **Server rolls dice for fairness**: Clarified with user - server generates dice, stores for audit, players read cards
- **One-time roll usage**: pending_manual_roll cleared after submission to prevent reuse
- **Early validation**: Check for pending roll BEFORE emitting outcome_accepted
- **Comprehensive error handling**: Field-level error messages for clear user feedback
- **Impact**:
- ✅ Complete manual outcome workflow implemented
- ✅ WebSocket handlers ready for frontend integration
- ✅ Terminal client testing commands available
- ✅ Audit trail maintained with server-rolled dice
- ✅ Foundation for SBA and PD manual mode gameplay
---
## Key Architecture Decisions Made
### 1. **Manual vs Auto Mode Clarification**
**Decision**: Manual mode doesn't use result charts at all - humans submit outcomes directly
**Rationale**:
- SBA and PD manual games use physical cards that aren't digitized (SBA) or optional digitization (PD)
- Players roll dice, read their card, and tell system the outcome + location via WebSocket
- Result charts only used for PD auto mode where we need to generate outcomes
**Impact**:
- Simpler architecture - no "manual result chart" logic needed
- ManualResultChart exists only for interface completeness (raises NotImplementedError)
- WebSocket handlers will receive ManualOutcomeSubmission objects
- PdAutoResultChart is truly optional - only for auto mode
### 2. **Decision Modifiers Affect Advancement, Not Outcomes**
**Decision**: Defensive decisions don't change the PlayOutcome - they change runner advancement
**Rationale**:
- User provided advancement charts showing different runner movements for same outcome
- GROUNDBALL_C stays GROUNDBALL_C whether infield is "in", "back", or "normal"
- The HIT LOCATION + DEFENSIVE POSITIONING determine advancement (Infield In/Back charts)
- Example: GROUNDBALL_C to SS with "corners_in" = different advancement than "normal" depth
**Impact**:
- Task 3 (this session) focused on outcome selection + hit location calculation
- Task 4 (next) implements advancement logic using hit locations from Task 3
- SimplifiedResultChart in play_resolver.py remains untouched (no breaking changes)
- Original Week 7 plan overestimated decision modifier complexity
### 3. **Hit Location is Critical, Not Just Informational**
**Decision**: Track precise hit location (1B, 2B, SS, 3B, LF, CF, RF, P, C) for every groundball/flyout
**Rationale**:
- User's advancement charts show different rules for different fielders
- "Corners in" only affects plays hit to 1B, 3B, P, or C (not 2B/SS)
- Hit location determines which advancement chart row to use
- Tag-up logic for flyouts depends on location (deep fly vs shallow)
**Impact**:
- calculate_hit_location() must be accurate with proper pull rates
- ManualOutcomeSubmission requires location for groundballs/flyouts
- Task 4 will use location extensively in advancement logic
- Future: Could add fielder ratings affecting outcomes
### 4. **On-Base Code is Enumeration, Not Bit Field**
**Decision**: current_on_base_code is 0-7 enumeration, not bit-field addition
**Clarification** (from user):
- 0: empty
- 1: on first
- 2: on second
- 3: on third
- 4: first and second
- 5: first and third
- 6: second and third
- 7: bases loaded
**Impact**:
- Fixed validator bug checking wrong codes for "runner on third"
- Code should use helper methods (`is_runner_on_first()`) instead of hardcoding
- Documentation updated with correct enumeration values
---
## Blockers Encountered 🚧
### 1. **PYTHONPATH Required for Tests**
**Issue**: Tests fail with `ModuleNotFoundError: No module named 'app'` without PYTHONPATH set
**Workaround**: Run tests with `export PYTHONPATH=. && pytest ...`
**Status**: ⚠️ Need to investigate why PYTHONPATH isn't set automatically by pytest.ini
**TODO**: Add PYTHONPATH configuration to pytest.ini or add __init__.py files to fix imports
---
## Outstanding Questions ❓
### 1. **Legacy Bot Code Review Timing**
**Question**: When should we review `../paper-dynasty/discord-app/in_game/` for advancement logic?
**Context**: User mentioned legacy bot has dozens of advancement scenarios coded. We should NOT reuse the code (not optimized) but the LOGIC is valuable.
**Recommendation**: Review before starting Task 4 to understand all edge cases (TOOTBLAN, FARTSLAM, DECIDE mechanics from user's images).
### 2. **WebSocket Event Names for Manual Submissions**
**Question**: What events should manual mode use?
**Context**: Need events for:
- Rolling dice and presenting to players
- Players submitting ManualOutcomeSubmission
- Validating submission
- Broadcasting result
**Proposed Names**:
- `roll_dice` - Server rolls dice and broadcasts to players
- `submit_manual_outcome` - Player sends ManualOutcomeSubmission
- `outcome_accepted` - Server confirms valid outcome
- `outcome_rejected` - Server rejects invalid outcome (validation error)
**Recommendation**: Define in Task 6 (WebSocket Handlers).
### 3. **Terminal Client Testing Without Frontend**
**Question**: How to test manual outcome submission flow without WebSocket?
**Context**: Terminal client currently uses game engine directly. Manual mode flow goes through WebSocket.
**Options**:
- A) Add `manual_outcome` command that simulates WebSocket submission
- B) Skip terminal client manual mode testing until WebSocket handlers done
- C) Add test-only bypass in game engine for manual outcomes
**Recommendation**: Option A - add `manual_outcome` command in Task 8 (Terminal Client Enhancement).
---
## Tasks for Next Session
### Task 4: Runner Advancement Logic (6-8 hours) - **HIGH PRIORITY**
**Files**:
- `app/core/runner_advancement.py` (NEW)
- `app/core/play_resolver.py` (integrate)
- `tests/unit/core/test_runner_advancement.py` (NEW)
**Goal**: Implement complete runner advancement logic using hit locations and game situation
**Changes**:
1. **Create `RunnerAdvancement` class**:
- `advance_runners(outcome, hit_location, state, defensive_decision) -> dict`
- Returns movements: `{runner_id: {from_base: int, to_base: int, is_out: bool}}`
2. **Implement Infield Back advancement** (user's first image):
- Normal advancement for standard plays
- Special rules for GROUNDBALL_C based on base situation
3. **Implement Infield In advancement** (user's second image):
- Runner on 3rd scores on contact (GROUNDBALL_C)
- Lead runner advancement based on hit location
- TOOTBLAN mechanic (pick-off at third attempt)
- FARTSLAM mechanic (runner tries to score on grounder)
- DECIDE mechanic (lead runner can attempt advance)
4. **Implement tag-up logic for flyouts**:
- Shallow flies: no advancement
- Medium flies: R3 can tag
- Deep flies: R3 tags, R2 can advance
5. **Force play detection**:
- Runner must advance if forced
- Used in advancement calculations
**Files to Update**:
- `app/core/runner_advancement.py` - NEW file with RunnerAdvancement class
- `app/core/play_resolver.py` - Integration point (call RunnerAdvancement)
- `tests/unit/core/test_runner_advancement.py` - NEW, ~30 test cases
**Test Command**:
```bash
export PYTHONPATH=. && pytest tests/unit/core/test_runner_advancement.py -v
```
**Acceptance Criteria**:
- [ ] RunnerAdvancement.advance_runners() returns correct movements dict
- [ ] Infield Back chart implemented (all 9 base situations from user image)
- [ ] Infield In chart implemented (all variations from user image)
- [ ] TOOTBLAN mechanic implemented (d20 roll for pick-off attempt)
- [ ] FARTSLAM mechanic implemented (d20 roll for safe range)
- [ ] DECIDE mechanic implemented (offense chooses advancement)
- [ ] Tag-up logic for flyouts (R3 on deep fly, etc.)
- [ ] Force play detection works correctly
- [ ] Hit location affects advancement (1B/3B/P/C for corners_in)
- [ ] 30+ test cases covering all scenarios
- [ ] Integration with play_resolver works
**IMPORTANT**: Review `../paper-dynasty/discord-app/in_game/` before starting to understand all edge cases!
---
### Task 5: Double Play Mechanics (2-3 hours)
**Files**:
- `app/core/play_resolver.py` (enhance)
- `tests/unit/core/test_play_resolver.py` (add tests)
**Goal**: Implement double play resolution for GROUNDBALL_A outcomes
**Changes**:
1. Add `_resolve_double_play_attempt()` method
2. Calculate DP probability based on:
- Base probability: 45%
- Positioning modifiers (DP depth +20%, infield in -15%)
- Hit location modifiers (up middle +10%, corners -10%)
- Runner speed modifiers (fast -15%, slow +10%)
3. Return (outs_recorded, [runner_ids_out])
4. Integrate with `_resolve_outcome()` for GROUNDBALL_A
**Files to Update**:
- `app/core/play_resolver.py` - Add DP resolution
- `tests/unit/core/test_play_resolver.py` - Add ~10 DP tests
**Test Command**:
```bash
export PYTHONPATH=. && pytest tests/unit/core/test_play_resolver.py::test_double_play -v
```
**Acceptance Criteria**:
- [ ] Base DP probability: 45%
- [ ] Positioning modifiers work correctly
- [ ] Hit location modifiers work correctly
- [ ] Runner speed considered (need player speed data)
- [ ] Returns correct outs_recorded
- [ ] Returns correct runner_ids_out list
- [ ] Terminal client shows "DP" in description
- [ ] 10+ test cases for various scenarios
---
### Task 6: PlayResolver Integration (3-4 hours)
**Files**:
- `app/core/play_resolver.py` (major refactor)
- `app/core/game_engine.py` (update calls)
**Goal**: Integrate result charts and runner advancement into play resolution
**Changes**:
1. Add `league_id` and `auto_mode` params to PlayResolver.__init__()
2. Create PdAutoResultChart for PD auto mode
3. Update resolve_play() to use result chart when in auto mode
4. Integrate RunnerAdvancement for all plays
5. Store hit_location in play results
6. Update all callers (game_engine, terminal_client)
**Files to Update**:
- `app/core/play_resolver.py` - Major refactor
- `app/core/game_engine.py` - Update resolve_play calls
- `tests/unit/core/test_play_resolver.py` - Update existing tests
- `terminal_client/commands.py` - Update for auto mode support
**Test Command**:
```bash
export PYTHONPATH=. && pytest tests/unit/core/test_play_resolver.py -v
```
**Acceptance Criteria**:
- [ ] PlayResolver accepts league_id and auto_mode params
- [ ] PD auto mode uses PdAutoResultChart
- [ ] Manual mode bypasses result charts (expects ManualOutcomeSubmission)
- [ ] RunnerAdvancement called for all outcomes
- [ ] Hit location stored in play results
- [ ] All existing tests pass (no regressions)
- [ ] Terminal client works with both modes
---
### Task 7: WebSocket Handlers for Manual Submissions (3-4 hours)
**Files**:
- `app/websocket/handlers.py` (add handlers)
- `tests/unit/websocket/test_manual_outcome_handlers.py` (NEW)
**Goal**: Create WebSocket event handlers for manual outcome submission
**Changes**:
1. Add `roll_dice` event handler - Server rolls and broadcasts dice
2. Add `submit_manual_outcome` event handler - Validates ManualOutcomeSubmission
3. Validate outcome is valid PlayOutcome
4. Validate location provided when required
5. Call play_resolver with manual outcome
6. Broadcast result to game room
**Files to Update**:
- `app/websocket/handlers.py` - Add manual outcome handlers
- `app/websocket/events.py` - Define event names (if doesn't exist)
- `tests/unit/websocket/test_manual_outcome_handlers.py` - NEW, ~15 tests
**Test Command**:
```bash
export PYTHONPATH=. && pytest tests/unit/websocket/test_manual_outcome_handlers.py -v
```
**Acceptance Criteria**:
- [ ] `roll_dice` handler rolls dice and broadcasts to players
- [ ] `submit_manual_outcome` validates ManualOutcomeSubmission
- [ ] Validates outcome is valid PlayOutcome enum value
- [ ] Validates location provided for groundballs/flyouts
- [ ] Rejects invalid outcomes with clear error
- [ ] Calls play_resolver with manual outcome
- [ ] Broadcasts result to game room
- [ ] 15+ test cases for all scenarios
- [ ] Error handling with clear messages
---
### Task 8: Terminal Client Enhancement (2-3 hours)
**Files**:
- `terminal_client/commands.py` (add command)
- `terminal_client/help_text.py` (update docs)
- `terminal_client/completions.py` (add completions)
**Goal**: Add `manual_outcome` command for testing manual submission flow
**Changes**:
1. Add `manual_outcome <outcome> [location]` command
2. Validates outcome is valid PlayOutcome
3. Validates location if required
4. Simulates manual submission (bypasses WebSocket for testing)
5. Add TAB completion for outcome names
6. Update help text with examples
**Files to Update**:
- `terminal_client/commands.py` - Add manual_outcome command
- `terminal_client/help_text.py` - Update documentation
- `terminal_client/completions.py` - Add TAB completions
**Test Command**:
```bash
python -m terminal_client
> help manual_outcome
> new_game --league sba
> roll_dice
> manual_outcome groundball_c SS
> status
```
**Acceptance Criteria**:
- [ ] `manual_outcome` command accepts outcome + optional location
- [ ] Validates outcome is valid PlayOutcome
- [ ] Validates location if required (groundballs/flyouts)
- [ ] Simulates manual submission flow
- [ ] TAB completion for outcome names works
- [ ] Help text shows examples
- [ ] Manual testing passes
- [ ] Works alongside auto resolution mode
---
## Files to Review Before Starting
### For Task 4 (Runner Advancement):
1. `../paper-dynasty/discord-app/in_game/` - Legacy bot advancement logic (DO NOT copy code, study LOGIC)
2. User's advancement chart images (already provided - see session context)
3. `app/config/result_charts.py:203-278` - calculate_hit_location() for understanding locations
4. `app/models/game_models.py:247-450` - GameState model for base runner access
5. `app/core/play_resolver.py` - Current resolution logic to integrate with
### For Task 5 (Double Play):
1. `app/core/play_resolver.py` - SimplifiedResultChart.get_outcome() for integration point
2. `app/models/game_models.py` - GameState for runner access
3. `tests/unit/core/test_play_resolver.py` - Existing test patterns
### For Task 6 (Integration):
1. `app/core/play_resolver.py` - Entire file needs refactor
2. `app/core/game_engine.py:300-400` - resolve_play calls
3. `app/config/result_charts.py` - ResultChart interface
4. `tests/unit/core/test_play_resolver.py` - Update all tests
### For Task 7 (WebSocket):
1. `app/websocket/handlers.py` - Existing handler patterns
2. `app/websocket/connection_manager.py` - Broadcasting methods
3. `app/models/game_models.py:192-240` - ManualOutcomeSubmission model
---
## Verification Steps
After each task:
1. **Run unit tests**:
```bash
# After Task 4
export PYTHONPATH=. && pytest tests/unit/core/test_runner_advancement.py -v
# After Task 5
export PYTHONPATH=. && pytest tests/unit/core/test_play_resolver.py -v
# After Task 6
export PYTHONPATH=. && pytest tests/unit/core/ -v
# After Task 7
export PYTHONPATH=. && pytest tests/unit/websocket/ -v
# After Task 8
python -m terminal_client # Manual testing
```
2. **Run all tests** (check for regressions):
```bash
export PYTHONPATH=. && pytest tests/unit/ -v
```
3. **Terminal client testing**:
```bash
python -m terminal_client
> new_game --league pd --auto
> defensive normal normal normal
> offensive normal
> resolve # Auto mode
> new_game --league sba
> roll_dice
> manual_outcome groundball_c SS # Manual mode
> status
```
4. **Commit after each task**:
```bash
git add [modified files]
git commit -m "CLAUDE: Implement Week 7 Task [N] - [Task Name]"
```
---
## Success Criteria
**Week 7** will be **100% complete** when:
- ✅ Task 1: Strategic Decision Integration (DONE)
- ✅ Task 2: Decision Validators (DONE - 54 tests passing)
- ✅ Task 3: Result Charts + PD Auto Mode (DONE - 21 tests passing)
- [ ] Task 4: Runner Advancement Logic (~30 tests passing) - **BLOCKED**: Awaiting advancement chart images from user
- [ ] Task 5: Double Play Mechanics (~10 tests passing)
- [ ] Task 6: PlayResolver Integration (all existing tests still pass)
- ✅ Task 7: WebSocket Manual Outcome Handlers (DONE - 12 tests passing)
- ✅ Task 8: Terminal Client Enhancement (DONE - manual commands working)
- [ ] All 130+ new tests passing (currently 87/130 done - 67%)
- ✅ Terminal client demonstrates both auto and manual modes
- ✅ Documentation updated
- ✅ Git commits for each task
**Week 8** will begin with:
- Substitution system (pinch hitters, defensive replacements)
- Pitching changes (bullpen management)
- Frontend game interface (mobile-first)
---
## Quick Reference
**Current Test Count**: ~489 tests passing
- Config tests: 79/79 ✅ (58 + 21 new from Task 3)
- Validators: 54/54 ✅
- WebSocket handlers: 12/12 ✅ (NEW from Task 7)
- Play resolver tests: 19/19 ✅
- Dice tests: 34/35 (1 pre-existing failure)
- Roll types tests: 27/27 ✅
- Player models: 32/32 ✅
- Game models: ~150+ ✅
- State manager: ~80+ ✅
**Target Test Count After Week 7**: ~550+ tests
**Current Progress**: 489/550 (89%)
**Last Test Run**: All passing except 1 pre-existing (2025-10-30)
**Branch**: `implement-phase-2`
**Python**: 3.13.3
**Virtual Env**: `backend/venv/`
**Database**: PostgreSQL @ 10.10.0.42:5432 (paperdynasty_dev)
**Key Imports for Week 7 Remaining Tasks**:
```python
from app.config import get_league_config, PlayOutcome
from app.config.result_charts import calculate_hit_location, PdAutoResultChart, ManualOutcomeSubmission
from app.core.dice import AbRoll
from app.core.validators import game_validator, ValidationError
from app.core.state_manager import state_manager
from app.core.ai_opponent import ai_opponent
from app.models.game_models import DefensiveDecision, OffensiveDecision, GameState, ManualOutcomeSubmission
```
**Recent Commit History** (Last 10):
```
9245b4e - CLAUDE: Implement Week 7 Task 3 - Result chart abstraction and PD auto mode (53 seconds ago)
c0051d2 - CLAUDE: Fix defensive decision validation for corners_in/infield_in depths (2 hours ago)
f07d8ca - CLAUDE: Update NEXT_SESSION.md - Task 2 complete (6 hours ago)
121a908 - CLAUDE: Implement Week 7 Task 2 - Decision Validators (6 hours ago)
0a21eda - CLAUDE: Update project plan for Week 7 continuation (11 hours ago)
95d8703 - CLAUDE: Implement Week 7 Task 1 - Strategic Decision Integration (15 hours ago)
d7caa75 - CLAUDE: Add manual outcome testing to terminal client and Phase 3 planning (16 hours ago)
6880b6d - CLAUDE: Complete Week 6 - granular PlayOutcome integration and metadata support (16 hours ago)
64aa800 - CLAUDE: Update implementation plans for next session (2 days ago)
5d5c13f - CLAUDE: Implement Week 6 league configuration and play outcome systems (2 days ago)
```
---
## Context for AI Agent Resume
**If the next agent needs to understand the bigger picture**:
- **Overall project**: See `@prd-web-scorecard-1.1.md` and `@CLAUDE.md`
- **Architecture**: See `@.claude/implementation/00-index.md`
- **Backend guide**: See `@backend/CLAUDE.md`
- **Current phase details**: See `@.claude/implementation/03-gameplay-features.md`
- **Week 7 detailed plan**: See `@.claude/implementation/WEEK_7_PLAN.md`
**Critical files for current work (Week 7 Tasks 4-8)**:
1. `app/core/runner_advancement.py` - CREATE for Task 4 (runner advancement logic)
2. `app/core/play_resolver.py` - UPDATE for Tasks 5-6 (DP mechanics + integration)
3. `app/websocket/handlers.py` - UPDATE for Task 7 (manual outcome handlers)
4. `terminal_client/commands.py` - UPDATE for Task 8 (manual outcome command)
5. `app/config/result_charts.py` - REFERENCE for hit location logic
6. `app/core/game_engine.py` - REFERENCE for integration points
7. `app/core/state_manager.py` - REFERENCE for decision workflow
8. `app/core/ai_opponent.py` - REFERENCE for AI decision generation
**What NOT to do**:
- ❌ Don't modify database schema without migration
- ❌ Don't use Python's datetime module (use Pendulum)
- ❌ Don't return Optional unless required (Raise or Return pattern)
- ❌ Don't disable type checking globally (use targeted # type: ignore)
- ❌ Don't skip validation - all decisions must be validated
- ❌ Don't implement full AI logic yet (Week 9 task)
- ❌ Don't commit without "CLAUDE: " prefix
- ❌ Don't forget `export PYTHONPATH=.` when running tests
- ❌ Don't try to change PlayOutcome with decision modifiers (affects advancement, not outcome)
**Patterns we're using**:
- ✅ Pydantic dataclasses for models
- ✅ Async/await for all database operations
- ✅ Frozen configs for immutability
- ✅ asyncio.Future for decision queue
- ✅ Validator pattern with clear error messages
- ✅ Result chart abstraction for league-specific resolution
- ✅ Manual vs auto mode separation (manual = WebSocket, auto = result charts)
- ✅ Hit location tracking for advancement logic
- ✅ TODO comments for future work (Week 9 AI, Week 8 substitutions)
**Manual Mode Flow**:
```python
# 1. Player requests action
> resolve
# 2. Server rolls dice
dice = dice_system.roll_ab(game_id)
# 3. Server broadcasts dice to players via WebSocket
emit('dice_rolled', {column_d6, row_2d6, chaos_d20})
# 4. Players read physical cards
[Human player looks at card]
# 5. Player submits outcome via WebSocket
emit('submit_manual_outcome', {
outcome: 'groundball_c',
hit_location: 'SS'
})
# 6. Server validates ManualOutcomeSubmission
submission = ManualOutcomeSubmission(**data)
# 7. Server resolves play with manual outcome
result = play_resolver.resolve_with_manual_outcome(submission, state)
# 8. Server broadcasts result
emit('play_resolved', result)
```
**Auto Mode Flow**:
```python
# 1. Player requests action
> resolve
# 2. Server generates outcome automatically
outcome, location = result_chart.get_outcome(roll, state, batter, pitcher)
# 3. Server resolves play with auto outcome
result = play_resolver.resolve_play(outcome, location, state)
# 4. Server broadcasts result
emit('play_resolved', result)
```
---
**Estimated Time for Next Session**: 16-22 hours (Tasks 4-8)
**Priority**: High (Task 4 is critical - all advancement logic)
**Blocking Other Work**: Yes (frontend needs WebSocket handlers from Task 7)
**Next Milestone After This**: Week 8 - Substitutions + Frontend UI