diff --git a/.planning/phases/02-audio-synthesis-engine/02-CONTEXT.md b/.planning/phases/02-audio-synthesis-engine/02-CONTEXT.md
new file mode 100644
index 0000000..50ab193
--- /dev/null
+++ b/.planning/phases/02-audio-synthesis-engine/02-CONTEXT.md
@@ -0,0 +1,113 @@
+# Phase 2: Audio Synthesis Engine - Context
+
+**Gathered:** 2026-03-26
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+Oscillators, EMA amplitude smoothing, multi-layer mixing, stereo panning, and MP3 encoding — all validated against synthetic `WindowSnapshot` inputs. No live traffic flows through this phase. The output is a valid MP3 file produced from fabricated traffic data.
+
+
+
+
+## Implementation Decisions
+
+### Tone mapping
+- **D-01:** Wide ambient frequency range: 60-800 Hz across 11 traffic classes
+- **D-02:** Frequencies use musical intervals (harmonic relationships — fifths, octaves, etc.) so layers blend pleasantly
+- **D-03:** Approximate register assignments: ICMP ~65 Hz (deep bass), DNS ~110 Hz, HTTPS ~175 Hz, HTTP ~220 Hz, SSH ~330 Hz, SMTP ~440 Hz, NTP ~520 Hz, DHCP ~600 Hz, other-TCP/other-UDP ~700-800 Hz
+- **D-04:** "unknown" traffic gets a dissonant/detuned tone — slightly off-key or beating frequency that audibly signals unclassified traffic, distinct from the harmonious known classes
+
+### Waveform texture
+- **D-05:** Each drone layer uses fundamental + 2-3 harmonics (not pure sine waves) for warm, pad-like sound
+- **D-06:** Harmonic ratios vary per traffic class for subtle timbral distinction — e.g., ICMP brighter, HTTPS warmer, SSH buzzier. Each protocol has its own sonic identity beyond just pitch.
+
+### Amplitude dynamics
+- **D-07:** EMA smoothing with medium responsiveness (1-2 second attack/decay). Traffic changes are audible but smooth — not glacial, not snappy.
+- **D-08:** Layers never fade to full silence — once a traffic class has been seen, it stays at a fixed whisper floor (~2-5% of max amplitude). Quiet network still has a faint base layer.
+- **D-09:** Fixed whisper floor (not recency-based decay). Simple and predictable.
+
+### Mixing & output
+- **D-10:** Fixed equal gain per layer — each of 11 layers gets 1/11 of headroom (~0.09 max amplitude). Sum never exceeds 1.0, no clipping, no dynamic limiter needed.
+- **D-11:** Stereo output with register-based panning: bass frequencies center, mid frequencies spread left/right, higher frequencies wider. Unknown stays center to stand out.
+- **D-12:** Panning positions: ICMP center, DNS slight-L, HTTPS slight-R, HTTP center-L, SSH center-R, SMTP mid-L, NTP mid-R, DHCP wide-L, other-TCP wide-R, other-UDP wide-L, unknown center.
+- **D-13:** 44100 Hz sample rate (CD quality)
+- **D-14:** 128 kbps MP3 encoding via `sjzar/go-lame`
+- **D-15:** `-o` flag for output path; defaults to `netsynth-.mp3` when omitted
+- **D-16:** Empty (zero-packet) input produces a clear error message, not a corrupt or zero-byte MP3
+
+### Claude's Discretion
+- Exact Hz values per class (within the 60-800 Hz range, using musical intervals)
+- Specific harmonic ratios per traffic class (within the "2-3 harmonics" constraint)
+- Exact EMA alpha/decay constants to achieve the 1-2 second feel
+- Exact whisper floor percentage (within 2-5% range)
+- WAV intermediate format usage (per CLAUDE.md recommendation of go-audio/wav)
+- Stereo panning implementation (constant-power pan law vs linear)
+
+
+
+
+## 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` — SYNTH-01, SYNTH-02, SYNTH-03, OUT-01, OUT-02, OUT-03
+
+### Prior phase
+- `.planning/phases/01-capture-and-classification/01-CONTEXT.md` — Phase 1 decisions; `WindowSnapshot` contract defined here
+- `classify/types.go` — `TrafficClass` constants and `WindowSnapshot` struct (the input contract for synthesis)
+- `aggregate/window.go` — `Aggregate()` function that produces `WindowSnapshot` on 500ms intervals
+
+### Stack decisions
+- `.planning/research/STACK.md` — Library recommendations (go-lame, go-audio/wav)
+- `.planning/research/ARCHITECTURE.md` — Pipeline architecture, component boundaries
+- `CLAUDE.md` — Technology stack section with `sjzar/go-lame` v0.0.9 usage, `go-audio/wav` for intermediate format
+
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- `classify.TrafficClass` type and constants (`classify/types.go`) — 11 named classes, used as map keys in WindowSnapshot
+- `classify.AllClasses()` — returns all classes in display order; useful for iterating when setting up oscillator bank
+- `classify.WindowSnapshot` — the input contract: `Counts map[TrafficClass]int64`, `TotalPackets int64`, `WindowIndex int`
+- `aggregate.Aggregate()` — produces `chan WindowSnapshot` on 500ms ticks; Phase 2 consumes this channel
+
+### Established Patterns
+- Channel-based pipeline: capture -> classify -> aggregate -> (synthesis goes here)
+- `done <-chan struct{}` for shutdown signaling
+- Buffered channels for stage decoupling (512-buffer capture, 8-buffer aggregate output)
+- io.Writer injection for testable output (used in aggregate/summary.go)
+
+### Integration Points
+- Synthesis engine will consume `<-chan classify.WindowSnapshot` from `aggregate.Aggregate()`
+- MP3 output path comes from Cobra CLI flags (already scaffolded in `cmd/netsynth/main.go`)
+- Phase 3 wires these together; Phase 2 tests against synthetic/fabricated WindowSnapshot data
+
+
+
+
+## Specific Ideas
+
+- Sound should feel like an "ambient synth pad" — warm, layered, organic
+- Unknown traffic should be immediately recognizable as "something doesn't belong" via its dissonant tone
+- The stereo field should create a sense of space — not just mono with volume panning
+- Each protocol should have a sonic identity beyond just pitch (varied harmonic ratios)
+
+
+
+
+## Deferred Ideas
+
+None — discussion stayed within phase scope
+
+
+
+---
+
+*Phase: 02-audio-synthesis-engine*
+*Context gathered: 2026-03-26*
diff --git a/.planning/phases/02-audio-synthesis-engine/02-DISCUSSION-LOG.md b/.planning/phases/02-audio-synthesis-engine/02-DISCUSSION-LOG.md
new file mode 100644
index 0000000..ede3a70
--- /dev/null
+++ b/.planning/phases/02-audio-synthesis-engine/02-DISCUSSION-LOG.md
@@ -0,0 +1,192 @@
+# Phase 2: Audio Synthesis Engine - 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:** 02-audio-synthesis-engine
+**Areas discussed:** Tone mapping, Waveform texture, Amplitude dynamics, Mixing & headroom
+
+---
+
+## Tone Mapping
+
+### Frequency range
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Narrow ambient (80-400 Hz) | Deep, bass-heavy drones — everything in warm low register | |
+| Wide ambient (60-800 Hz) | Spread across bass to mid range — rich, layered soundscape | ✓ |
+| Full spectrum (50-2000 Hz) | Bass through high-mid — maximum separation | |
+
+**User's choice:** Wide ambient (60-800 Hz)
+**Notes:** None
+
+### Register assignment
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Keep as shown | HTTPS at ~175 Hz is low enough for bulk drone feel | ✓ |
+| Swap to match prior rule | Strictly follow bulk=low, control=mid, interactive=high | |
+| You decide | Let Claude optimize Hz values | |
+
+**User's choice:** Keep as shown
+**Notes:** None
+
+### Tuning approach
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Musical intervals | Harmonic/musical relationships so layers blend pleasantly | ✓ |
+| Arbitrary spacing | Spread evenly, simpler but may clash | |
+| You decide | Claude picks | |
+
+**User's choice:** Musical intervals
+**Notes:** None
+
+### Unknown traffic tone
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Single fixed tone at top of range | Always ~800 Hz | |
+| Dissonant/detuned tone | Off-key or beating frequency signals unclassified traffic | ✓ |
+| You decide | Claude picks | |
+
+**User's choice:** Dissonant/detuned tone
+**Notes:** None
+
+---
+
+## Waveform Texture
+
+### Richness
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Pure sine waves | Clean, minimal, ethereal — single frequency per class | |
+| Sine + 2-3 harmonics | Fundamental + overtones — warm, pad-like, textured | ✓ |
+| Unique waveform per class | Different harmonic profiles per traffic type | |
+
+**User's choice:** Sine + 2-3 harmonics
+**Notes:** None
+
+### Harmonic ratios
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Same ratios everywhere | All classes use identical harmonic recipe | |
+| Vary per class | Each class gets different harmonic weights for timbral distinction | ✓ |
+| You decide | Claude picks | |
+
+**User's choice:** Vary per class
+**Notes:** None
+
+---
+
+## Amplitude Dynamics
+
+### Responsiveness
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Slow, glacial (2-4 sec) | Layers swell and fade gradually like weather | |
+| Medium (1-2 sec) | Noticeable response, still smooth | ✓ |
+| Snappy (0.5-1 sec) | Layers track traffic closely, more reactive | |
+
+**User's choice:** Medium (1-2 sec)
+**Notes:** None
+
+### Zero-traffic behavior
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fade to full silence | Only active traffic produces sound | |
+| Fade to a whisper | Barely-audible trace remains for any seen protocol | ✓ |
+| You decide | Claude picks | |
+
+**User's choice:** Fade to a whisper
+**Notes:** None
+
+### Whisper floor type
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fixed floor | Once seen, stays at fixed very-low amplitude (2-5%) | ✓ |
+| Recency-based decay | Whisper fades further over time based on recency | |
+| You decide | Claude picks | |
+
+**User's choice:** Fixed floor
+**Notes:** None
+
+---
+
+## Mixing & Headroom
+
+### Mix strategy
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fixed equal gain | Each layer gets 1/N headroom (~0.09 max) | ✓ |
+| Weighted gain by priority | Bulk traffic gets more headroom | |
+| Dynamic limiter | No fixed gain, soft-clip if exceeds headroom | |
+
+**User's choice:** Fixed equal gain
+**Notes:** None
+
+### Sample rate
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| 44100 Hz (CD quality) | Standard, LAME native | ✓ |
+| 22050 Hz (half rate) | Smaller files, still fine for <800 Hz | |
+| You decide | Claude picks | |
+
+**User's choice:** 44100 Hz
+**Notes:** None
+
+### MP3 bitrate
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| 128 kbps | Good quality, ~1 MB/min | ✓ |
+| 192 kbps | Higher quality, ~1.5 MB/min | |
+| You decide | Claude picks | |
+
+**User's choice:** 128 kbps
+**Notes:** None
+
+### Channel mode
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Mono | Single channel, simpler | |
+| Stereo with panning | Each class panned for spatial separation | ✓ |
+
+**User's choice:** Stereo with panning
+**Notes:** None
+
+### Panning approach
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Fixed positions by register | Bass center, mid spread, high wider | ✓ |
+| Even spread | All 11 evenly from hard L to hard R | |
+| You decide | Claude picks | |
+
+**User's choice:** Fixed positions by register
+**Notes:** ICMP center, DNS slight-L, HTTPS slight-R, etc.
+
+---
+
+## Claude's Discretion
+
+- Exact Hz values per class (within 60-800 Hz, musical intervals)
+- Specific harmonic ratios per traffic class
+- Exact EMA alpha/decay constants for 1-2 sec feel
+- Exact whisper floor percentage (2-5%)
+- WAV intermediate format usage
+- Stereo panning implementation method
+
+## Deferred Ideas
+
+None — discussion stayed within phase scope