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
This commit is contained in:
+10
-10
@@ -9,11 +9,11 @@ Requirements for Format Parity milestone. Each maps to roadmap phases.
|
|||||||
|
|
||||||
### OGG Vorbis Tag Writing
|
### 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
|
- [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
|
||||||
- [ ] **OGG-02**: OGG tag writes preserve existing non-edited Vorbis Comment fields (ReplayGain, lyrics, etc.)
|
- [x] **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)
|
- [x] **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
|
- [x] **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-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
|
- [ ] **OGG-06**: OGG writer round-trip tests verify all fields via dhowden/tag read-back
|
||||||
|
|
||||||
### WAV Tag Writing
|
### WAV Tag Writing
|
||||||
@@ -71,11 +71,11 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| WAV-04 | Phase 19 | Complete |
|
| WAV-04 | Phase 19 | Complete |
|
||||||
| WAV-05 | Phase 19 | Complete |
|
| WAV-05 | Phase 19 | Complete |
|
||||||
| WAV-06 | Phase 19 | Complete |
|
| WAV-06 | Phase 19 | Complete |
|
||||||
| OGG-01 | Phase 20 | Pending |
|
| OGG-01 | Phase 20 | Complete |
|
||||||
| OGG-02 | Phase 20 | Pending |
|
| OGG-02 | Phase 20 | Complete |
|
||||||
| OGG-03 | Phase 20 | Pending |
|
| OGG-03 | Phase 20 | Complete |
|
||||||
| OGG-04 | Phase 20 | Pending |
|
| OGG-04 | Phase 20 | Complete |
|
||||||
| OGG-05 | Phase 20 | Pending |
|
| OGG-05 | Phase 20 | Complete |
|
||||||
| OGG-06 | Phase 20 | Pending |
|
| OGG-06 | Phase 20 | Pending |
|
||||||
| CLEAN-01 | Phase 21 | Pending |
|
| CLEAN-01 | Phase 21 | Pending |
|
||||||
| CLEAN-02 | Phase 21 | Pending |
|
| CLEAN-02 | Phase 21 | Pending |
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ Plans:
|
|||||||
3. Editing an OGG file's tags does not alter audio playback — the file sounds identical before and after
|
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
|
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)
|
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:
|
Plans:
|
||||||
- [ ] 20-01-PLAN.md — OGG page parser/writer, Vorbis Comment serializer, writeOggTags, pipeline integration
|
- [ ] 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 |
|
| 17. Single Track Edit | v1.2 | 2/2 | Complete | 2026-03-18 |
|
||||||
| 18. Batch 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 | - |
|
| 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 | - |
|
| 21. Cleanup | v1.2.1 | 0/? | Not started | - |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+18
-14
@@ -2,13 +2,13 @@
|
|||||||
gsd_state_version: 1.0
|
gsd_state_version: 1.0
|
||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: unknown
|
status: in-progress
|
||||||
last_updated: "2026-03-19T13:03:37.978Z"
|
last_updated: "2026-03-19T17:53:47Z"
|
||||||
progress:
|
progress:
|
||||||
total_phases: 1
|
total_phases: 1
|
||||||
completed_phases: 1
|
completed_phases: 1
|
||||||
total_plans: 2
|
total_plans: 4
|
||||||
completed_plans: 2
|
completed_plans: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
# YellowJacket — Project State
|
# YellowJacket — Project State
|
||||||
@@ -18,14 +18,14 @@ progress:
|
|||||||
See: .planning/PROJECT.md (updated 2026-03-18)
|
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.
|
**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
|
## Current Position
|
||||||
|
|
||||||
Phase: 19 — WAV Tag Writer (COMPLETE)
|
Phase: 20 — OGG Vorbis Tag Writer (IN PROGRESS)
|
||||||
Plan: 2 of 2 (all complete)
|
Plan: 1 of 2 complete
|
||||||
Status: Phase complete — all WAV requirements (WAV-01 through WAV-06) verified
|
Status: Plan 01 complete (implementation) — Plan 02 pending (tests)
|
||||||
Last activity: 2026-03-19 — Completed 19-02-PLAN.md (WAV tag writer tests)
|
Last activity: 2026-03-19 — Completed 20-01-PLAN.md (OGG Vorbis tag writer implementation)
|
||||||
|
|
||||||
```
|
```
|
||||||
v1.2.1 Format Parity
|
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-01 | WAV tag writer impl | 5 min | 2 | 4 |
|
||||||
| 19-02 | WAV tag writer tests | 9 min | 3 | 2 |
|
| 19-02 | WAV tag writer tests | 9 min | 3 | 2 |
|
||||||
|
| 20-01 | OGG Vorbis tag writer impl | 3 min | 1 | 4 |
|
||||||
|
|
||||||
## Accumulated Context
|
## 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
|
- 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 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)
|
- 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)
|
### Warnings (carry forward)
|
||||||
|
|
||||||
@@ -86,9 +90,9 @@ All decisions archived in PROJECT.md Key Decisions table and RETROSPECTIVE.md. K
|
|||||||
### Last Session
|
### Last Session
|
||||||
|
|
||||||
**Date:** 2026-03-19
|
**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.
|
**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 19-02-PLAN.md — Phase 19 complete
|
**Where we stopped:** Completed 20-01-PLAN.md
|
||||||
**Next action:** `/gsd-plan-phase` for next phase (OGG Vorbis or next milestone phase)
|
**Next action:** Execute 20-02-PLAN.md (OGG Vorbis tag writer tests)
|
||||||
|
|
||||||
---
|
---
|
||||||
*State initialized: 2026-02-27*
|
*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/) |
|
| 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/) |
|
| 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 activity: 2026-03-19 - completed 20-01-PLAN.md
|
||||||
*Last updated: 2026-03-19 — completed 19-02-PLAN.md (WAV tag writer tests — Phase 19 complete)*
|
*Last updated: 2026-03-19 — completed 20-01-PLAN.md (OGG Vorbis tag writer implementation)*
|
||||||
|
|||||||
@@ -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*
|
||||||
Reference in New Issue
Block a user