From c086215533869736d9a8cc18dd3fb3eb92f54e9c Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Fri, 27 Feb 2026 13:16:41 -0500 Subject: [PATCH] docs: create roadmap (8 phases) --- .planning/REQUIREMENTS.md | 58 +++++++++--------- .planning/ROADMAP.md | 124 ++++++++++++++++++++++++++++++++++++++ .planning/STATE.md | 77 +++++++++++++++++++++++ 3 files changed, 230 insertions(+), 29 deletions(-) create mode 100644 .planning/ROADMAP.md create mode 100644 .planning/STATE.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 2b80142..3fb90c2 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -89,38 +89,38 @@ Which phases cover which requirements. Updated during roadmap creation. | Requirement | Phase | Status | |-------------|-------|--------| -| CORR-01 | — | Pending | -| CORR-02 | — | Pending | -| CORR-03 | — | Pending | -| CORR-04 | — | Pending | -| CORR-05 | — | Pending | -| CORR-06 | — | Pending | -| CORR-07 | — | Pending | -| CORR-08 | — | Pending | -| CORR-09 | — | Pending | -| QUAL-01 | — | Pending | -| QUAL-02 | — | Pending | -| QUAL-03 | — | Pending | -| QUAL-04 | — | Pending | -| PERF-01 | — | Pending | -| PERF-02 | — | Pending | -| PERF-03 | — | Pending | -| PERF-04 | — | Pending | -| PERF-05 | — | Pending | -| TEST-01 | — | Pending | -| TEST-02 | — | Pending | -| TEST-03 | — | Pending | -| TEST-04 | — | Pending | -| TEST-05 | — | Pending | -| TEST-06 | — | Pending | -| UX-01 | — | Pending | -| UX-02 | — | Pending | +| CORR-01 | Phase 1: Concurrency Race Fixes | Pending | +| CORR-02 | Phase 1: Concurrency Race Fixes | Pending | +| CORR-03 | Phase 1: Concurrency Race Fixes | Pending | +| CORR-04 | Phase 1: Concurrency Race Fixes | Pending | +| CORR-05 | Phase 2: Backend Correctness | Pending | +| CORR-06 | Phase 2: Backend Correctness | Pending | +| CORR-07 | Phase 2: Backend Correctness | Pending | +| CORR-08 | Phase 2: Backend Correctness | Pending | +| CORR-09 | Phase 2: Backend Correctness | Pending | +| QUAL-01 | Phase 6: SQL Consolidation & Code Quality | Pending | +| QUAL-02 | Phase 6: SQL Consolidation & Code Quality | Pending | +| QUAL-03 | Phase 6: SQL Consolidation & Code Quality | Pending | +| QUAL-04 | Phase 6: SQL Consolidation & Code Quality | Pending | +| PERF-01 | Phase 7: Backend Performance | Pending | +| PERF-02 | Phase 7: Backend Performance | Pending | +| PERF-03 | Phase 7: Backend Performance | Pending | +| PERF-04 | Phase 3: Test Infrastructure | Pending | +| PERF-05 | Phase 8: Frontend Performance & UX | Pending | +| TEST-01 | Phase 3: Test Infrastructure | Pending | +| TEST-02 | Phase 4: Queue, Config & Player Tests | Pending | +| TEST-03 | Phase 5: Database & Library Tests | Pending | +| TEST-04 | Phase 4: Queue, Config & Player Tests | Pending | +| TEST-05 | Phase 4: Queue, Config & Player Tests | Pending | +| TEST-06 | Phase 5: Database & Library Tests | Pending | +| UX-01 | Phase 8: Frontend Performance & UX | Pending | +| UX-02 | Phase 8: Frontend Performance & UX | Pending | **Coverage:** - v1 requirements: 26 total -- Mapped to phases: 0 -- Unmapped: 26 +- Mapped to phases: 26 +- Unmapped: 0 --- *Requirements defined: 2026-02-27* -*Last updated: 2026-02-27 after initial definition* +*Last updated: 2026-02-27 after roadmap creation (traceability updated)* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md new file mode 100644 index 0000000..ca512c3 --- /dev/null +++ b/.planning/ROADMAP.md @@ -0,0 +1,124 @@ +# Roadmap: YellowJacket Consolidation + +**Created:** 2026-02-27 +**Depth:** Comprehensive +**Phases:** 8 +**Requirements:** 26/26 mapped + +## Phases + +- [ ] **Phase 1: Concurrency Race Fixes** — Eliminate all SetContext data races across Queue, Library, Playlist, and Player +- [ ] **Phase 2: Backend Correctness** — Fix error handling gaps, file permissions, package-level state, and scan error separation +- [ ] **Phase 3: Test Infrastructure** — Create in-memory SQLite test helper and apply production SQLite PRAGMAs +- [ ] **Phase 4: Queue, Config & Player Tests** — Write unit tests for queue operations, config roundtrip, and extracted player pure logic +- [ ] **Phase 5: Database & Library Tests** — Write unit tests for FTS5 search queries, migrations, library scan, and entity cache +- [ ] **Phase 6: SQL Consolidation & Code Quality** — Deduplicate FTS5 queries via VIEW, add event codegen, migrate to sqlc where feasible, document exceptions +- [ ] **Phase 7: Backend Performance** — Optimize queue persistence, fix SetQueue Phase 2 redundancy, enable lazy library loading +- [ ] **Phase 8: Frontend Performance & UX** — Optimize frontend rendering for large libraries and fix visual inconsistencies + +## Phase Details + +### Phase 1: Concurrency Race Fixes +**Goal:** All SetContext patterns across the codebase are race-free and the app can run under `-race` without data race reports +**Depends on:** Nothing (first phase) +**Requirements:** CORR-01, CORR-02, CORR-03, CORR-04 +**Success Criteria** (what must be TRUE): + 1. Running the app with `go test -race` produces zero data race reports for SetContext calls in queue, library, playlist, and player packages + 2. Queue.SetContext(), Library.SetContext(), and Playlist.Service.SetContext() each acquire their mutex before writing the ctx field + 3. Player.SetContext() uses a single lock acquisition instead of the double-lock pattern + 4. Concurrent calls to SetContext from multiple goroutines do not corrupt shared state +**Plans:** TBD + +### Phase 2: Backend Correctness +**Goal:** All known error handling gaps are closed, configuration is secure, and the backend reports problems honestly instead of swallowing them +**Depends on:** Phase 1 (race-free code is prerequisite for reliable error paths) +**Requirements:** CORR-05, CORR-06, CORR-07, CORR-08, CORR-09 +**Success Criteria** (what must be TRUE): + 1. The package-level `startupErr` variable no longer exists; startup errors are stored in a YellowJacketApp struct field + 2. Config files are written with 0o644 permissions (owner read/write, group/other read-only) + 3. MPRIS lifecycle callback errors (Pause, Seek) appear in the application log instead of being silently discarded + 4. Artist credit link creation checks the actual error — only UNIQUE constraint violations are ignored, all other errors are surfaced + 5. Library.Scan() returns warnings (skipped files, partial failures) in ScanMetrics and fatal errors (database failures) in the error return, so callers can distinguish between "scan completed with issues" and "scan failed" +**Plans:** TBD + +### Phase 3: Test Infrastructure +**Goal:** A reliable, production-mirroring test foundation exists so that all subsequent test phases can write database-backed tests with confidence +**Depends on:** Phase 1 (race-free code required for `-race`-clean test runs), Phase 2 (correct error handling needed for accurate test assertions) +**Requirements:** TEST-01, PERF-04 +**Success Criteria** (what must be TRUE): + 1. `database.NewTestDB(t)` returns a clean in-memory SQLite database that applies the same migrations and PRAGMAs as the production `NewDB()` + 2. Production SQLite connection applies `synchronous=NORMAL`, `cache_size=-8000`, and `mmap_size=67108864` PRAGMAs at database open + 3. Each test gets an isolated database instance — no shared state between test functions + 4. Tests using `NewTestDB` pass with `-race` flag enabled +**Plans:** TBD + +### Phase 4: Queue, Config & Player Tests +**Goal:** The queue, config, and player packages have comprehensive unit tests that characterize current behavior and serve as a safety net for later refactoring +**Depends on:** Phase 3 (queue tests need NewTestDB for persistence tests) +**Requirements:** TEST-02, TEST-04, TEST-05 +**Success Criteria** (what must be TRUE): + 1. Queue package has ~15-20 tests covering SetQueue, Next, Previous, shuffle mode, repeat modes (off, one, all), and state persistence across save/load cycles + 2. Config package has ~8-10 tests covering load/save roundtrip fidelity, validation rule enforcement, default value application, and graceful handling of missing or empty config files + 3. Player pure logic (UserVolume↔Volume conversion, state serialization/deserialization, format detection from file extension) is extracted into standalone functions with ~5-8 unit tests + 4. All tests in this phase pass with `-race` flag enabled +**Plans:** TBD + +### Phase 5: Database & Library Tests +**Goal:** Database queries (especially FTS5 search) and library scan logic have unit tests that lock down current behavior before SQL consolidation and performance optimization +**Depends on:** Phase 3 (database tests need NewTestDB), Phase 4 (queue tests validate persistence patterns reused here) +**Requirements:** TEST-03, TEST-06 +**Success Criteria** (what must be TRUE): + 1. Database package has ~10-15 tests covering FTS5 search (basic terms, empty query, special characters, multi-word), search index rebuild, and schema migration application + 2. Library scan logic has ~10-15 tests covering metadata extraction processing, entity cache hit/miss behavior, and orphan track cleanup + 3. FTS5 search tests verify that search ranking produces consistent, expected ordering for known test data + 4. All tests in this phase pass with `-race` flag enabled +**Plans:** TBD + +### Phase 6: SQL Consolidation & Code Quality +**Goal:** Duplicated SQL patterns are eliminated, event names are provably synchronized between Go and TypeScript, and intentional SQL exceptions are documented +**Depends on:** Phase 5 (FTS5 search tests verify consolidation doesn't break ranking; database tests verify migration safety) +**Requirements:** QUAL-01, QUAL-02, QUAL-03, QUAL-04 +**Success Criteria** (what must be TRUE): + 1. The duplicated 5-table FTS5 JOIN pattern is consolidated into a single SQLite VIEW (`track_metadata` or similar), and all search queries use the VIEW instead of inline JOINs + 2. A code generator reads Go event constants from `backend/events/events.go` and produces `frontend/src/events.ts`, wired into `go generate` and the pre-commit hook — adding an event in Go without regenerating TypeScript fails the hook + 3. Queue batch lookups in `persistence.go` use `sqlc.slice()` for IN clauses where sqlc supports it, replacing `fmt.Sprintf` placeholder construction + 4. Every hand-crafted SQL statement that intentionally bypasses sqlc has a `// SAFETY:` comment explaining why (batch INSERT, dynamic IN clauses, etc.) +**Plans:** TBD + +### Phase 7: Backend Performance +**Goal:** Queue mutations and library loading are fast — single-track queue changes are O(1) instead of O(n), and the library doesn't block startup with a full data fetch +**Depends on:** Phase 4 (queue tests verify persistence optimization doesn't lose data), Phase 5 (library tests verify lazy loading doesn't break data access) +**Requirements:** PERF-01, PERF-02, PERF-03 +**Success Criteria** (what must be TRUE): + 1. Adding or removing a single track from the queue uses incremental INSERT/DELETE via existing sqlc queries, not a full table rewrite + 2. SetQueue Phase 2 (`resolveRemainingTracks`) skips file paths that were already resolved in Phase 1, eliminating redundant database lookups + 3. Library store constructor no longer calls `eagerFetch()` — data loads lazily on first access via the existing `getTracks()`/`getAlbums()`/etc. getters, and the app starts without blocking on a full library load +**Plans:** TBD + +### Phase 8: Frontend Performance & UX +**Goal:** The app feels smooth and visually consistent — large libraries render without jank, and the UI follows a coherent visual language +**Depends on:** Phase 7 (backend lazy loading changes the data availability pattern the frontend consumes) +**Requirements:** PERF-05, UX-01, UX-02 +**Success Criteria** (what must be TRUE): + 1. Track and album lists use Lit `repeat()` directive with stable keys (filePath for tracks, albumId for albums) for efficient DOM reuse during scrolling and filtering + 2. Store notifications during rapid updates (e.g., library scan) are debounced via `queueMicrotask()` to prevent layout thrashing + 3. Visual inconsistencies (spacing, colors, typography, icon sizing) are audited and follow a consistent pattern across all components + 4. Scrolling, view switching, and search filtering in a 10k+ track library are smooth with no visible jank or dropped frames +**Plans:** TBD + +## Progress + +| Phase | Plans Complete | Status | Completed | +|-------|----------------|--------|-----------| +| 1. Concurrency Race Fixes | 0/? | Not started | — | +| 2. Backend Correctness | 0/? | Not started | — | +| 3. Test Infrastructure | 0/? | Not started | — | +| 4. Queue, Config & Player Tests | 0/? | Not started | — | +| 5. Database & Library Tests | 0/? | Not started | — | +| 6. SQL Consolidation & Code Quality | 0/? | Not started | — | +| 7. Backend Performance | 0/? | Not started | — | +| 8. Frontend Performance & UX | 0/? | Not started | — | + +--- +*Roadmap created: 2026-02-27* +*Last updated: 2026-02-27* diff --git a/.planning/STATE.md b/.planning/STATE.md new file mode 100644 index 0000000..f93f89f --- /dev/null +++ b/.planning/STATE.md @@ -0,0 +1,77 @@ +# YellowJacket — Consolidation Milestone State + +## Project Reference + +**Core value:** The music player works reliably and feels solid — every interaction is correct, responsive, and trustworthy. +**Current focus:** Roadmap created, awaiting Phase 1 planning. +**Milestone:** Consolidation (correctness, performance, code quality, UX polish, test coverage) + +## Current Position + +**Phase:** — (not started) +**Plan:** — (not started) +**Status:** Roadmap complete, ready for phase planning + +``` +Phase Progress: [........] 0/8 phases complete +``` + +## Performance Metrics + +| Metric | Value | +|--------|-------| +| Phases complete | 0/8 | +| Plans complete | 0/? | +| Requirements delivered | 0/26 | +| Tests added | 0 | +| Bugs fixed | 0 | + +## Accumulated Context + +### Key Decisions + +| Decision | Rationale | Phase | +|----------|-----------|-------| +| Fix races before tests | Can't run `-race`-clean tests with active data races | Phase 1 → 3 | +| PRAGMAs with test infra | NewTestDB must mirror production DB setup; PRAGMAs change production NewDB | Phase 3 | +| Tests before refactoring | Research unanimously recommends characterization tests as safety net | Phase 4-5 → 6-7 | +| SQL consolidation after DB tests | FTS5 search tests verify VIEW doesn't change ranking | Phase 5 → 6 | +| Frontend last | Backend API should be stable before frontend adapts | Phase 8 | + +### TODOs + +- [ ] Plan Phase 1 (next step) +- [ ] Validate sqlc + SQLite VIEW + FTS5 compatibility during Phase 6 planning (research flag) +- [ ] Design queue test architecture during Phase 4 planning (research flag) +- [ ] Determine library scan test fixture strategy during Phase 5 planning (research flag) +- [ ] Measure startup time with large library before Phase 7 lazy loading work + +### Blockers + +None currently. + +### Warnings + +- Player lock ordering (`p.mu` before `speaker.Lock()`, goroutine dispatch in beep callback) — do NOT refactor lock-sensitive paths; extract pure logic only +- modernc.org/libc version must match exactly when updating modernc.org/sqlite +- `@lit-labs/signals` is experimental (v0.2.0) — not blocking but noted + +## Session Continuity + +### Last Session + +**Date:** 2026-02-27 +**What happened:** Project initialized — codebase analysis, research, requirements definition, roadmap creation +**Where we stopped:** Roadmap created with 8 phases covering 26 requirements +**Next action:** `/gsd-plan-phase 1` to create execution plan for Concurrency Race Fixes + +### Context for Next Session + +- All 26 v1 requirements mapped across 8 phases +- Dependency chain: correctness → test infra → tests → SQL/perf optimization → frontend +- Phase 1 is 4 requirements (CORR-01 to CORR-04), all mechanical mutex additions +- Research says Phase 1 fixes are "textbook race, LOW effort" — standard patterns, skip research-phase + +--- +*State initialized: 2026-02-27* +*Last updated: 2026-02-27*