chore: archive v1.1 phase directories to milestones
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
---
|
||||
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>
|
||||
Reference in New Issue
Block a user