Files
2026-03-26 22:06:36 +01:00

5.8 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
06-config-package-and-sound-overrides 01 config
toml
BurntSushi/toml
config-loading
partial-merge
validation
phase provides
05-waveform-types-and-bank-decoupling WaveformType enum, WaveformPresetHarmonics, FreqConfig.WaveformType field
phase provides
01-capture-and-classification classify.TrafficClass, classify.AllClasses, 14 class constants
config.Load(configPath string) returns map[classify.TrafficClass]synth.FreqConfig
SoundOverride struct with pointer fields for partial-merge semantics
TOML file parsing with unknown-key detection via BurntSushi/toml Undecoded()
Auto-discovery of ./netsynth.toml and ~/.config/netsynth/config.toml
Per-field overlay merge preserving unspecified defaults
Waveform string validation before merge (fail fast)
06-02 (CLI flag wiring
--config flag passes configPath to config.Load)
encode package (RunSynthesis will accept merged config map from config.Load)
added patterns
github.com/BurntSushi/toml v1.6.0 — TOML parsing with MetaData.Undecoded() for unknown-key detection
Pointer fields (*float64, *string) in decode struct for partial-override semantics (nil = not set)
parseFile → validate → merge pipeline for fail-fast config loading (D-11)
Dedicated config package for testable isolation from Cobra/CLI concerns
created modified
config/config.go
config/config_test.go
go.mod
go.sum
Used BurntSushi/toml v1.6.0 over pelletier/go-toml v2 — Undecoded() returns structured []Key (not formatted string), easier to extract key name for error messages
Shallow copy in copyDefaults() is safe because merge reconstructs Harmonics via WaveformPresetHarmonics rather than mutating the original slice
Unknown class names produce stderr warning (not error) per D-09, preparing for Phase 7 user-defined classes
Config package is independent of cmd/ — no Cobra imports, fully unit-testable
Merge functions take defaults map by value and modify in place, returning it
CFG-01
CFG-02
CFG-04
CFG-05
3min 2026-03-26

Phase 6 Plan 01: Config Package Summary

TOML-based config loader with pointer-field partial merge, BurntSushi/toml Undecoded() unknown-key detection, and XDG auto-discovery at ./netsynth.toml and ~/.config/netsynth/config.toml

Performance

  • Duration: ~3 min
  • Started: 2026-03-26T19:55:08Z
  • Completed: 2026-03-26T19:57:45Z
  • Tasks: 1 (TDD: red → green)
  • Files modified: 4 (config/config.go, config/config_test.go, go.mod, go.sum)

Accomplishments

  • Created config package with single Load(configPath string) public API
  • Implemented pointer-field partial merge: only non-nil fields override defaults (CFG-04)
  • Added BurntSushi/toml Undecoded() for field-level typo detection (CFG-05)
  • Auto-discovery of netsynth.toml in working dir and ~/.config/netsynth/config.toml (CFG-02)
  • Explicit file missing returns clear error; auto-discovery missing is silent (CFG-02/CFG-03)
  • Harmonics regenerated via WaveformPresetHarmonics when waveform or frequency is overridden
  • All 9 tests pass; go vet clean

Task Commits

Each task committed atomically via TDD:

  1. RED - Failing tests - b9ec05a (test): 9 test functions for CFG-01 through CFG-05
  2. GREEN - Full implementation - 1f877e7 (feat): config.Load, merge, validate, discover

Note: TDD task has two commits (RED test stub → GREEN implementation)

Files Created/Modified

  • config/config.go - Load(), SoundOverride, rawConfig, merge, validate, discoverPath
  • config/config_test.go - 9 test functions covering all CFG requirements
  • go.mod - Added github.com/BurntSushi/toml v1.6.0
  • go.sum - Updated checksum for new dependency

Decisions Made

  • BurntSushi/toml over pelletier/go-toml v2: Undecoded() returns []toml.Key ([]string slices) — structured, allowing exact key name extraction for error messages. pelletier's DisallowUnknownFields returns a formatted string (harder to extract just the key name).
  • Shallow copy in copyDefaults(): Safe because merge code always replaces Harmonics with a freshly generated slice from WaveformPresetHarmonics rather than mutating the original. Documented with comment for future maintainers.
  • Unknown class warning (not error): Following D-09 to emit fmt.Fprintf(os.Stderr, "Warning: ...") for unknown class names. Phase 7 user-defined classes will be valid, so this is by design.

Deviations from Plan

None - plan executed exactly as written. The worktree needed a rebase onto master to include phase 05 code (WaveformType, WaveformPresetHarmonics) before starting — this was a prerequisite resolution, not a deviation.

Issues Encountered

  • Worktree was based on remote origin/master (pre-phase-05). Rebased onto local master to get WaveformType and WaveformPresetHarmonics before implementation. No code conflicts.

User Setup Required

None - no external service configuration required. BurntSushi/toml is fetched automatically via go get.

Next Phase Readiness

  • config.Load() is ready for wiring into cmd/netsynth/main.go via --config flag (Plan 06-02)
  • encode.RunSynthesis signature change (accept freqCfgs map[classify.TrafficClass]synth.FreqConfig) is needed in Plan 06-02
  • All 14 default classes always present in result map — safe to pass directly to synth.NewBank()

Self-Check: PASSED

  • FOUND: config/config.go
  • FOUND: config/config_test.go
  • FOUND: .planning/phases/06-config-package-and-sound-overrides/06-01-SUMMARY.md
  • FOUND: b9ec05a (RED commit — failing tests)
  • FOUND: 1f877e7 (GREEN commit — full implementation)

Phase: 06-config-package-and-sound-overrides Completed: 2026-03-26