# Phase 5 Implementation Roadmap: JamTrack Player

**Comprehensive implementation plan for React JamTrack player with risk analysis and success metrics**

---

## 1. Phase 5 Task Breakdown (Preliminary)

> **Note:** This breakdown is preliminary and will be refined during Phase 5 planning (`/gsd:plan-phase 5`). The actual number and scope of plans will be determined based on the planning depth setting (Quick/Standard/Comprehensive) in `.planning/config.json`.

### Plan 1: Redux Infrastructure & Bug Fixes

**Scope:** Foundation work before component development

**Tasks:**
1. **Fix loadJamTrack thunk fqId bug** - CRITICAL blocking issue
   - Current code: uses `jamTrack.id` instead of fqId format
   - Fix: Build fqId from `jamTrack.id` and sample rate
   - Test: Verify jamClient calls receive correct format

2. **Extend mediaSlice for JamTrack state**
   - Add `jamTrackState` (playback position, selected mixdown, mode)
   - Add `downloadState` (6-state sync machine with progress)
   - Add reducers: `setJamTrackState`, `setDownloadState`, `clearJamTrackState`

3. **Extend activeSessionSlice for mixdown data**
   - Add `availableMixdowns` (master/custom/stem hierarchy)
   - Add `activeMixdown` (currently selected)
   - Add `mixdownCache` (package metadata)
   - Add reducers: `setAvailableMixdowns`, `setActiveMixdown`, `cacheMixdownPackage`

4. **Extend sessionUISlice for JamTrack UI state**
   - Add `openJamTrack` (which JamTrack is currently open)
   - Add `jamTrackUI` preferences (last used mixdown, volume)

**Deliverables:**
- Redux state structure complete
- loadJamTrack bug fixed and tested
- Unit tests for new reducers

**Checkpoint:** Verify Redux state updates correctly via Redux DevTools

---

### Plan 2: Async Thunks & WebSocket Handlers

**Scope:** Core async operations and real-time updates

**Tasks:**
1. **Implement loadJamTrack thunk (enhanced)**
   - Build fqId from jamTrack.id and sample rate
   - Check sync state via `JamTrackGetTrackDetail(fqId)`
   - Trigger download if not synchronized
   - Load JMEP if present
   - Call `JamTrackPlay(fqId)` with correct format

2. **Implement downloadJamTrack thunk**
   - Get mixdown package ID via `pickMyPackage()` logic
   - Set up global download callbacks (string names)
   - Call `JamTrackDownload()` with callbacks
   - Poll download progress via WebSocket MIXDOWN_CHANGES
   - Request keys via `JamTrackKeysRequest()` when complete
   - Handle timeout/failure scenarios

3. **Implement checkJamTrackSync thunk**
   - Call `JamTrackGetTrackDetail(fqId)`
   - Return sync state, key state, package info
   - Used during initialization to determine if download needed

4. **Implement loadJMEP thunk**
   - Load JMEP data before playback if jamTrack.jmep exists
   - Call `JamTrackLoadJmep(fqId, jmepData)`

5. **Implement seekJamTrack thunk**
   - Call `JamTrackSeekMs(fqId, positionMs)`
   - Apply UAT-003 fix pattern (pending seek while paused)

6. **Implement closeJamTrack thunk**
   - Stop playback if playing
   - Clear state
   - Cleanup to prevent stale state

7. **Add WebSocket handlers**
   - Extend `MIXER_CHANGES` for JamTrack mixdowns
   - Add `JAM_TRACK_CHANGES` for playback state updates
   - Add `MIXDOWN_CHANGES` for download/packaging progress

**Deliverables:**
- 6 async thunks complete
- 3 WebSocket handlers integrated
- Error handling for all async operations

**Checkpoint:** Test each thunk in isolation via Redux DevTools dispatching

---

### Plan 3: JKSessionJamTrackPlayer Component - Core Structure

**Scope:** Basic player component with initialization and lifecycle

**Tasks:**
1. **Create JKSessionJamTrackPlayer.js file**
   - Props interface (isOpen, jamTrack, jamClient, session, etc.)
   - Component structure with sub-components placeholder
   - Local state vs Redux state setup

2. **Implement initialization pattern**
   - `initializePlayer()` function:
     - Build fqId
     - Check sync state via `checkJamTrackSync` thunk
     - Trigger download if needed OR load JMEP and play
   - Call on mount and when jamTrack changes

3. **Implement cleanup pattern**
   - Stop playback on unmount via `closeJamTrack` thunk
   - Clear local state
   - Remove event listeners

