Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
263 lines
10 KiB
Markdown
263 lines
10 KiB
Markdown
---
|
|
phase: 06-config-package-and-sound-overrides
|
|
plan: 02
|
|
type: execute
|
|
wave: 2
|
|
depends_on: ["06-01"]
|
|
files_modified:
|
|
- encode/mp3.go
|
|
- encode/mp3_test.go
|
|
- cmd/netsynth/main.go
|
|
autonomous: true
|
|
requirements:
|
|
- CFG-03
|
|
|
|
must_haves:
|
|
truths:
|
|
- "User passes --config /path/to/file.toml and the tool uses that file for sound overrides"
|
|
- "User passes --config /nonexistent.toml and the tool exits with a clear error before capture"
|
|
- "User runs without --config and auto-discovery kicks in (or defaults used silently)"
|
|
- "RunSynthesis uses the merged config map instead of hardcoded ClassFreqConfigs"
|
|
artifacts:
|
|
- path: "cmd/netsynth/main.go"
|
|
provides: "--config flag, config.Load call, passing merged map to RunSynthesis"
|
|
contains: "configPath"
|
|
- path: "encode/mp3.go"
|
|
provides: "RunSynthesis with freqCfgs parameter"
|
|
contains: "freqCfgs map[classify.TrafficClass]synth.FreqConfig"
|
|
- path: "encode/mp3_test.go"
|
|
provides: "Updated tests for new RunSynthesis signature"
|
|
key_links:
|
|
- from: "cmd/netsynth/main.go"
|
|
to: "config/config.go"
|
|
via: "config.Load(configPath)"
|
|
pattern: "config\\.Load"
|
|
- from: "cmd/netsynth/main.go"
|
|
to: "encode/mp3.go"
|
|
via: "encode.RunSynthesis(snapshots, outputPath, freqCfgs)"
|
|
pattern: "encode\\.RunSynthesis.*freqCfgs"
|
|
- from: "encode/mp3.go"
|
|
to: "synth/bank.go"
|
|
via: "synth.NewBank(1.0, freqCfgs) using passed-in config"
|
|
pattern: "synth\\.NewBank.*freqCfgs"
|
|
---
|
|
|
|
<objective>
|
|
Wire the config package into the CLI and synthesis pipeline. Add `--config` flag to Cobra, call `config.Load` at startup, change `RunSynthesis` signature to accept the merged config map, and update all call sites.
|
|
|
|
Purpose: Completes CFG-03 (explicit --config flag) and D-10 (RunSynthesis signature change). After this plan, the end-to-end flow works: user creates TOML -> tool loads it -> synthesis uses overridden frequencies/waveforms.
|
|
|
|
Output: Updated `cmd/netsynth/main.go`, `encode/mp3.go`, `encode/mp3_test.go`
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/06-config-package-and-sound-overrides/06-CONTEXT.md
|
|
@.planning/phases/06-config-package-and-sound-overrides/06-01-SUMMARY.md
|
|
|
|
<interfaces>
|
|
<!-- Key types and contracts the executor needs. -->
|
|
|
|
From config/config.go (created in Plan 01):
|
|
```go
|
|
// Load finds, parses, validates, and merges a config file.
|
|
// configPath is the --config flag value; empty string triggers auto-discovery.
|
|
func Load(configPath string) (map[classify.TrafficClass]synth.FreqConfig, error)
|
|
```
|
|
|
|
From encode/mp3.go (current signature to change):
|
|
```go
|
|
// Current:
|
|
func RunSynthesis(snapshots []classify.WindowSnapshot, outputPath string) error
|
|
// New:
|
|
func RunSynthesis(snapshots []classify.WindowSnapshot, outputPath string, freqCfgs map[classify.TrafficClass]synth.FreqConfig) error
|
|
```
|
|
|
|
From cmd/netsynth/main.go (existing flags pattern):
|
|
```go
|
|
var (
|
|
ifaceName string
|
|
listIfaces bool
|
|
verbose bool
|
|
outputPath string
|
|
bpfFilter string
|
|
readPath string
|
|
)
|
|
// Flag registration pattern:
|
|
rootCmd.Flags().StringVar(&bpfFilter, "filter", "", "BPF filter expression")
|
|
```
|
|
|
|
From synth/config.go:
|
|
```go
|
|
var ClassFreqConfigs = map[classify.TrafficClass]FreqConfig{ /* 14 entries */ }
|
|
```
|
|
</interfaces>
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Change RunSynthesis signature and update encode tests</name>
|
|
<files>encode/mp3.go, encode/mp3_test.go</files>
|
|
<read_first>
|
|
encode/mp3.go (current RunSynthesis signature and body)
|
|
encode/mp3_test.go (current test calls to RunSynthesis)
|
|
synth/config.go (ClassFreqConfigs, FreqConfig type)
|
|
classify/types.go (TrafficClass type)
|
|
</read_first>
|
|
<action>
|
|
**encode/mp3.go changes:**
|
|
|
|
1. Add `freqCfgs map[classify.TrafficClass]synth.FreqConfig` as third parameter to RunSynthesis:
|
|
```
|
|
func RunSynthesis(snapshots []classify.WindowSnapshot, outputPath string, freqCfgs map[classify.TrafficClass]synth.FreqConfig) error
|
|
```
|
|
|
|
2. Change line 57 from:
|
|
```
|
|
bank := synth.NewBank(1.0, synth.ClassFreqConfigs)
|
|
```
|
|
to:
|
|
```
|
|
bank := synth.NewBank(1.0, freqCfgs)
|
|
```
|
|
|
|
3. No other changes to encode/mp3.go.
|
|
|
|
**encode/mp3_test.go changes:**
|
|
|
|
4. Update `TestMP3Valid` (line 56): change `RunSynthesis(snaps, tmpPath)` to `RunSynthesis(snaps, tmpPath, synth.ClassFreqConfigs)`.
|
|
|
|
5. Update `TestZeroPacketError` (line 101): change `RunSynthesis([]classify.WindowSnapshot{}, tmpPath)` to `RunSynthesis([]classify.WindowSnapshot{}, tmpPath, synth.ClassFreqConfigs)`.
|
|
|
|
6. Update `TestZeroPacketError` (line 121): change `RunSynthesis(zeroSnaps, tmpPath2)` to `RunSynthesis(zeroSnaps, tmpPath2, synth.ClassFreqConfigs)`.
|
|
|
|
The `synth` import is already present in mp3_test.go.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/dev/workspace/yoloyolo && go build ./encode/... && go test ./encode/... -count=1 -run TestZeroPacketError</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- encode/mp3.go contains `func RunSynthesis(snapshots []classify.WindowSnapshot, outputPath string, freqCfgs map[classify.TrafficClass]synth.FreqConfig) error`
|
|
- encode/mp3.go contains `synth.NewBank(1.0, freqCfgs)` (not synth.ClassFreqConfigs)
|
|
- encode/mp3_test.go contains `RunSynthesis(snaps, tmpPath, synth.ClassFreqConfigs)`
|
|
- encode/mp3_test.go contains `RunSynthesis([]classify.WindowSnapshot{}, tmpPath, synth.ClassFreqConfigs)`
|
|
- encode/mp3_test.go contains `RunSynthesis(zeroSnaps, tmpPath2, synth.ClassFreqConfigs)`
|
|
- `go build ./encode/...` exits 0
|
|
- `go test ./encode/... -count=1 -run TestZeroPacketError` exits 0
|
|
</acceptance_criteria>
|
|
<done>
|
|
RunSynthesis accepts injected config map. All encode tests updated and passing.
|
|
</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Add --config flag and wire config.Load into main.go</name>
|
|
<files>cmd/netsynth/main.go</files>
|
|
<read_first>
|
|
cmd/netsynth/main.go (full file — flag definitions, run function, runLiveMode, runPcapMode)
|
|
config/config.go (Load function signature)
|
|
encode/mp3.go (updated RunSynthesis signature from Task 1)
|
|
</read_first>
|
|
<action>
|
|
**cmd/netsynth/main.go changes:**
|
|
|
|
1. Add `configPath` to the var block (after `readPath`):
|
|
```go
|
|
configPath string // NEW: --config flag (CFG-03)
|
|
```
|
|
|
|
2. Add import for config package in the import block:
|
|
```go
|
|
"github.com/netsynth/netsynth/config"
|
|
```
|
|
Also add import for `synth` package (needed for ClassFreqConfigs fallback reference — though config.Load handles this internally):
|
|
No — `synth` is NOT needed in main.go. `config.Load` returns the full map. Only add `config` import.
|
|
|
|
3. Add flag registration in main() after the `readPath` flag line (line 44):
|
|
```go
|
|
rootCmd.Flags().StringVar(&configPath, "config", "", "Path to TOML config file (default: auto-discover)")
|
|
```
|
|
|
|
4. In the `run` function, add config loading AFTER the BPF filter validation block (after line 80) and BEFORE output path resolution (before line 83). This is per D-11 (fail fast on config errors before capture):
|
|
```go
|
|
// Load config (CFG-01 through CFG-05, D-11: fail fast)
|
|
freqCfgs, err := config.Load(configPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
```
|
|
|
|
5. The `freqCfgs` variable must be accessible in both `runLiveMode` and `runPcapMode`. Two approaches:
|
|
- Option A: Pass freqCfgs to both functions (cleanest).
|
|
- Option B: Store in a package-level var (simpler change).
|
|
|
|
Use Option A. Change signatures:
|
|
- `runLiveMode(cmd *cobra.Command) error` -> `runLiveMode(cmd *cobra.Command, freqCfgs map[classify.TrafficClass]synth.FreqConfig) error`
|
|
- `runPcapMode(cmd *cobra.Command) error` -> `runPcapMode(cmd *cobra.Command, freqCfgs map[classify.TrafficClass]synth.FreqConfig) error`
|
|
|
|
This requires adding `synth` import after all:
|
|
```go
|
|
"github.com/netsynth/netsynth/synth"
|
|
```
|
|
|
|
Update call sites in `run()`:
|
|
- Line 92: `return runPcapMode(cmd)` -> `return runPcapMode(cmd, freqCfgs)`
|
|
- Line 94: `return runLiveMode(cmd)` -> `return runLiveMode(cmd, freqCfgs)`
|
|
|
|
6. In `runLiveMode`, change the RunSynthesis call (line 147):
|
|
From: `encode.RunSynthesis(collectedSnapshots, outputPath)`
|
|
To: `encode.RunSynthesis(collectedSnapshots, outputPath, freqCfgs)`
|
|
|
|
7. In `runPcapMode`, change the RunSynthesis call (line 215):
|
|
From: `encode.RunSynthesis(collectedSnapshots, outputPath)`
|
|
To: `encode.RunSynthesis(collectedSnapshots, outputPath, freqCfgs)`
|
|
|
|
After all changes, run `go build ./cmd/netsynth/...` to verify compilation.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/dev/workspace/yoloyolo && go build ./cmd/netsynth/... && go vet ./cmd/netsynth/... && go test ./... -count=1 2>&1 | tail -20</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- cmd/netsynth/main.go contains `configPath string`
|
|
- cmd/netsynth/main.go contains `rootCmd.Flags().StringVar(&configPath, "config", ""`
|
|
- cmd/netsynth/main.go contains `config.Load(configPath)`
|
|
- cmd/netsynth/main.go contains `"github.com/netsynth/netsynth/config"` in imports
|
|
- cmd/netsynth/main.go contains `encode.RunSynthesis(collectedSnapshots, outputPath, freqCfgs)` (two occurrences — one in runLiveMode, one in runPcapMode)
|
|
- cmd/netsynth/main.go contains `runLiveMode(cmd, freqCfgs)` and `runPcapMode(cmd, freqCfgs)`
|
|
- `go build ./cmd/netsynth/...` exits 0
|
|
- `go vet ./cmd/netsynth/...` exits 0
|
|
- `go test ./... -count=1` exits 0 (full suite green)
|
|
</acceptance_criteria>
|
|
<done>
|
|
--config flag registered in Cobra. config.Load called at startup before capture. Merged config map flows through to RunSynthesis in both live and pcap modes. Full test suite passes.
|
|
</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
- `go build ./...` compiles entire project
|
|
- `go test ./... -count=1` all tests pass
|
|
- `go vet ./...` no issues
|
|
- `./netsynth --help` shows `--config` flag in output
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- --config flag appears in CLI help output (CFG-03)
|
|
- Explicit --config with missing file produces error before capture (CFG-03)
|
|
- RunSynthesis uses injected config map, not hardcoded ClassFreqConfigs (D-10)
|
|
- Full test suite passes including encode and config package tests
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/06-config-package-and-sound-overrides/06-02-SUMMARY.md`
|
|
</output>
|