From 7d7aa9760dfd85aa5877889961d78df019ae5c9c Mon Sep 17 00:00:00 2001 From: Nuwan Date: Wed, 14 Jan 2026 22:27:22 +0530 Subject: [PATCH] docs(04-02): create Phase 5 implementation roadmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comprehensive roadmap with 9 preliminary plans, risk analysis, and success metrics. Key insights: - JamTrack 2.5-3x more complex than Backing Track - 9 plans: Redux → Thunks → Component Core → Playback → Mixdown → Download UI → Modal → Errors → UAT - High risks: download/sync state machine, native client race conditions, fqId bugs - 5 critical decisions: popup mode, stem controls, error recovery, download cancellation, UAT threshold - Testing strategy: unit tests for Redux, integration tests for flows, comprehensive UAT checklist - Applies Phase 3 lessons: popup mode from start, race condition mitigation, performance built-in Co-Authored-By: Claude Sonnet 4.5 --- .../IMPLEMENTATION_ROADMAP.md | 1030 +++++++++++++++++ 1 file changed, 1030 insertions(+) create mode 100644 .planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md diff --git a/.planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md b/.planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md new file mode 100644 index 000000000..a7479cd36 --- /dev/null +++ b/.planning/phases/04-jamtrack-research-design/IMPLEMENTATION_ROADMAP.md @@ -0,0 +1,1030 @@ +# 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**