4. **Add loading states**
   - `isLoadingSync` - checking if JamTrack is synchronized
   - `isOperating` - prevent rapid clicks during async operations
   - Display loading spinner during operations

**Deliverables:**
- JKSessionJamTrackPlayer.js skeleton
- Initialization and cleanup working
- Loading states functional

**Checkpoint:** Player initializes correctly, shows loading states, cleans up on unmount

---

### Plan 4: JKSessionJamTrackPlayer Component - Playback Controls

**Scope:** Play/pause/stop controls with polling

**Tasks:**
1. **Implement playback control handlers**
   - `handlePlay()` - Start playback via `loadJamTrack` thunk
   - `handlePause()` - Pause via `jamClient.JamTrackPause(fqId)`
   - `handleStop()` - Stop via `jamClient.JamTrackStop(fqId)`
   - All handlers with try/catch and error state updates

2. **Implement visibility-aware polling** (from Phase 3 pattern)
   - Poll interval: 500ms visible, 2000ms hidden
   - Fetch position via `jamClient.JamTrackGetPositionMs(fqId)`
   - Fetch duration via `jamClient.JamTrackGetDurationMs(fqId)`
   - Update Redux via `setJamTrackState` action
   - Conditional updates (only update if values changed)

3. **Implement seek slider**
   - Wire slider to `currentPositionMs` from Redux
   - `handleSeek()` dispatches `seekJamTrack` thunk
   - Apply UAT-003 fix (pending seek while paused)

4. **Add end-of-track handling**
   - Detect when `currentPositionMs >= durationMs`
   - Stop and reset playback state
   - Prepare for restart (apply Phase 3 lessons)

**Deliverables:**
- Full playback controls working
- Polling active with performance optimizations
- Seek slider functional

**Checkpoint:** Can play/pause/stop/seek JamTrack, polling updates position

---

### Plan 5: JKSessionJamTrackPlayer Component - Mixdown Selection

**Scope:** Mixdown picker and selection logic

**Tasks:**
1. **Fetch available mixdowns on mount**
   - Call `jamClient.JamTrackGetMixdowns(jamTrack.id)`
   - Organize into hierarchy: master, custom mixes, stems
   - Store in Redux via `setAvailableMixdowns` action

2. **Implement mixdown picker UI**
   - Dropdown or modal for mixdown selection
   - Show master, custom mixes, stems organized
   - Indicate currently selected mixdown

3. **Implement mixdown selection logic**
   - `handleMixdownChange(mixdownId)` function
   - Stop current playback
   - Set new `selectedMixdownId` in Redux
   - Reinitialize player with new mixdown
   - Start playback if was playing

4. **Handle mixdown-specific logic**
   - Master: single audio stream
   - Custom mix: merged audio from multiple stems
   - Stem: single instrument track
   - Update playback mode in Redux

**Deliverables:**
- Mixdown picker UI complete
- Can switch between mixdowns
- Playback restarts with new mixdown

**Checkpoint:** Can select different mixdowns and hear audio change

---

### Plan 6: JKSessionJamTrackPlayer Component - Download/Sync UI

**Scope:** Download progress and sync state machine UI

**Tasks:**
1. **Implement download progress UI**
   - Progress bar showing `downloadState.progress` (0-100%)
   - Step indicator: "Downloading... (step 2 of 5)"
   - Cancel button (calls `jamClient.JamTrackCancelDownload()`)

2. **Implement 6-state sync machine UI**
   - `idle` - No download in progress
   - `checking` - Checking sync state (spinner)
   - `downloading` - Download in progress (progress bar)
   - `keying` - Requesting decryption keys (spinner)
   - `synchronized` - Ready to play (show player)
   - `error` - Download failed (error message with retry)

3. **Implement WebSocket progress updates**
   - `MIXDOWN_CHANGES` handler updates `downloadState.currentStep` and `totalSteps`
   - Show packaging progress during server-side mixdown

4. **Add retry logic**
   - Retry button in error state
   - Call `downloadJamTrack` thunk again
   - Clear error state before retry

**Deliverables:**
- Download progress UI complete
- Sync state machine working
- Retry on error functional

**Checkpoint:** Can download JamTrack, see progress, handle errors

---

### Plan 7: JKSessionJamTrackModal Updates

**Scope:** Minor updates to existing modal component

**Tasks:**
1. **Update modal to pass new props to player**
   - Pass `initialMixdownId` if user previously selected mixdown
   - Pass `autoPlay` flag

2. **Update modal to handle download state**
   - Show "Downloading..." in modal header if `downloadState.state !== 'idle'`

