Replace static EMA-smoothed drones with an evolving ambient soundscape:
- ADSR envelope system with sustained (2s attack, 4s release) and bursty
(30ms attack, no sustain) modes per protocol group
- LFO pitch wobble and amplitude tremolo with incommensurable rates per
group (Eno technique) so modulation patterns never repeat
- C major pentatonic frequency tuning (just intonation) — any combination
of active protocols sounds consonant
- tanh soft limiter on master output prevents clipping
- Sync all documentation: README, PROJECT.md, ARCHITECTURE.md, v1.2
requirements traceability
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- TestPrintConfigGroupHeaders: verifies all group section headers in canonical order
- TestLoadGroupOverride: verifies [groups] TOML reassigns class group without changing Hz/waveform
- TestLoadGroupUnknownClass: verifies unknown class in [groups] produces warning not error
- TestPrintConfigGroupReassignment: verifies PrintConfig reflects reassigned group placement
- Add TestGroupFieldPopulated test to verify all ClassFreqConfigs have non-empty Group (GRP-01)
- Change TestHarmonicsNonEmpty threshold from < 2 to < 1 (accepts single-harmonic sine entries)
- Fix oscillator Advance() to use math.Abs(h.Amplitude) for normalization weight accumulation:
triangle wave uses alternating-sign amplitudes; signed sum underestimates totalWeight causing
output to exceed [-1,1] bounds when using WaveformPresetHarmonics (Rule 1 bug fix)
- Update TestStereoPan to use ClassSSH (pan=-0.7) instead of ClassDHCP (pan changed to 0.1)
- Update TestNewBankCustomConfigNoClip: passes after oscillator normalization fix
- Fix TestLoadPartialOverrideFrequency: derive expected WaveformType from defaults (not hardcoded 0)
- Fix TestAutoFreqSkipsBuiltins: derive expected HTTPS BaseHz from defaults (150.0 in Phase 9)
- Update TestAutoFreqAssignment bounds from [1200, 2350] to [2500, 4000]
- Update TestAutoFreqAssignment comment to reflect new range
- Update TestAutoFreqSkipsBuiltins HTTPS expected value from 175.0 to 150.0
(coordinated with Plan 01 frequency rebalancing)
- Add RawRule struct with Port *uint16, Protocol, Class fields
- Add LoadResult struct with FreqCfgs, UserRules, ConfigPath fields
- Change Load() signature to return LoadResult instead of bare map
- Add validateRules: checks protocol required, class required, valid protocols
- Add convertRules: converts RawRule slices to classify.Rule slices
- Add autoAssignFreq: FNV-32a deterministic Hz in [1200-2350] range
- Add addAutoFreqEntries: creates FreqConfig for new class names, skips built-ins
- Reorder ops: addAutoFreqEntries before merge so sounds overrides apply to user classes
- Update main.go call site to use LoadResult.FreqCfgs
- Update all 8 existing tests to use LoadResult return type
- Add 13 new tests covering rule parsing, validation, auto-freq, and LoadResult