Core value: The music player works reliably and feels solid — every interaction is correct, responsive, and trustworthy.
Current focus: v1.1 Multi-Library Support + Performance Optimization
Current Position
Phase: 14 — Performance Optimization
Plan: 4 of 4 in Phase (Plans 01, 02, 03 complete; 04 awaiting checkpoint)
Status: Plan 14-03 complete — render & store optimization; 14-04 awaiting checkpoint
Progress: ████████████████████ Phase 14 in progress (3/4 plans complete, 1 checkpoint pending)
Last activity: 2026-03-14 — Completed 14-03 render & store optimization
Phase Overview
Phase
Status
9. Scan Cancellation & Keyboard Shortcuts
Complete (5/5 plans) ✅
10. Schema & Migration
Complete (2/2 plans) ✅
11. Per-Library Scan Pipeline
Complete (3/3 plans) ✅
12. Library CRUD & Data Integrity
In progress (1/2 plans)
13. Library Views & Phantom Tracks
Not started
14. Performance Optimization
In progress (4/4 plans, checkpoint pending)
Performance Metrics
v1.0 baseline: 8 phases, 17 plans, 34 tasks in 6 days (107 commits)
v1.1 scope: Phase 9 complete (5 plans), Phases 10-13 pending (20 requirements across 4 phases)
Phase
Plan
Duration
Tasks
Files
09-01
scan control backend
16 min
2
5
09-02
keyboard shortcuts config & service
35 min
2
12
09-04
keyboard shortcuts settings UI
5 min
2
2
09-03
scan control UI
2 min
1
3
09-05
integration testing & verification
3 min
2
1
Phase 10-01 P01
11 min
2 tasks
10 files
Phase 10-02 P02
5 min
2 tasks
9 files
Phase 11-01 P01
7 min
2 tasks
11 files
Phase 11-03 P03
10 min
1 task
3 files
Phase 11-02 P02
4 min
2 tasks
2 files
Phase 12-01 P01
6 min
2 tasks
6 files
Phase 14-02 P02
1 min
1 task
1 file
Phase 14-03 P03
4 min
2 tasks
5 files
Phase 14-01 P01
3 min
2 tasks
7 files
Phase 14-04 P04
2 min
2 tasks
3 files
Accumulated Context
Key Decisions
Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns to carry forward:
Pre-populate phantom metadata BEFORE cascade delete
Avoids lost join data — playlist_tracks need track metadata after audio_files rows are gone
Phase 14 Decisions
Decision
Rationale
Primary views cached, detail views ephemeral
Detail views depend on entity IDs that change; caching would show stale content
Inline style.display toggle over CSS class
Simpler, no specificity issues, empty string restores natural display value
viewCache bounded at 6 entries
One per primary view — negligible memory since data is already in store caches
contain: strict only on .main-panel
Has explicit dimensions (flex: 1, overflow: hidden); elsewhere use layout style to not break flex
will-change: transform only on scroll containers
Not on :host — avoids wasting GPU memory on non-scrolling elements
content-visibility: auto on album cards with contain-intrinsic-size
Prevents layout shift during scroll while skipping off-screen rendering
Event delegation via data-index + closest() for virtualizer items
Zero per-item closures in renderItem; all events delegated on virtualizer element
changeGeneration counter in library store
Simpler than typed subscriptions; skips requestUpdate on loading-only transitions
RAF throttle over debounce for scroll saves
Saves position once per frame during scrolling, not just after stop; prevents lost positions on quick navigation
Keep monkey-patch alongside overflow-anchor CSS
CSS overflow-anchor disables browser anchoring but not lit-virtualizer's internal _correctScrollError
Warnings (carry forward)
Player lock ordering (p.mu before speaker.Lock(), goroutine dispatch in beep callback) — carry forward
modernc.org/libc version must match exactly when updating modernc.org/sqlite
@lit-labs/signals is experimental (v0.2.0) — not blocking but noted
Scan cancellation: skip orphan cleanup on cancelled scans — Phase 9 ✅ (implemented in 09-01)
Volume mutations (ChangeVolume/MuteToggle) must emit events + persist state — Phase 9 ✅ (fixed in 09-05)
ALTER TABLE ADD COLUMN requires DEFAULT for NOT NULL — create libraries table first
Table rebuild must audit ALL CASCADE FKs (playlist_tracks AND queue_tracks)
FTS5 contentless can't DELETE rows — stale entries accumulate after library removal; consider contentless_delete migration
Orphan cleanup must not delete shared entities across libraries (reference-counting bottom-up)
Existing user migration must be seamless (TOML DirectoryPath to DB libraries table)
Deferred Improvements
Bulk phantom matching performance — FindPhantomMatches runs 3 sequential DB queries per phantom track (basename search, FTS filename, FTS keywords). With hundreds of phantoms this is O(n×3) round trips. Could batch the basename query (WHERE basename IN (...)), pre-load FTS results, or parallelize with goroutines. Not urgent now that the false-phantom bug is fixed (tracks appeared phantom due to empty library root, not actual missing files). Revisit if users import large playlists from external sources with genuinely unresolved paths.
Research Flags
Multi-library research complete — see .planning/research/ (STACK.md, FEATURES.md, ARCHITECTURE.md, PITFALLS.md, SUMMARY.md)
Session Continuity
Last Session
Date: 2026-03-14
What happened: Executed Phase 14, Plan 03 — event delegation eliminates per-scroll-frame closures, queueMicrotask batching for queue store, changeGeneration counter for library store. Plan 04 Tasks 1-2 were completed earlier, awaiting checkpoint.
Where we stopped: Completed 14-03-PLAN.md — Plans 01, 02, 03 complete; 14-04 awaiting human-verify checkpoint
Next action: User verifies scroll smoothness and navigation speed across all views (14-04 Task 3 checkpoint)
State initialized: 2026-02-27
Quick Tasks Completed
#
Description
Date
Commit
Directory
16
add ctrl+a hotkey to multi-select views to select all items