3. **Verify modal still works with updated player**
   - Test opening/closing modal
   - Test player initialization in modal mode

**Deliverables:**
- JKSessionJamTrackModal updated
- Modal mode tested and working

**Checkpoint:** Modal opens with JamTrack player, no regressions

---

### Plan 8: Error Handling & Edge Cases

**Scope:** Comprehensive error handling following Phase 3 patterns

**Tasks:**
1. **Implement typed error system** (from Phase 3)
   - Error types: file, network, playback, download, general
   - Error display with color coding (red for critical, yellow for warnings)
   - User-friendly error messages

2. **Add error handling to all async operations**
   - loadJamTrack: handle sync check failures, JMEP load failures, play failures
   - downloadJamTrack: handle download failures, key request failures, timeout
   - seekJamTrack: handle seek failures
   - All jamClient calls wrapped in try/catch

3. **Implement network resilience**
   - Stop polling after 3 consecutive failures
   - Show network error to user
   - Resume polling when network recovers

4. **Handle edge cases**
   - Invalid JamTrack (missing data, corrupt file)
   - No mixdowns available (show error)
   - Download interrupted (partial files)
   - Native client disconnected (jamClient unavailable)

**Deliverables:**
- Full error handling coverage
- Edge cases handled gracefully
- Network resilience working

**Checkpoint:** Intentionally trigger errors, verify user sees clear messages

---

### Plan 9: Performance Optimization & Final UAT

**Scope:** Performance tuning and user acceptance testing

**Tasks:**
1. **Apply React performance optimizations** (from Phase 3)
   - `useCallback` for all event handlers
   - `useMemo` for computed values (formatted time, progress percentage)
   - Conditional state updates in polling

2. **Verify visibility-aware polling**
   - Confirm 500ms interval when visible
   - Confirm 2000ms interval when hidden
   - Test tab switching performance

3. **Remove diagnostic logging**
   - Remove all `console.log` statements
   - Keep only error logging via error handler

4. **Conduct comprehensive UAT**
   - Test all playback controls (play/pause/stop/seek)
   - Test mixdown selection (master/custom/stem)
   - Test download progress and error scenarios
   - Test popup mode (if applicable)
   - Test cleanup on unmount
   - Document any issues found

5. **Create UAT issues file if needed**
   - Document deferred issues (like Phase 3 Issues 1-3)
   - Note severity and root cause analysis
   - Plan fix tasks if critical

**Deliverables:**
- Performance optimizations applied
- UAT completed with test results
- Issues documented in `05-XX-ISSUES.md` if any

**Checkpoint:** UAT approval gate - User verifies JamTrack player works as expected

---

## 2. Dependency Graph

```
Plan 1: Redux Infrastructure & Bug Fixes
  ↓
Plan 2: Async Thunks & WebSocket Handlers
  ↓
Plan 3: Player Core Structure ──┐
  ↓                              │
Plan 4: Playback Controls        │
  ↓                              │
Plan 5: Mixdown Selection        │
  ↓                              │
Plan 6: Download/Sync UI         │
  ↓                              │
Plan 7: Modal Updates ←──────────┘
  ↓
Plan 8: Error Handling & Edge Cases
  ↓
Plan 9: Performance & Final UAT
```

**Critical Path:**
- Plans 1-2 must complete before any component work (foundational)
- Plans 3-6 are sequential within player component (build from core to features)
- Plan 7 can happen after Plan 3 (minimal dependency)
- Plans 8-9 must be last (requires complete implementation)

**Parallel Opportunities:**
- Plan 7 (Modal Updates) can run in parallel with Plans 4-6 after Plan 3 completes
- This could reduce total duration by ~10-15%

---

## 3. Risk Analysis

### High Risk Areas

#### Risk 1: Download/Sync State Machine Complexity
**Severity:** HIGH
**Probability:** MEDIUM
**Impact:** Could delay Plans 2 and 6

**Description:**
The 6-state download/sync machine (`idle` → `checking` → `downloading` → `keying` → `synchronized` → `error`) is significantly more complex than Backing Track's simple load pattern. Legacy CoffeeScript implementation has race conditions and callback timing issues.

**Mitigation:**
- Reference legacy implementation closely (JAMTRACK_LEGACY.md:102-127)
- Test state transitions thoroughly in Plan 2
- Add diagnostic logging during development (remove in Plan 9)
- Use Redux DevTools to visualize state transitions
- Consider creating a state machine diagram for verification

