diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 439a565..ff7dd5c 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -12,7 +12,7 @@ NetSynth is built in four phases ordered by technical risk. Phase 1 validates th Decimal phases appear between their surrounding integers in numeric order. -- [ ] **Phase 1: Capture and Classification** - Live packet capture, protocol identification, and CLI scaffolding — no audio yet +- [x] **Phase 1: Capture and Classification** - Live packet capture, protocol identification, and CLI scaffolding — no audio yet (completed 2026-03-25) - [ ] **Phase 2: Audio Synthesis Engine** - Oscillators, EMA amplitude smoothing, mixing, and MP3 encoding against synthetic inputs - [ ] **Phase 3: Pipeline Integration and MVP** - Wire capture into synthesis, Ctrl+C with valid MP3 output, auto-clustering of unknown traffic - [ ] **Phase 4: Power User Features** - BPF capture filter, offline pcap file input @@ -29,13 +29,13 @@ Decimal phases appear between their surrounding integers in numeric order. 3. User running without root/CAP_NET_RAW sees a clear error message with a `sudo` hint — not a panic or silent failure 4. On exit, user sees a per-protocol packet count summary printed to stderr 5. User can pass `--verbose` and see per-window protocol activity lines on stderr -**Plans:** 3/4 plans executed +**Plans:** 4/4 plans complete Plans: - [x] 01-01-PLAN.md — Go 1.24 setup, module init, shared types, config-driven classifier with tests - [x] 01-02-PLAN.md — Capture package: OpenCapture, ListInterfaces, privilege error handling - [x] 01-03-PLAN.md — Aggregation: time-windowed accumulator, exit summary, verbose output -- [ ] 01-04-PLAN.md — CLI wiring: Cobra commands, signal handling, pipeline assembly, smoke test +- [x] 01-04-PLAN.md — CLI wiring: Cobra commands, signal handling, pipeline assembly, smoke test ### Phase 2: Audio Synthesis Engine **Goal**: The synthesis and encoding stack produces a valid MP3 from synthetic WindowSnapshot inputs — audio pipeline fully validated before any real traffic flows through it @@ -77,7 +77,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 1. Capture and Classification | 3/4 | In Progress| | +| 1. Capture and Classification | 4/4 | Complete | 2026-03-25 | | 2. Audio Synthesis Engine | 0/? | Not started | - | | 3. Pipeline Integration and MVP | 0/? | Not started | - | | 4. Power User Features | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 60a9a4f..1b96108 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,14 +2,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: Ready to execute -stopped_at: Completed 01-02-PLAN.md -last_updated: "2026-03-25T11:18:58.336Z" +status: Phase complete — ready for verification +stopped_at: Completed 01-04-PLAN.md +last_updated: "2026-03-25T12:18:00.863Z" progress: total_phases: 4 - completed_phases: 0 + completed_phases: 1 total_plans: 4 - completed_plans: 3 + completed_plans: 4 --- # Project State @@ -49,6 +49,7 @@ Plan: 4 of 4 | Phase 01 P01 | 4 | 2 tasks | 6 files | | Phase 01 P03 | 8 | 2 tasks | 4 files | | Phase 01-capture-and-classification P02 | 3min | 1 tasks | 4 files | +| Phase 01-capture-and-classification P04 | 15min | 2 tasks | 2 files | ## Accumulated Context @@ -70,6 +71,8 @@ Recent decisions affecting current work: - [Phase 01-capture-and-classification]: Use net.Interfaces() for listing (go-pcap has no FindAllDevs equivalent); privileges not required for enumeration - [Phase 01-capture-and-classification]: StartCapture uses 512-buffered channel with atomic drop counter to prevent backpressure blocking capture goroutine - [Phase 01-capture-and-classification]: Dynamic link type detection via handle.LinkType() not hardcoded LinkTypeEthernet +- [Phase 01-04]: Cobra RunE + signal.NotifyContext for clean shutdown: context cancellation is the single stop signal propagating through all three pipeline stages +- [Phase 01-04]: Three-stage pipeline: capture -> classify goroutine -> aggregate via buffered channels; 1024-buffered classified channel absorbs burst processing ### Pending Todos @@ -83,6 +86,6 @@ None yet. ## Session Continuity -Last session: 2026-03-25T11:18:58.329Z -Stopped at: Completed 01-02-PLAN.md +Last session: 2026-03-25T12:18:00.856Z +Stopped at: Completed 01-04-PLAN.md Resume file: None diff --git a/.planning/phases/01-capture-and-classification/01-04-SUMMARY.md b/.planning/phases/01-capture-and-classification/01-04-SUMMARY.md new file mode 100644 index 0000000..bb9eef7 --- /dev/null +++ b/.planning/phases/01-capture-and-classification/01-04-SUMMARY.md @@ -0,0 +1,131 @@ +--- +phase: 01-capture-and-classification +plan: 04 +subsystem: cli +tags: [go, cobra, signal-handling, channels, pipeline, cli, stderr-output] + +# Dependency graph +requires: + - phase: 01-capture-and-classification + provides: capture.StartCapture, capture.ListInterfaces, capture.OpenCapture from capture/capture.go (Plan 02) + - phase: 01-capture-and-classification + provides: classify.Classifier, classify.DefaultRules, classify.ClassifiedPacket types from classify/ (Plan 01) + - phase: 01-capture-and-classification + provides: aggregate.Aggregate, aggregate.PrintSummary, aggregate.PrintWindowLine, aggregate.AccumulateTotals from aggregate/ (Plan 03) + +provides: + - Cobra CLI binary (cmd/netsynth/main.go) wiring all three pipeline stages + - -i / --interface flag for specifying capture interface + - --list-interfaces flag that enumerates available interfaces and exits + - --verbose flag enabling per-window protocol activity on stderr + - Ctrl+C / SIGTERM clean shutdown with Aggregate done-channel propagation + - Exit summary showing per-protocol packet counts and percentages + +affects: [02-audio-synthesis] + +# Tech tracking +tech-stack: + added: + - github.com/spf13/cobra v1.10.2 (Cobra CLI framework) + patterns: + - "Cobra RunE pattern: RunE returns error, Cobra handles exit code" + - "signal.NotifyContext for clean SIGINT/SIGTERM shutdown — cancels context which closes packet channel which drains pipeline" + - "Three-stage pipeline via goroutine + channels: capture -> classify -> aggregate" + - "Atomic drop counter (droppedPtr) surfaced at exit if non-zero" + +key-files: + created: + - cmd/netsynth/main.go + - cmd/netsynth/main_test.go + modified: [] + +key-decisions: + - "Cobra RunE (not Run) used so errors propagate cleanly to stderr and exit code 1" + - "signal.NotifyContext chosen over manual signal.Notify channel — cancels context automatically on SIGINT/SIGTERM, simpler shutdown chain" + - "classified channel buffered at 1024 to absorb burst traffic between capture and aggregate goroutines" + - "Permission error message lives in capture.StartCapture (Plan 02); main.go just returns it — single source of truth for platform-specific sudo hint" + +patterns-established: + - "Pattern: context cancellation is the single stop signal — capture reads ctx.Done(), packet channel close propagates to classify goroutine, which closes classified channel, which drains Aggregate" + - "Pattern: pipeline stages communicate only via channels — no shared state beyond atomic drop counter" + +requirements-completed: [CAPT-01, CAPT-02, CAPT-04, CLAS-01, CLAS-03, CLAS-04] + +# Metrics +duration: ~15min +completed: 2026-03-25 +--- + +# Phase 01 Plan 04: CLI Integration Summary + +**Cobra CLI wiring all three pipeline stages (capture -> classify -> aggregate) with signal-handling, --verbose per-window stderr output, and Ctrl+C exit summary — completes Phase 1 runnable netsynth binary** + +## Performance + +- **Duration:** ~15 min +- **Started:** 2026-03-25T11:25:00Z +- **Completed:** 2026-03-25T11:40:00Z +- **Tasks:** 2 (1 code + 1 human-verify checkpoint) +- **Files modified:** 2 + +## Accomplishments + +- cmd/netsynth/main.go wires capture, classify, and aggregate packages into a three-stage goroutine pipeline with buffered channels +- Cobra CLI exposes -i/--interface, --list-interfaces, and --verbose flags with correct validation and error messages +- signal.NotifyContext propagates SIGINT/SIGTERM through context cancellation to cleanly drain all pipeline stages before exit +- Per-window verbose output enabled via onSnapshot callback into aggregate.PrintWindowLine on stderr +- Exit summary printed via aggregate.PrintSummary after pipeline drains — shows per-protocol packet counts with percentages +- Binary builds with CGO_ENABLED=0 (Phase 1 has no CGo dependency; LAME is deferred to Phase 2+) +- Manual smoke test approved: live capture, verbose output, and Ctrl+C summary all verified on real interface + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Wire Cobra CLI with capture-classify-aggregate pipeline and signal handling** - `1be56a5` (feat) +2. **Task 2: Smoke test live capture on real interface** - checkpoint:human-verify (approved by user, no code commit) + +**Plan metadata:** TBD (docs: complete plan) + +## Files Created/Modified + +- `cmd/netsynth/main.go` - Cobra root command, run() pipeline assembly, runListInterfaces(), signal handling +- `cmd/netsynth/main_test.go` - Tests: TestListInterfacesFlag, TestMissingInterfaceFlag, TestHelpOutput + +## Decisions Made + +- Cobra RunE (not Run) pattern used so error propagates cleanly — Cobra prints to stderr and sets exit code 1 +- signal.NotifyContext preferred over manual signal channel — context cancellation is already the pipeline stop signal, so one mechanism handles both +- classified channel buffered at 1024 to absorb classify goroutine burst processing without blocking packet capture +- Permission error message owned by capture.StartCapture, not main.go — keeps platform-specific hint in one place + +## Deviations from Plan + +None — plan executed exactly as written. Task 1 implementation matched the plan's code template precisely. All acceptance criteria passed. + +## Issues Encountered + +None — build succeeded on first attempt, tests passed, smoke test approved. + +## User Setup Required + +**Live capture requires elevated privileges.** Two options: +1. Run as root: `sudo ./netsynth -i eth0` +2. Grant capability: `sudo setcap cap_net_raw+eip ./netsynth` then run without sudo + +## Next Phase Readiness + +- Phase 1 complete: capture, classify, aggregate, and CLI all wired and verified +- Phase 2 (audio synthesis) receives WindowSnapshot channel from aggregate.Aggregate — the Phase 2 synthesizer plugs in between the Aggregate output and the final exit summary +- No blockers for Phase 2; frequency mapping and oscillator math are the next open design decisions + +## Self-Check: PASSED + +- `cmd/netsynth/main.go` exists +- `cmd/netsynth/main_test.go` exists +- `01-04-SUMMARY.md` exists +- Commit `1be56a5` (feat(01-04): wire Cobra CLI) confirmed in git history + +--- +*Phase: 01-capture-and-classification* +*Completed: 2026-03-25*