diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index bd55d5f..8f06528 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -23,7 +23,7 @@ Requirements for Format Parity milestone. Each maps to roadmap phases. - [x] **WAV-03**: WAV tag writes preserve audio data identically (lossless round-trip) - [x] **WAV-04**: User can embed, replace, and remove cover art in WAV files via ID3v2 APIC frame - [x] **WAV-05**: WAV tag writing uses crash-safe atomic writes (write-to-temp-then-rename) -- [ ] **WAV-06**: WAV writer round-trip tests verify all fields via dhowden/tag read-back +- [x] **WAV-06**: WAV writer round-trip tests verify all fields via dhowden/tag read-back ### Cleanup @@ -70,7 +70,7 @@ Which phases cover which requirements. Updated during roadmap creation. | WAV-03 | Phase 19 | Complete | | WAV-04 | Phase 19 | Complete | | WAV-05 | Phase 19 | Complete | -| WAV-06 | Phase 19 | Pending | +| WAV-06 | Phase 19 | Complete | | OGG-01 | Phase 20 | Pending | | OGG-02 | Phase 20 | Pending | | OGG-03 | Phase 20 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index ebc0d08..242a79e 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -52,7 +52,7 @@ ### v1.2.1 Format Parity (Phases 19-21) -- [ ] **Phase 19: WAV Tag Writer** — Full metadata and cover art writing for WAV files via ID3v2-in-RIFF +- [x] **Phase 19: WAV Tag Writer** — Full metadata and cover art writing for WAV files via ID3v2-in-RIFF (completed 2026-03-19) - [ ] **Phase 20: OGG Vorbis Tag Writer** — Full metadata and cover art writing for OGG Vorbis files via custom page rewriter - [ ] **Phase 21: Cleanup** — Fix lint warnings and small issues carried forward from v1.2 @@ -68,7 +68,7 @@ 3. Editing a WAV file's tags does not alter audio playback — the file sounds identical before and after 4. Existing metadata in the WAV file that wasn't edited (RIFF INFO chunks, bext, cue markers) survives the tag write unchanged 5. If the app crashes or loses power during a WAV tag write, the original file is intact (not corrupted or truncated) -**Plans:** 1/2 plans executed +**Plans:** 2/2 plans complete Plans: - [ ] 19-01-PLAN.md — WAV RIFF parser/writer and writeWavTags function @@ -117,7 +117,7 @@ Plans: | 16. Tag Writing & Database Sync | v1.2 | 3/3 | Complete | 2026-03-17 | | 17. Single Track Edit | v1.2 | 2/2 | Complete | 2026-03-18 | | 18. Batch Edit | v1.2 | 2/2 | Complete | 2026-03-18 | -| 19. WAV Tag Writer | 1/2 | In Progress| | - | +| 19. WAV Tag Writer | 2/2 | Complete | 2026-03-19 | - | | 20. OGG Vorbis Tag Writer | v1.2.1 | 0/? | Not started | - | | 21. Cleanup | v1.2.1 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 52bcd98..b7aac16 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,12 +3,12 @@ gsd_state_version: 1.0 milestone: "v1.2.1" milestone_name: "Format Parity" status: executing -last_updated: "2026-03-19T12:45:01.000Z" +last_updated: "2026-03-19T12:58:09.000Z" progress: total_phases: 3 - completed_phases: 0 + completed_phases: 1 total_plans: 2 - completed_plans: 1 + completed_plans: 2 --- # YellowJacket — Project State @@ -18,18 +18,18 @@ progress: See: .planning/PROJECT.md (updated 2026-03-18) **Core value:** The music player works reliably and feels solid — every interaction is correct, responsive, and trustworthy. -**Current focus:** v1.2.1 Format Parity — executing Phase 19 (WAV Tag Writer) +**Current focus:** v1.2.1 Format Parity — Phase 19 complete, ready for next phase ## Current Position -Phase: 19 — WAV Tag Writer -Plan: 2 of 2 -Status: Executing — completed 19-01, next 19-02 -Last activity: 2026-03-19 — Completed 19-01-PLAN.md (WAV tag writer implementation) +Phase: 19 — WAV Tag Writer (COMPLETE) +Plan: 2 of 2 (all complete) +Status: Phase complete — all WAV requirements (WAV-01 through WAV-06) verified +Last activity: 2026-03-19 — Completed 19-02-PLAN.md (WAV tag writer tests) ``` v1.2.1 Format Parity -[███░░░░░░░░░░░░░░░░░] 1/3 phases (in progress) +[███████░░░░░░░░░░░░░] 1/3 phases complete ``` ## Performance Metrics @@ -41,6 +41,7 @@ v1.2.1 Format Parity | Phase | Plan | Duration | Tasks | Files | |-------|------|----------|-------|-------| | 19-01 | WAV tag writer impl | 5 min | 2 | 4 | +| 19-02 | WAV tag writer tests | 9 min | 3 | 2 | ## Accumulated Context @@ -61,6 +62,7 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K - Three-state field model via implicit dirty tracking (editValues map presence) - Custom RIFF parser for WAV: lenient-read/strict-write, ID3v2 chunk at end of file - WAV writer reuses MP3's applyTextChanges/applyCoverArtChanges for ID3v2 tag manipulation +- WAV test read-back uses bogem/id3v2.ParseReader (dhowden/tag ReadFrom does not support WAV) ### Warnings (carry forward) @@ -84,9 +86,9 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K ### Last Session **Date:** 2026-03-19 -**What happened:** Executed 19-01-PLAN.md — WAV tag writer implementation. Created RIFF parser/writer, writeWavTags function, FormatWAV constant, pipeline dispatch. Fixed album_artist TPE2 mapping. -**Where we stopped:** Completed 19-01-PLAN.md -**Next action:** `/gsd-execute-phase 19` to execute 19-02-PLAN.md (WAV tag writer tests) +**What happened:** Executed 19-02-PLAN.md — WAV tag writer tests. Created 7 round-trip tests verifying all WAV requirements (WAV-01 through WAV-06). Used bogem/id3v2 ParseReader for read-back. +**Where we stopped:** Completed 19-02-PLAN.md — Phase 19 complete +**Next action:** `/gsd-plan-phase` for next phase (OGG Vorbis or next milestone phase) --- *State initialized: 2026-02-27* @@ -99,5 +101,5 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K | 18 | add multi-column metadata display to playlist-details | 2026-03-08 | ce23177 | [18-add-multi-column-metadata-display-to-pla](./quick/18-add-multi-column-metadata-display-to-pla/) | | 19 | fix phantom playlist tracks with multi-root path resolution | 2026-03-16 | 9144ded | [19-fix-phantom-playlist-tracks](./quick/19-fix-phantom-playlist-tracks/) | -Last activity: 2026-03-19 - completed 19-01-PLAN.md -*Last updated: 2026-03-19 — completed 19-01-PLAN.md (WAV tag writer implementation)* +Last activity: 2026-03-19 - completed 19-02-PLAN.md +*Last updated: 2026-03-19 — completed 19-02-PLAN.md (WAV tag writer tests — Phase 19 complete)* diff --git a/.planning/phases/19-wav-tag-writer/19-02-SUMMARY.md b/.planning/phases/19-wav-tag-writer/19-02-SUMMARY.md new file mode 100644 index 0000000..2c61d87 --- /dev/null +++ b/.planning/phases/19-wav-tag-writer/19-02-SUMMARY.md @@ -0,0 +1,125 @@ +--- +phase: 19-wav-tag-writer +plan: 02 +subsystem: tagwriter +tags: [wav, riff, id3v2, round-trip-tests, bogem-id3v2] + +# Dependency graph +requires: + - phase: 19-wav-tag-writer + provides: "writeWavTags function, RIFF parser/writer, FormatWAV pipeline dispatch" +provides: + - "7 WAV round-trip tests covering all WAV requirements (WAV-01 through WAV-06)" + - "createTestWAV fixture builder for WAV test files" + - "readWavID3Tags read-back helper using bogem/id3v2 ParseReader" + - "createTestWAVWithExtraChunks for chunk preservation testing" +affects: [20-ogg-vorbis-tag-writer] + +# Tech tracking +tech-stack: + added: [] + patterns: ["bogem/id3v2 ParseReader for WAV ID3v2 read-back (dhowden/tag ReadFrom does not support WAV)", "RIFF chunk preservation verification via byte-equal comparison"] + +key-files: + created: + - backend/tagwriter/wav_test.go + modified: + - backend/tagwriter/wav.go + +key-decisions: + - "Used bogem/id3v2.ParseReader instead of dhowden/tag.ReadID3v2Tags for test read-back — handles empty tags (cleared cover art) correctly" + - "Fixed wsl lint warning in wav.go writeRIFF (cuddled copy expression) from Plan 01" + +patterns-established: + - "WAV test read-back: extract id3 chunk via parseRIFF, parse with bogem/id3v2.ParseReader, convert to TrackMetadata" + - "Chunk preservation testing: compare pre/post byte data for each non-ID3 chunk" + +requirements-completed: [WAV-01, WAV-02, WAV-03, WAV-04, WAV-05, WAV-06] + +# Metrics +duration: 9min +completed: 2026-03-19 +--- + +# Phase 19 Plan 02: WAV Tag Writer Tests Summary + +**7 round-trip tests for WAV ID3v2 tag writing: text fields, cover art, clear art, partial update, chunk preservation, atomic safety, and RF64 rejection** + +## Performance + +- **Duration:** 9 min +- **Started:** 2026-03-19T12:48:10Z +- **Completed:** 2026-03-19T12:58:09Z +- **Tasks:** 3 +- **Files modified:** 2 + +## Accomplishments +- Created test fixture builder (createTestWAV) producing minimal valid WAV files with optional ID3v2 tags +- Created RIFF-aware read-back helper using bogem/id3v2.ParseReader (dhowden/tag cannot read WAV files) +- Verified all 9 text fields round-trip correctly (Title, Artist, Album, AlbumArtist, Genre, Year, TrackNumber, DiscNumber, Composer) +- Verified cover art embed, replace, and clear operations +- Verified partial updates preserve unchanged fields +- Verified non-ID3v2 chunks (fmt, data, LIST INFO, bext) are byte-identical after tag write +- Verified atomic safety: failed write leaves original file untouched +- Verified RF64 files are rejected with clear error message +- Fixed all wsl lint warnings in WAV files (zero remaining lint issues in wav.go and wav_test.go) + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create WAV test fixture builder and read-back helper** - `21fe172` (test) +2. **Task 2: Write round-trip tests for all WAV requirements** - `1b28882` (test) +3. **Task 3: Full test suite verification and lint fixes** - `f11b523` (style) + +## Files Created/Modified +- `backend/tagwriter/wav_test.go` - 7 test functions, 3 test helpers (createTestWAV, readWavID3Tags, createTestWAVWithExtraChunks), ~665 lines +- `backend/tagwriter/wav.go` - Fixed wsl lint warning (cuddled copy expression in writeRIFF) + +## Decisions Made +- Used bogem/id3v2.ParseReader instead of dhowden/tag.ReadID3v2Tags for WAV read-back — dhowden/tag.ReadID3v2Tags fails on empty tags (after clearing all APIC frames), while bogem handles all cases +- Fixed lint warning in wav.go from Plan 01 (in scope since it's a phase-19 file) + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] dhowden/tag ReadID3v2Tags fails on empty ID3v2 tags** +- **Found during:** Task 2 (TestWriteWavTags_ClearCoverArt) +- **Issue:** Plan specified using `tag.ReadID3v2Tags()` for read-back, but it fails with EOF when parsing an ID3v2 tag with no frames (after clearing all cover art) +- **Fix:** Switched readWavID3Tags helper to use `bogem/id3v2.ParseReader()` which handles empty tags correctly, then manually extracts fields from the bogem tag object +- **Files modified:** backend/tagwriter/wav_test.go +- **Verification:** TestWriteWavTags_ClearCoverArt passes +- **Committed in:** 1b28882 (Task 2 commit) + +**2. [Rule 3 - Blocking] wsl lint warnings in wav_test.go and wav.go** +- **Found during:** Task 3 (make lint) +- **Issue:** Multiple "only cuddled expressions if assigning variable or using from line above" warnings from wsl linter +- **Fix:** Added blank lines before cuddled expressions in both wav_test.go and wav.go +- **Files modified:** backend/tagwriter/wav_test.go, backend/tagwriter/wav.go +- **Verification:** make lint shows zero warnings in WAV files +- **Committed in:** f11b523 (Task 3 commit) + +--- + +**Total deviations:** 2 auto-fixed (1 bug, 1 blocking) +**Impact on plan:** ReadID3v2Tags limitation required alternative approach for read-back; lint fixes are mechanical. No scope creep. + +## Issues Encountered +None + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- WAV tag writer is fully implemented and tested (WAV-01 through WAV-06 complete) +- Phase 19 (WAV Tag Writer) is complete +- Ready for Phase 20 (OGG Vorbis Tag Writer) or next milestone phase + +## Self-Check: PASSED + +All created files verified on disk. All commit hashes found in git log. wav_test.go is 664 lines (exceeds 200 min_lines requirement). + +--- +*Phase: 19-wav-tag-writer* +*Completed: 2026-03-19*