**Contingency:**
- If WebSocket progress updates unreliable, fall back to polling `JamTrackGetTrackDetail(fqId)` every 2 seconds
- Document known issues if race conditions persist (like Phase 3 Issues 1-2)

---

#### Risk 2: Native Client Race Conditions
**Severity:** HIGH
**Probability:** HIGH (observed in Phase 3)
**Impact:** Could require rework in Plans 4 and 8

**Description:**
Phase 3 encountered multiple race conditions between React state and native client state:
- End-of-track restart requires double-click (Issue 1)
- Play state synchronization delays
- Loop flag not respected (Issue 2)

JamTrack has MORE async complexity: sync checks, downloads, JMEP loading, mixdown selection. Expect similar or worse race conditions.

**Mitigation:**
- Apply Phase 3 lessons learned from the start:
  - Use verification delays (50-100ms) after critical jamClient calls
  - Implement pending state pattern (like UAT-003 fix for seek-while-paused)
  - Add state machine guards (prevent invalid transitions)
- Test extensively in Plans 4 and 6
- Document race conditions found with diagnostic logging

**Contingency:**
- Defer complex issues to future work (like Phase 3 Issues 1-3)
- Add workarounds where possible (e.g., double-click retry logic)
- Consider adding "Known Limitations" section to UAT results

---

#### Risk 3: fqId Format Bugs Throughout Codebase
**Severity:** MEDIUM
**Probability:** HIGH
**Impact:** Could block Plan 1 and delay subsequent plans

**Description:**
Identified bug in existing `loadJamTrack` thunk: uses `jamTrack.id` instead of fqId format `{jamTrackId}-{sampleRate}`. This bug may exist in other places:
- JKSessionJamTrackModal component
- JKSessionJamTrackStems component
- Other Redux thunks
- WebSocket message handlers

If fqId format is wrong, ALL jamClient JamTrack calls will fail silently or return incorrect data.

**Mitigation:**
- Audit all JamTrack-related code in Plan 1 for fqId usage
- Search codebase for `jamTrack.id` patterns and verify each usage
- Create helper function `buildFqId(jamTrack, sampleRate)` to centralize logic
- Add unit tests verifying fqId format
- Use TypeScript type guards if available

**Contingency:**
- If bugs widespread, add Plan 1.5 for comprehensive fqId audit and fixes
- Estimate +1 plan to roadmap

---

#### Risk 4: Mixdown Selection Logic Complexity
**Severity:** MEDIUM
**Probability:** MEDIUM
**Impact:** Could delay Plan 5

**Description:**
Mixdown selection involves complex logic:
1. Fetch mixdowns from jamClient (async)
2. Filter by file type (ogg), encryption (jkz), sample rate
3. Organize hierarchy: master, custom mixes (user-created), stems
4. Handle "no mixdowns available" edge case
5. Switch between mixdowns mid-playback (stop → reinitialize → play)

Legacy CoffeeScript has `pickMyPackage()` function with 50+ lines of filtering logic. This must be replicated accurately or downloads will fail.

**Mitigation:**
- Study legacy `pickMyPackage()` implementation closely (JAMTRACK_LEGACY.md:141-162)
- Create unit tests for mixdown filtering logic
- Test with multiple JamTracks (different mixdown configurations)
- Verify sample rate matching (44.1 kHz vs 48 kHz)

**Contingency:**
- If logic too complex, simplify initial implementation:
  - Phase 5: Support master mixdown only (simplest case)
  - Future phase: Add custom mix and stem support
- Estimate +1 plan for advanced mixdown features

---

### Medium Risk Areas

#### Risk 5: JMEP Support
**Severity:** MEDIUM
**Probability:** LOW
**Impact:** Could delay Plan 2

**Description:**
JMEP (Jam Enhancement Package) provides tempo/pitch modifications. Must be loaded BEFORE playback via `JamTrackLoadJmep(fqId, jmepData)`.

Unclear if JMEP is required for all JamTracks or optional. Legacy code shows conditional loading, but error handling unclear.

**Mitigation:**
- Reference JAMTRACK_API.md:318-343 for JMEP API details
- Check if `jamTrack.jmep` property exists before loading
- Add error handling if JMEP load fails (should playback continue?)
- Test with JamTracks with and without JMEP

**Contingency:**
- If JMEP causes issues, make it optional and log warning
- Document as known limitation if full support not feasible

---

#### Risk 6: WebSocket Handler Integration
**Severity:** MEDIUM
**Probability:** LOW
**Impact:** Could delay Plan 2

**Description:**
Need to extend existing `MIXER_CHANGES` handler and add two new handlers (`JAM_TRACK_CHANGES`, `MIXDOWN_CHANGES`). WebSocket integration code not well-documented. Must locate where handlers are registered and ensure correct message parsing.

