diff --git a/.planning/phases/06-config-package-and-sound-overrides/06-CONTEXT.md b/.planning/phases/06-config-package-and-sound-overrides/06-CONTEXT.md new file mode 100644 index 0000000..5d19f77 --- /dev/null +++ b/.planning/phases/06-config-package-and-sound-overrides/06-CONTEXT.md @@ -0,0 +1,111 @@ +# Phase 6: Config Package and Sound Overrides - Context + +**Gathered:** 2026-03-26 +**Status:** Ready for planning + + +## Phase Boundary + +Add a TOML-based configuration system that lets users override frequency and waveform per traffic class, with auto-discovery from standard paths, explicit `--config` flag, partial override semantics (only specified fields change), and strict unknown-key validation. Wire the merged config into the synthesis pipeline via the injection seam created in Phase 5. + +Requirements covered: CFG-01 through CFG-05. + + + + +## Implementation Decisions + +### TOML Schema Design +- **D-01:** Use keyed TOML tables `[sounds.]` for per-class overrides. Each table supports `frequency` (float64, Hz) and `waveform` (string: "sine", "square", "sawtooth", "triangle"). Class names match `classify.TrafficClass` string values (e.g., `[sounds.ICMP]`, `[sounds.HTTPS]`). +- **D-02:** Top-level structure is flat — no deeply nested hierarchies. Future phases (custom rules) will add `[[rules]]` array-of-tables at the top level. + +### Config Merge Semantics +- **D-03:** Per-field overlay merge — only fields explicitly set in TOML override defaults. Unspecified fields retain their built-in values. For example, setting only `frequency` for ICMP leaves its waveform and harmonics unchanged. This satisfies CFG-04 (partial override without replicating entire config). +- **D-04:** Merge produces a `map[classify.TrafficClass]FreqConfig` that is passed to `synth.NewBank()` via the injection seam from Phase 5. The default map is `synth.ClassFreqConfigs`. + +### Auto-Discovery and Precedence +- **D-05:** Discovery order (most-specific wins): `--config ` > `./netsynth.toml` > `~/.config/netsynth/config.toml`. If `--config` is specified and the file does not exist, exit with a clear error before capture begins (CFG-03). If no config is found via auto-discovery, proceed silently with defaults (CFG-02). +- **D-06:** Only one config file is loaded — no multi-file merge. The first found in precedence order wins entirely. + +### Validation and Error Reporting +- **D-07:** Unknown keys cause an immediate startup error naming the unrecognized key (CFG-05). Use TOML strict decoding to detect unknown keys. Suggest the closest valid key name if edit distance is small (nice-to-have, Claude's discretion on implementation). +- **D-08:** Type mismatches (e.g., `frequency = "not a number"`) produce a clear error with field name and expected type, before capture begins. +- **D-09:** Unknown class names in `[sounds.]` produce a warning (not error) — this prepares for Phase 7 where user-defined class names are valid. + +### Pipeline Wiring +- **D-10:** `encode.RunSynthesis` signature changes to accept the merged config map (or loads config internally). The `--config` flag is added to the Cobra root command in `cmd/netsynth/main.go`. +- **D-11:** Config loading happens once at startup, before any capture begins — fail fast on all config errors. + +### Claude's Discretion +- TOML library choice (BurntSushi/toml vs pelletier/go-toml) — researcher should evaluate both +- Whether to create a dedicated `config` package or keep loading in `cmd/netsynth` +- Waveform string-to-WaveformType mapping implementation details +- Edit distance algorithm for typo suggestions (or skip if complexity isn't justified) + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Injection Seam (Phase 5 output) +- `synth/bank.go` — `NewBank(tau float64, cfgs map[classify.TrafficClass]FreqConfig)` — the injection point for merged config +- `synth/config.go` — `ClassFreqConfigs` default map, `FreqConfig` struct with `WaveformType` field, `WaveformPresetHarmonics()` function +- `encode/mp3.go` — `RunSynthesis()` calls `synth.NewBank(1.0, synth.ClassFreqConfigs)` — the call site to modify + +### CLI Entry Point +- `cmd/netsynth/main.go` — Cobra command setup, flag definitions, `run()` function that dispatches to live/pcap modes + +### Requirements +- `.planning/REQUIREMENTS.md` — CFG-01 through CFG-05 acceptance criteria + +### Prior Context +- `.planning/phases/05-waveform-types-and-bank-decoupling/05-CONTEXT.md` — Phase 5 decisions (D-02 WaveformType, D-05 bank injection seam) + +No external specs — requirements fully captured in decisions above. + + + + +## Existing Code Insights + +### Reusable Assets +- `synth.ClassFreqConfigs` — Default config map (14 entries), serves as base for merge +- `synth.WaveformType` enum — Maps to TOML waveform strings (sine/square/sawtooth/triangle) +- `synth.NewBank(tau, cfgs)` — Already accepts injected config map (Phase 5) +- `classify.TrafficClass` (string type) — Keys for config map, matches TOML section names +- `classify.AllClasses()` — Returns all 14 built-in class names for validation + +### Established Patterns +- Cobra for CLI flags — add `--config` flag in same pattern as existing flags +- `encode.RunSynthesis` is the single call site for synthesis — modification point is narrow +- Package-level vars (`ClassFreqConfigs`, `DefaultRules`) serve as defaults — config system overlays on top + +### Integration Points +- `cmd/netsynth/main.go:run()` — Config loading inserts between flag parsing and capture start +- `encode.RunSynthesis()` — Must receive merged config map (currently hardcoded to `synth.ClassFreqConfigs`) +- `synth.FreqConfig.WaveformType` field — Set from TOML waveform string after parsing + + + + +## Specific Ideas + +No specific requirements — standard TOML config pattern with partial merge semantics. + + + + +## Deferred Ideas + +- `--print-config` command (CFG-06) — scoped to Phase 7 +- Custom classification rules (`[[rules]]` TOML blocks) — scoped to Phase 7 +- Config hot-reload — explicitly out of scope per REQUIREMENTS.md + + + +--- + +*Phase: 06-config-package-and-sound-overrides* +*Context gathered: 2026-03-26* diff --git a/.planning/phases/06-config-package-and-sound-overrides/06-DISCUSSION-LOG.md b/.planning/phases/06-config-package-and-sound-overrides/06-DISCUSSION-LOG.md new file mode 100644 index 0000000..582233d --- /dev/null +++ b/.planning/phases/06-config-package-and-sound-overrides/06-DISCUSSION-LOG.md @@ -0,0 +1,75 @@ +# Phase 6: Config Package and Sound Overrides - Discussion Log + +> **Audit trail only.** Do not use as input to planning, research, or execution agents. +> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered. + +**Date:** 2026-03-26 +**Phase:** 06-config-package-and-sound-overrides +**Areas discussed:** TOML structure, Config merge, Auto-discovery precedence, Error reporting +**Mode:** --auto (all areas auto-selected, recommended defaults chosen) + +--- + +## TOML Structure + +| Option | Description | Selected | +|--------|-------------|----------| +| Keyed table `[sounds.]` | Natural TOML pattern, matches traffic class names | ✓ | +| Flat key-value pairs | Simpler but doesn't scale to per-class overrides | | +| Nested `[sounds..audio]` | Unnecessary nesting depth | | + +**User's choice:** [auto] Keyed table `[sounds.]` (recommended default) +**Notes:** Matches classify.TrafficClass string values directly. Supports `frequency` and `waveform` fields per class. + +--- + +## Config Merge Semantics + +| Option | Description | Selected | +|--------|-------------|----------| +| Per-field overlay | Only specified fields override defaults (CFG-04) | ✓ | +| Full section replace | Setting any field in a class replaces all fields | | +| Deep merge with arrays | Overkill for flat config structure | | + +**User's choice:** [auto] Per-field overlay (recommended default) +**Notes:** Satisfies CFG-04 requirement. User sets one field, everything else keeps defaults. + +--- + +## Auto-Discovery Precedence + +| Option | Description | Selected | +|--------|-------------|----------| +| Local > user > flag | Most-specific wins: --config > ./netsynth.toml > ~/.config/ | ✓ | +| Flag only | Simpler but no auto-discovery (violates CFG-02) | | +| Multi-file merge | Load and merge all found configs | | + +**User's choice:** [auto] Local > user-level > flag (recommended default) +**Notes:** Standard CLI convention. Only one file loaded — no multi-file merge complexity. + +--- + +## Error Reporting + +| Option | Description | Selected | +|--------|-------------|----------| +| Fail-fast with key name + suggestion | Exit at startup, name the bad key (CFG-05) | ✓ | +| Warning and continue | Tolerant but hides mistakes | | +| Strict with no suggestions | Simpler but less helpful | | + +**User's choice:** [auto] Fail-fast with key name and optional typo suggestion (recommended default) +**Notes:** Matches CFG-05 requirement. Unknown class names are warnings (not errors) to prepare for Phase 7. + +--- + +## Claude's Discretion + +- TOML library choice +- Package organization (dedicated `config` package vs inline) +- Waveform string mapping implementation +- Edit distance for typo suggestions + +## Deferred Ideas + +- `--print-config` (CFG-06) — Phase 7 +- Custom rules `[[rules]]` — Phase 7