Files
yoloyolo/.planning/phases/04-power-user-features/04-CONTEXT.md
T
2026-03-26 14:09:07 +01:00

5.2 KiB

Phase 4: Power User Features - Context

Gathered: 2026-03-26 Status: Ready for planning

## Phase Boundary

Two additive CLI features: BPF capture filter (--filter flag) and offline pcap file input (--read flag). Both feed into the existing classify → aggregate → synthesis pipeline. No changes to audio synthesis, classification rules, or MP3 encoding.

## Implementation Decisions

Pcap file timing

  • D-01: Use packet timestamps from the pcap file to assign packets to 500ms time windows. Processing is fast — a 10-minute pcap produces a 10-minute MP3 in seconds.
  • D-02: Preserve time gaps as silence. Windows with zero packets during gaps produce silent audio sections. MP3 duration faithfully matches the pcap file's time span.

Flag interaction rules

  • D-03: --read and -i are mutually exclusive. Error if both provided. --read replaces -i as the packet source.
  • D-04: --filter works with both -i (live capture) and --read (pcap file). BPF filter applies to whichever packet source is active.
  • D-05: --read without -o derives output filename from input: capture.pcapcapture.mp3.

Offline processing feedback

  • D-06: Bookend messages: "Reading <file>..." at start, then protocol summary + "Saved" line at end. No progress bar — processing is fast enough that it would flash by.
  • D-07: --verbose works with --read — per-window protocol activity lines scroll by quickly. Consistent behavior regardless of packet source.

Claude's Discretion

  • BPF filter validation approach (pre-validate before opening capture vs let go-pcap/gopacket reject it)
  • Pcap file format detection and error messages for corrupt/unreadable files
  • Implementation of timestamp-based windowing (new aggregation path vs adapter that feeds existing Aggregate())
  • How to handle pcap files with no packets (reuse existing zero-packet guard from OUT-03)

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Project context

  • .planning/PROJECT.md — Core value, constraints (Go, MP3 output, non-interactive)
  • .planning/REQUIREMENTS.md — CAPT-05 (BPF filter), CAPT-06 (pcap file input)

Prior phase context

  • .planning/phases/01-capture-and-classification/01-CONTEXT.md — Phase 1 decisions; pure-Go pcap backend, classifier design, privilege model
  • .planning/phases/02-audio-synthesis-engine/02-CONTEXT.md — Phase 2 decisions; tone mapping, mixing, encoding
  • .planning/phases/03-pipeline-integration-and-mvp/03-CONTEXT.md — Phase 3 decisions; hash-bucketing, encoding feedback format

Key source files (integration points)

  • cmd/netsynth/main.go — CLI wiring; Cobra flags, pipeline assembly, encoding feedback output
  • capture/capture.goOpenCapture() and StartCapture() — will need filter parameter and pcap file reading path
  • aggregate/window.goAggregate() function using real-time ticks; pcap mode needs timestamp-based windowing
  • encode/mp3.goRunSynthesis() entry point; no changes expected
  • classify/types.goWindowSnapshot struct (input contract for synthesis)

Stack decisions

  • CLAUDE.md — Technology stack section; packetcap/go-pcap for capture, gopacket/gopacket for decoding
  • .planning/research/STACK.md — Library recommendations and alternatives

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • capture.StartCapture(ctx, iface) — live capture pipeline; pcap file reading needs a parallel entry point returning the same <-chan gopacket.Packet
  • classify.NewClassifier(rules) / classifier.Classify(pkt) — reused unchanged for both live and pcap sources
  • aggregate.Aggregate(done, classified, windowMs, onSnapshot) — reused for live; pcap needs timestamp-based variant
  • encode.RunSynthesis([]WindowSnapshot, path) — reused unchanged
  • aggregate.PrintSummary() / aggregate.PrintWindowLine() — reused for both modes

Established Patterns

  • Channel-based pipeline: capture → classify → aggregate → synthesis
  • done <-chan struct{} for shutdown signaling via signal.NotifyContext
  • Buffered channels for stage decoupling (512 capture, 1024 classified, 8 aggregate)
  • io.Writer injection for testable output
  • Cobra flag-based CLI with RunE function

Integration Points

  • main.go — Add --filter and --read Cobra flags; branch run() into live vs pcap paths
  • capture/capture.go — Add filter parameter to OpenCapture(); add new ReadPcapFile() function
  • aggregate/window.go — Add timestamp-based windowing function for offline mode (or adapter)

</code_context>

## Specific Ideas
  • --read + --filter is a key workflow: capture broad with tcpdump, then sonify a subset
  • Output filename derivation (capture.pcapcapture.mp3) follows ffmpeg conventions
  • Pcap file processing should feel instant — no unnecessary waiting or progress indicators
  • BPF filter errors should fail fast before any capture begins, with a clear message
## Deferred Ideas

None — discussion stayed within phase scope


Phase: 04-power-user-features Context gathered: 2026-03-26