**Mitigation:**
- Reference existing Backing Track WebSocket handlers
- Search codebase for `MIXER_CHANGES` to find registration point
- Verify Protocol Buffer message format matches expectations
- Test WebSocket messages with Redux DevTools

**Contingency:**
- If WebSocket unreliable, fall back to polling for state updates
- Polling less efficient but guaranteed to work

---

### Low Risk Areas

#### Risk 7: Modal Component Updates
**Severity:** LOW
**Probability:** LOW
**Impact:** Minimal - Plan 7 is small scope

**Description:**
JKSessionJamTrackModal already exists and works. Only minor updates needed (pass new props, handle download state). Low complexity, well-understood patterns.

**Mitigation:**
- Verify existing modal code before modifying
- Test after each change
- Keep changes minimal

---

#### Risk 8: Performance Degradation
**Severity:** LOW
**Probability:** LOW (if Phase 3 patterns applied)
**Impact:** Could require rework in Plan 9

**Description:**
JamTrack player has MORE polling than Backing Track (position, duration, sync state, download progress). Could cause performance issues.

**Mitigation:**
- Apply Phase 3 visibility-aware polling from the start
- Use conditional state updates (only update if values changed)
- Apply React optimizations (useCallback, useMemo) in Plan 9
- Test with multiple JamTracks open simultaneously

**Contingency:**
- Increase polling intervals if performance issues observed
- Consolidate polling calls into single jamClient request if possible

---

## 4. Critical Decisions Needed Before Phase 5

### Decision 1: Popup Mode Support
**Question:** Should JamTrack player support popup window mode like Backing Track?

**Context:**
Phase 3 discovered popup mode has architectural limitations:
- Mixer state not available (empty array)
- Volume control doesn't work
- Props passed differently (string vs object)

**Options:**
- **A) Support both modes** - Follow Backing Track pattern, document limitations
- **B) Modal only** - Simpler, avoid popup complexity
- **C) Refactor mixer architecture** - Make mixers available in popup mode (large effort)

**Recommendation:** **Option A** - Support both modes, document limitations
**Rationale:** Consistency with Backing Track, users may expect popup mode

**Impact on Plan:**
- If Option A: Add popup mode testing to Plan 9 UAT
- If Option B: Remove popup mode code from Plan 3
- If Option C: Add Plan 1.5 for mixer architecture refactor (+2-3 tasks)

---

### Decision 2: Stem Control Integration
**Question:** Should JKSessionJamTrackPlayer integrate stem volume controls or defer to separate component?

**Context:**
JKSessionJamTrackStems component exists for controlling individual stem volumes. Two integration approaches:

**Options:**
- **A) Embed stem controls in player** - Single unified component
- **B) Keep separate, communicate via Redux** - Modular, reusable
- **C) Hybrid - show stem controls only when stem mixdown selected** - Contextual

**Recommendation:** **Option B** - Keep separate, communicate via Redux
**Rationale:** Maintains separation of concerns, reusable across contexts

**Impact on Plan:**
- If Option A: Expand Plan 5 to include stem control UI (+2-3 tasks)
- If Option B: No impact, verify Redux integration in Plan 1
- If Option C: Add conditional rendering logic to Plan 5 (+1 task)

---

### Decision 3: Error Recovery Strategy
**Question:** How aggressive should error recovery be (auto-retry vs user-initiated)?

**Context:**
Phase 3 used network resilience (stop after 3 failures, show error). JamTrack has more failure modes: download failures, sync failures, JMEP failures, key request failures.

**Options:**
- **A) Auto-retry with exponential backoff** - User-friendly, may hide problems
- **B) User-initiated retry** - Explicit, more control
- **C) Hybrid - auto-retry transient errors, user retry for fatal errors** - Balanced

**Recommendation:** **Option C** - Hybrid approach
**Rationale:** Best UX, matches user expectations

**Impact on Plan:**
- If Option A: Add retry logic to all error handlers in Plan 8 (+1-2 tasks)
- If Option B: Add retry buttons to error UI in Plan 8 (+1 task)
- If Option C: Add retry logic + retry buttons in Plan 8 (+2 tasks)

---

### Decision 4: Download Cancellation
**Question:** Should users be able to cancel in-progress downloads?

**Context:**
JamTrack downloads can be large (hundreds of MB) and take minutes. Legacy implementation has `JamTrackCancelDownload()` method but unclear if it works reliably.

