From d289390396007457eaf24f8c8109ab1fdb36e9f9 Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Thu, 19 Mar 2026 13:55:39 -0400 Subject: [PATCH] docs(20-01): complete OGG Vorbis tag writer implementation plan - SUMMARY.md with implementation details and decisions - STATE.md updated with position, metrics, and key decisions - ROADMAP.md updated with Phase 20 progress (1/2 plans) - REQUIREMENTS.md: OGG-01 through OGG-05 marked complete --- .planning/REQUIREMENTS.md | 20 ++-- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 32 +++--- .../20-ogg-vorbis-tag-writer/20-01-SUMMARY.md | 107 ++++++++++++++++++ 4 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 .planning/phases/20-ogg-vorbis-tag-writer/20-01-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 8f06528..7e90aa5 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -9,11 +9,11 @@ Requirements for Format Parity milestone. Each maps to roadmap phases. ### OGG Vorbis Tag Writing -- [ ] **OGG-01**: User can edit all 8 text metadata fields (title, artist, album, album_artist, genre, year, track#, disc#, composer) on OGG Vorbis files -- [ ] **OGG-02**: OGG tag writes preserve existing non-edited Vorbis Comment fields (ReplayGain, lyrics, etc.) -- [ ] **OGG-03**: OGG tag writes preserve audio data identically (lossless round-trip) -- [ ] **OGG-04**: User can embed, replace, and remove cover art in OGG Vorbis files via METADATA_BLOCK_PICTURE -- [ ] **OGG-05**: OGG tag writing uses crash-safe atomic writes (write-to-temp-then-rename) +- [x] **OGG-01**: User can edit all 8 text metadata fields (title, artist, album, album_artist, genre, year, track#, disc#, composer) on OGG Vorbis files +- [x] **OGG-02**: OGG tag writes preserve existing non-edited Vorbis Comment fields (ReplayGain, lyrics, etc.) +- [x] **OGG-03**: OGG tag writes preserve audio data identically (lossless round-trip) +- [x] **OGG-04**: User can embed, replace, and remove cover art in OGG Vorbis files via METADATA_BLOCK_PICTURE +- [x] **OGG-05**: OGG tag writing uses crash-safe atomic writes (write-to-temp-then-rename) - [ ] **OGG-06**: OGG writer round-trip tests verify all fields via dhowden/tag read-back ### WAV Tag Writing @@ -71,11 +71,11 @@ Which phases cover which requirements. Updated during roadmap creation. | WAV-04 | Phase 19 | Complete | | WAV-05 | Phase 19 | Complete | | WAV-06 | Phase 19 | Complete | -| OGG-01 | Phase 20 | Pending | -| OGG-02 | Phase 20 | Pending | -| OGG-03 | Phase 20 | Pending | -| OGG-04 | Phase 20 | Pending | -| OGG-05 | Phase 20 | Pending | +| OGG-01 | Phase 20 | Complete | +| OGG-02 | Phase 20 | Complete | +| OGG-03 | Phase 20 | Complete | +| OGG-04 | Phase 20 | Complete | +| OGG-05 | Phase 20 | Complete | | OGG-06 | Phase 20 | Pending | | CLEAN-01 | Phase 21 | Pending | | CLEAN-02 | Phase 21 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 2906ee2..260925a 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -84,7 +84,7 @@ Plans: 3. Editing an OGG file's tags does not alter audio playback — the file sounds identical before and after 4. Existing Vorbis Comments that weren't edited (ReplayGain, lyrics, custom fields) survive the tag write unchanged 5. If the app crashes or loses power during an OGG tag write, the original file is intact (not corrupted or truncated) -**Plans:** 2 plans +**Plans:** 1/2 plans executed Plans: - [ ] 20-01-PLAN.md — OGG page parser/writer, Vorbis Comment serializer, writeOggTags, pipeline integration @@ -122,7 +122,7 @@ Plans: | 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 | 2/2 | Complete | 2026-03-19 | - | -| 20. OGG Vorbis Tag Writer | v1.2.1 | 0/2 | Planned | - | +| 20. OGG Vorbis Tag Writer | 1/2 | In Progress| | - | | 21. Cleanup | v1.2.1 | 0/? | Not started | - | --- diff --git a/.planning/STATE.md b/.planning/STATE.md index c063b29..9de0418 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,13 +2,13 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: unknown -last_updated: "2026-03-19T13:03:37.978Z" +status: in-progress +last_updated: "2026-03-19T17:53:47Z" progress: total_phases: 1 completed_phases: 1 - total_plans: 2 - completed_plans: 2 + total_plans: 4 + completed_plans: 3 --- # YellowJacket — Project State @@ -18,14 +18,14 @@ 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 — Phase 19 complete, ready for next phase +**Current focus:** v1.2.1 Format Parity — Phase 20 in progress (OGG Vorbis tag writer) ## Current Position -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) +Phase: 20 — OGG Vorbis Tag Writer (IN PROGRESS) +Plan: 1 of 2 complete +Status: Plan 01 complete (implementation) — Plan 02 pending (tests) +Last activity: 2026-03-19 — Completed 20-01-PLAN.md (OGG Vorbis tag writer implementation) ``` v1.2.1 Format Parity @@ -42,6 +42,7 @@ v1.2.1 Format Parity |-------|------|----------|-------|-------| | 19-01 | WAV tag writer impl | 5 min | 2 | 4 | | 19-02 | WAV tag writer tests | 9 min | 3 | 2 | +| 20-01 | OGG Vorbis tag writer impl | 3 min | 1 | 4 | ## Accumulated Context @@ -63,6 +64,9 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K - 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) +- Custom OGG CRC32 with precomputed lookup table (hash/crc32 uses incompatible reflected bit ordering) +- Raw byte preservation for Vorbis Comment entries — [][]byte instead of []string for non-UTF-8 safety +- METADATA_BLOCK_PICTURE + legacy COVERART/COVERARTMIME stripping on all OGG cover art operations ### Warnings (carry forward) @@ -86,9 +90,9 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K ### Last Session **Date:** 2026-03-19 -**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) +**What happened:** Executed 20-01-PLAN.md — OGG Vorbis tag writer implementation. Created custom OGG page parser/writer with MSB-first CRC32, Vorbis Comment packet serializer with METADATA_BLOCK_PICTURE cover art, and pipeline integration. +**Where we stopped:** Completed 20-01-PLAN.md +**Next action:** Execute 20-02-PLAN.md (OGG Vorbis tag writer tests) --- *State initialized: 2026-02-27* @@ -101,5 +105,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-02-PLAN.md -*Last updated: 2026-03-19 — completed 19-02-PLAN.md (WAV tag writer tests — Phase 19 complete)* +Last activity: 2026-03-19 - completed 20-01-PLAN.md +*Last updated: 2026-03-19 — completed 20-01-PLAN.md (OGG Vorbis tag writer implementation)* diff --git a/.planning/phases/20-ogg-vorbis-tag-writer/20-01-SUMMARY.md b/.planning/phases/20-ogg-vorbis-tag-writer/20-01-SUMMARY.md new file mode 100644 index 0000000..1a419cb --- /dev/null +++ b/.planning/phases/20-ogg-vorbis-tag-writer/20-01-SUMMARY.md @@ -0,0 +1,107 @@ +--- +phase: 20-ogg-vorbis-tag-writer +plan: 01 +subsystem: tagwriter +tags: [ogg, vorbis, crc32, metadata, cover-art, vorbis-comment, metadata-block-picture] + +# Dependency graph +requires: + - phase: 19-wav-tag-writer + provides: AtomicWrite pattern, TagChanges interface, pipeline dispatch pattern +provides: + - OGG Vorbis tag writing (text fields + cover art) + - Custom OGG page parser/writer with MSB-first CRC32 + - Vorbis Comment packet parse/serialize with raw byte preservation + - METADATA_BLOCK_PICTURE base64 encoding for OGG cover art + - FormatOGG constant and pipeline integration +affects: [21-ogg-vorbis-tag-writer-tests, metadata, tagwriter] + +# Tech tracking +tech-stack: + added: [] + patterns: [OGG page parser/writer, MSB-first CRC32 lookup table, Vorbis Comment raw byte preservation, base64 METADATA_BLOCK_PICTURE encoding] + +key-files: + created: + - backend/tagwriter/ogg.go + - backend/tagwriter/ogg_vorbis.go + modified: + - backend/tagwriter/tagwriter.go + - backend/tagwriter/pipeline.go + +key-decisions: + - "Custom OGG CRC32 with precomputed 256-entry lookup table (Go's hash/crc32 uses incompatible reflected bit ordering)" + - "Raw byte preservation for non-edited Vorbis Comment entries to avoid corrupting non-UTF-8 tags" + - "Combined comment+setup header pages per Vorbis spec with 255-segment-per-page splitting" + +patterns-established: + - "OGG page parser: lenient-read (warn on CRC mismatch) / strict-write (always correct CRC)" + - "Vorbis Comment raw byte entries: [][]byte instead of []string for non-UTF-8 safety" + - "METADATA_BLOCK_PICTURE + legacy COVERART/COVERARTMIME stripping on all cover art operations" + +requirements-completed: [OGG-01, OGG-02, OGG-03, OGG-04, OGG-05] + +# Metrics +duration: 3min +completed: 2026-03-19 +--- + +# Phase 20 Plan 01: OGG Vorbis Tag Writer Implementation Summary + +**Custom OGG page parser/writer with MSB-first CRC32, Vorbis Comment packet serializer with METADATA_BLOCK_PICTURE cover art, and pipeline integration for .ogg files** + +## Performance + +- **Duration:** 3 min +- **Started:** 2026-03-19T17:50:03Z +- **Completed:** 2026-03-19T17:53:47Z +- **Tasks:** 1 +- **Files modified:** 4 + +## Accomplishments +- Custom OGG page parser with lenient CRC and strict validation (single-stream Vorbis only) +- MSB-first CRC32 lookup table matching libogg reference implementation +- Vorbis Comment parse/serialize with raw byte preservation for non-edited fields +- METADATA_BLOCK_PICTURE base64 cover art encoding with legacy field stripping +- Full pipeline integration: FormatOGG constant, .ogg detection, writeOggTags dispatch + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create OGG page parser/writer with CRC32 and writeOggTags entry point** - `5e98c03` (feat) + +## Files Created/Modified +- `backend/tagwriter/ogg.go` - OGG page parser/writer, CRC32 lookup table, writeOggTags entry point, packet extraction/splitting, page building +- `backend/tagwriter/ogg_vorbis.go` - Vorbis Comment packet parse/serialize, field manipulation, METADATA_BLOCK_PICTURE encoding, text/cover art change application +- `backend/tagwriter/tagwriter.go` - Added FormatOGG constant and .ogg case in DetectFormat +- `backend/tagwriter/pipeline.go` - Added case FormatOGG dispatch to writeOggTags + +## Decisions Made +- Used custom MSB-first CRC32 implementation (Go's hash/crc32 uses reflected bit ordering — incompatible with OGG spec) +- Raw byte entries ([][]byte) for Vorbis Comment fields instead of strings — preserves non-UTF-8 tags from other tools +- Comment and setup header packets share pages per Vorbis spec; page splitting at 255-segment boundaries handles large cover art +- Page sequence numbers renumbered from 0 after header page count changes + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- OGG tag writer implementation complete, ready for round-trip tests (Plan 02) +- All existing MP3/FLAC/WAV tests pass (no regressions verified) +- `go build` and `go vet` pass clean + +## Self-Check: PASSED + +All files verified on disk, all commits found in git log. + +--- +*Phase: 20-ogg-vorbis-tag-writer* +*Completed: 2026-03-19*