**Options:**
- **A) Implement cancellation** - Better UX, may have edge cases
- **B) No cancellation, show progress only** - Simpler, less flexible
- **C) Defer to future work** - MVP without cancellation

**Recommendation:** **Option A** - Implement cancellation
**Rationale:** Large downloads, user should have control

**Impact on Plan:**
- If Option A: Add cancel button and handler to Plan 6 (+1 task)
- If Option B: No impact
- If Option C: Remove cancellation from Plan 6, add to future roadmap

---

### Decision 5: UAT Deferral Threshold
**Question:** What severity threshold should trigger deferring UAT issues to future work?

**Context:**
Phase 3 deferred 3 issues:
- Issue 1 (Minor) - End-of-track double-click
- Issue 2 (Medium) - Loop not working
- Issue 3 (Medium) - Volume in popup mode

**Options:**
- **A) Defer all issues** - Ship fast, iterate later
- **B) Defer minor only, fix medium+** - Balanced quality
- **C) Fix all issues before completion** - High quality, slower

**Recommendation:** **Option B** - Defer minor only, fix medium+
**Rationale:** Balances speed with quality, matches Phase 3 approach

**Impact on Plan:**
- If Option A: Plan 9 UAT may identify issues but all deferred
- If Option B: May need Plan 10 for critical UAT fixes (like Phase 3 did)
- If Option C: May need multiple fix plans, extends Phase 5 significantly

---

## 5. Success Metrics for Phase 5

### Functional Completeness

**Must Have (P0):**
- ✅ JamTrack opens in modal/popup mode
- ✅ Download progress UI shows sync state and percentage
- ✅ Play/pause/stop controls work
- ✅ Seek slider functional
- ✅ Position and duration display correctly (MM:SS format)
- ✅ Mixdown selection (master, custom, stem)
- ✅ Error handling with user feedback
- ✅ Cleanup on unmount (no stale state)

**Should Have (P1):**
- ✅ Download cancellation
- ✅ JMEP support for tempo/pitch modifications
- ✅ Network resilience (retry on failure)
- ✅ Visibility-aware polling (performance)
- ✅ Loading states and disabled UI during operations

**Nice to Have (P2):**
- ✅ Volume control (if mixer architecture allows)
- ✅ Loop functionality (if native client supports)
- ✅ Popup mode fully functional (with documented limitations)

---

### Code Quality Metrics

**Maintainability:**
- All components use established React patterns (hooks, Redux, error handling)
- Code follows existing conventions (JK prefix, file structure)
- No code duplication (DRY principle applied)
- Clear separation of concerns (presentational vs container)

**Performance:**
- Polling optimized (visibility-aware, conditional updates)
- React optimizations applied (useCallback, useMemo)
- No unnecessary re-renders (verified with React DevTools)
- Clean console output (no diagnostic logging)

**Testing:**
- Redux reducers have unit tests
- Critical thunks tested in isolation
- Component tested manually via UAT
- Edge cases covered (invalid data, network failures)

---

### User Experience Metrics

**Usability:**
- User can open JamTrack and start playing within 3 seconds (if already synced)
- Download progress clearly communicated (percentage, step indicator)
- Errors presented with clear messages and recovery actions
- Controls respond immediately (no lag from polling)

**Reliability:**
- No crashes or unrecoverable errors during normal use
- Graceful degradation on network issues
- Cleanup prevents stale state bugs
- Known limitations documented clearly

---

### Comparison to Phase 3

| Metric | Phase 3 (Backing Track) | Phase 5 Target (JamTrack) |
|--------|------------------------|---------------------------|
| Plans | 3 plans | 9 plans (preliminary) |
| Duration | ~3-4 hours | ~8-12 hours (estimated) |
| Components Created | 0 (updated existing) | 1 (JKSessionJamTrackPlayer) |
| Components Updated | 1 (JKSessionBackingTrackPlayer) | 2 (Modal, Stems) |
| Redux Slices Extended | 1 (mediaSlice) | 3 (media, activeSession, sessionUI) |
| Async Thunks Added | 0 (used existing loadBackingTrack) | 6 (load, download, sync, JMEP, seek, close) |
| WebSocket Handlers | 1 (MIXER_CHANGES extended) | 3 (MIXER extended, JAM_TRACK, MIXDOWN) |
| UAT Issues Deferred | 3 (2 medium, 1 minor) | 2-4 expected (similar complexity) |
| Complexity Factor | 1x (baseline) | 2.5x (download/sync, mixdown, JMEP) |

**Key Differences:**
- JamTrack is ~2.5x more complex than Backing Track
- More Redux state to manage (download/sync machine)
- More async operations (download, keying, JMEP)
- More UI states (6 sync states vs 2 for Backing Track)
- More potential race conditions (more jamClient calls)

**Adjusted Estimates:**
- If Phase 3 took 3 plans → Phase 5 should take ~7-9 plans (2.5x complexity)
- Preliminary breakdown shows 9 plans → reasonable estimate
- May consolidate to 7-8 plans during actual Phase 5 planning

---

## 6. Testing Strategy

### Unit Testing

**Redux Reducers:**
- Test all new reducers (setJamTrackState, setDownloadState, etc.)
- Verify state updates correctly
- Test edge cases (null values, invalid states)

**Redux Selectors:**
- Test all new selectors (selectJamTrackState, selectDownloadState, etc.)
- Verify computed values correct (formatted time, progress percentage)

**Async Thunks:**
- Mock jamClient calls
- Test success path (happy path)
- Test error paths (jamClient throws, network failure)
- Verify Redux state updates correctly

**Helper Functions:**
- Test `buildFqId(jamTrack, sampleRate)` with various inputs
- Test `pickMyPackage()` mixdown filtering logic
- Test `formatTime(ms)` utility

---

### Integration Testing

**Component + Redux:**
- Mount JKSessionJamTrackPlayer with Redux store
- Dispatch actions, verify component updates
- Test user interactions trigger correct thunks

**WebSocket + Redux:**
- Send mock WebSocket messages
- Verify Redux state updates
- Verify component re-renders

**jamClient + Redux:**
- Mock jamClient responses
- Test full user flows (open → download → play → seek → close)
- Verify state transitions correct

---

### Manual Testing (UAT)

**Test Plan 9 UAT Checklist:**

**Initialization:**
- [ ] Open JamTrack in modal mode
- [ ] Open JamTrack in popup mode (if supported)
- [ ] JamTrack already synced → plays immediately
- [ ] JamTrack not synced → shows download UI

**Download/Sync:**
- [ ] Download progress shows percentage
- [ ] Download progress shows step indicator
- [ ] WebSocket updates progress in real-time
- [ ] Download completes, transitions to play state
- [ ] Download error shows error message
- [ ] Download cancellation works (if supported)

**Playback Controls:**
- [ ] Play button starts playback
- [ ] Pause button pauses playback
- [ ] Stop button stops playback
- [ ] Seek slider moves during playback
- [ ] Drag seek slider to new position
- [ ] Seek works while playing
- [ ] Seek works while paused (UAT-003 fix)

**Mixdown Selection:**
- [ ] Mixdown picker shows available mixdowns
- [ ] Select master mixdown → audio changes
- [ ] Select custom mix → audio changes
- [ ] Select stem → audio changes
- [ ] Switch mixdown mid-playback → restarts correctly

**Display:**
- [ ] Position displays correctly (MM:SS format)
- [ ] Duration displays correctly (MM:SS format)
- [ ] Seek slider position matches audio position
- [ ] Loading states show during operations
- [ ] Error states show clear messages

**Performance:**
- [ ] No lag during playback
- [ ] Polling doesn't cause CPU spikes
- [ ] Visibility-aware polling works (check intervals)
- [ ] Multiple JamTracks can coexist (if applicable)

**Edge Cases:**
- [ ] Invalid JamTrack (missing data) → shows error
- [ ] No mixdowns available → shows error
- [ ] Network failure during download → shows error, allows retry
- [ ] Network failure during polling → stops polling, shows error
- [ ] Native client disconnected → shows error
- [ ] Close modal/popup during playback → stops playback
- [ ] Unmount component during download → cancels download

**Cleanup:**
- [ ] Close modal → playback stops
- [ ] Close popup → playback stops
- [ ] Open different JamTrack → previous stops
- [ ] No console errors after interactions
- [ ] No stale state bugs (open → close → reopen works)

---

### Regression Testing

**Verify Phase 3 Backing Track Still Works:**
- [ ] Open Backing Track in modal mode
- [ ] Open Backing Track in popup mode
- [ ] All playback controls work
- [ ] Seek slider works
- [ ] Volume control works (modal mode)
- [ ] Loop checkbox works (if fixed)
- [ ] No new issues introduced

**Verify JamTrack Modal/Stems Still Work:**
- [ ] JKSessionJamTrackModal opens correctly
- [ ] JKSessionJamTrackStems shows stem controls
- [ ] Stem volume changes work
- [ ] No regressions from Redux changes

---

## 7. Comparison to Phase 3 Effort

### Similarities

**Architecture Patterns:**
- Both use jamClient for native client integration
- Both use Redux for shared state
- Both use WebSocket for real-time updates
- Both need polling for playback position

**React Patterns:**
- Error handling approach same (typed errors, user feedback)
- Loading states pattern same (isOperating flag)
- Cleanup on unmount same (prevent stale state)
- Performance optimizations same (visibility-aware polling, useCallback)

**Development Approach:**
- Both start with Redux infrastructure
- Both build component from core to features
- Both end with error handling and UAT
- Both expect to defer some issues to future work

---

### Key Differences

**Complexity:**
| Aspect | Backing Track | JamTrack |
|--------|---------------|----------|
| Component State | 2 states (playing, paused) | 6 states (idle, checking, downloading, keying, synchronized, error) |
| User Actions | 5 actions (play, pause, stop, seek, volume) | 10+ actions (play, pause, stop, seek, select mixdown, cancel download, retry) |
| jamClient Calls | 8 methods | 15+ methods |
| Redux Slices | 1 extended | 3 extended |
| Async Thunks | 0 new | 6 new |
| WebSocket Handlers | 1 extended | 3 (1 extended, 2 new) |
| UI Components | 1 player component | 1 player + download UI + mixdown picker |

**New Challenges:**
1. **Download/Sync State Machine** - Not present in Backing Track
2. **Mixdown Selection** - Not present in Backing Track (single file)
3. **JMEP Support** - Not present in Backing Track
4. **Progress Callbacks** - Not present in Backing Track (no download phase)
5. **Package/Key Management** - Not present in Backing Track

**Effort Multiplier:**
- Base complexity: 2.5x Backing Track
- More Redux state: +20% effort
- More jamClient integration: +30% effort
- Download/sync UI: +25% effort
- **Total estimated effort: 2.5-3x Phase 3**

---

### Lessons Learned from Phase 3 Applied

**Lesson 1: Popup vs Modal Modes**
**Phase 3:** Discovered popup mode issues during UAT, had to retrofit fixes
**Phase 5:** Consider both modes from Plan 3 (component structure)

**Lesson 2: Native Client Race Conditions**
**Phase 3:** Encountered multiple race conditions, deferred 2 issues
**Phase 5:** Add state verification from the start, expect similar issues

**Lesson 3: Mixer Dependencies**
**Phase 3:** Volume control failed in popup mode (no mixers)
**Phase 5:** Document mixer limitations early, consider architecture

**Lesson 4: UAT Reveals Unknowns**
**Phase 3:** 3 issues deferred, required additional diagnostic work
**Phase 5:** Budget time for UAT fixes, expect 1-2 issues to defer

**Lesson 5: Performance from the Start**
**Phase 3:** Added visibility-aware polling in final plan
**Phase 5:** Build in performance optimizations from Plan 4 (polling)

**Lesson 6: Incremental Commits**
**Phase 3:** Atomic commits per task worked well
**Phase 5:** Continue same approach, aids debugging

---

### Risk Mitigation from Phase 3 Experience

**Race Condition Strategy:**
- Use Phase 3's pending state pattern (UAT-003 fix)
- Add verification delays after critical jamClient calls
- Test state transitions thoroughly before UAT
- Budget time for race condition debugging

**Error Handling Strategy:**
- Reuse Phase 3's typed error system
- Apply network resilience from the start
- Test error paths early (don't wait for UAT)
- Clear user feedback for all error states

**Performance Strategy:**
- Apply visibility-aware polling from Plan 4
- Use React DevTools to verify no unnecessary re-renders
- Conditional state updates in all polling
- Profile with React DevTools before UAT

---

## 8. Next Steps

**After Phase 4 Plan 2 Completion:**

1. **User Approval** - Present this roadmap for verification
2. **Phase 4 Completion** - Create SUMMARY.md, update STATE.md, update ROADMAP.md
3. **Context Clear** - `/clear` to free context window
4. **Phase 5 Planning** - Run `/gsd:plan-phase 5` to create executable PLAN.md files

**During Phase 5 Planning:**
- Refine task breakdown based on config depth (Quick/Standard/Comprehensive)
- May consolidate 9 preliminary plans into 7-8 actual plans
- Finalize decisions (popup mode, stem controls, error recovery, etc.)
- Create detailed execution context for each plan

**Phase 5 Execution:**
- Follow atomic commit strategy (1 commit per task)
- Pause at verification checkpoints for user approval
- Document deviations and issues as they arise
- Create SUMMARY.md after each plan completion

---

**END OF IMPLEMENTATION ROADMAP**
