Files
yoloyolo/.planning/milestones/v1.2-phases/11-synthesis-and-config-layer/11-01-PLAN.md
T
gurixandClaude Opus 4.6 494385b528 chore: archive v1.2 milestone — Extended Protocol Coverage
35 traffic classes across 9 protocol families shipped. Archives
ROADMAP, REQUIREMENTS, and phase directories to milestones/v1.2-*.
Updates README with new protocol families, sound design table,
and [groups] TOML config documentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:48:53 +01:00

12 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
11-synthesis-and-config-layer 01 execute 1
synth/config.go
classify/types.go
synth/bank_test.go
config/config_test.go
classify/classifier_test.go
true
GRP-02
GRP-03
truths artifacts key_links
ClassFreqConfigs has exactly 35 entries matching AllClasses()
Every new class has correct Hz, waveform, pan, and group from frequency allocation table
LDAP, Kerberos, Syslog appear in AllClasses() and have Infrastructure group with Triangle waveform
go test ./synth/... ./classify/... ./config/... all pass
path provides contains
synth/config.go 21 new ClassFreqConfigs entries classify.ClassIMAP
path provides contains
classify/types.go AllClasses() returns 35 entries including LDAP/Kerberos/Syslog ClassLDAP
from to via pattern
synth/config.go classify/types.go ClassFreqConfigs references TrafficClass constants classify.Class(IMAP|POP3|SMTPSub|RDP|Telnet|VNC|FTP|SMB|TFTP|MySQL|PostgreSQL|Redis|MongoDB|SIP|QUIC|MDNS|SSDP|SNMP|LDAP|Kerberos|Syslog)
Add all 21 missing ClassFreqConfigs entries and update AllClasses() to include LDAP/Kerberos/Syslog, then fix every hardcoded count assertion across synth, config, and classify test files.

Purpose: This is the foundational data layer for Phase 11 -- all subsequent work (PrintConfig group headers, TOML [groups]) depends on all 35 classes having complete synthesis configs. Output: synth/config.go with 35 ClassFreqConfigs entries, classify/types.go with 35-entry AllClasses(), all count-based tests green.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @synth/config.go @classify/types.go @synth/bank_test.go @synth/config_test.go @config/config_test.go @classify/classifier_test.go

From classify/types.go:

type TrafficClass string
// Constants: ClassIMAP, ClassPOP3, ClassSMTPSub, ClassFTP, ClassSMB, ClassTFTP,
// ClassRDP, ClassTelnet, ClassVNC, ClassMySQL, ClassPostgreSQL, ClassRedis,
// ClassMongoDB, ClassMDNS, ClassSSDP, ClassSNMP, ClassSIP, ClassQUIC,
// ClassLDAP, ClassKerberos, ClassSyslog
func AllClasses() []TrafficClass

From synth/config.go:

type FreqConfig struct {
    BaseHz       float64
    Harmonics    []HarmonicDef
    Pan          float64
    WaveformType WaveformType
    Group        string
}
var ClassFreqConfigs = map[classify.TrafficClass]FreqConfig{...}
func WaveformPresetHarmonics(wt WaveformType, baseHz float64, sampleRate int) []HarmonicDef
Task 1: Add 21 ClassFreqConfigs entries and update AllClasses() synth/config.go, classify/types.go synth/config.go, classify/types.go **synth/config.go** -- Add 21 new entries to the ClassFreqConfigs map, after the existing entries and before the closing brace. Use WaveformPresetHarmonics() for all entries (per D-01). The exact values from the frequency allocation table (lines 74-110 of synth/config.go):
// --- Infrastructure additions (Triangle, 93-118 Hz) ---
classify.ClassMDNS:  {BaseHz: 93.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 93.0, SampleRate), Pan: 0.3, Group: "Infrastructure"}
classify.ClassSSDP:  {BaseHz: 105.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 105.0, SampleRate), Pan: -0.2, Group: "Infrastructure"}
classify.ClassSNMP:  {BaseHz: 118.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 118.0, SampleRate), Pan: 0.2, Group: "Infrastructure"}
// --- Web addition (Sawtooth, 190 Hz) ---
classify.ClassQUIC:  {BaseHz: 190.0, WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 190.0, SampleRate), Pan: -0.2, Group: "Web"}
// --- Mail additions (Triangle, 241-305 Hz) ---
classify.ClassIMAP:    {BaseHz: 241.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 241.0, SampleRate), Pan: 0.3, Group: "Mail"}
classify.ClassPOP3:    {BaseHz: 271.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 271.0, SampleRate), Pan: 0.4, Group: "Mail"}
classify.ClassSMTPSub: {BaseHz: 305.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 305.0, SampleRate), Pan: 0.5, Group: "Mail"}
// --- Remote Access additions (Square, 385-485 Hz) ---
classify.ClassRDP:    {BaseHz: 385.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 385.0, SampleRate), Pan: -0.6, Group: "Remote Access"}
classify.ClassTelnet: {BaseHz: 432.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 432.0, SampleRate), Pan: -0.5, Group: "Remote Access"}
classify.ClassVNC:    {BaseHz: 485.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 485.0, SampleRate), Pan: -0.4, Group: "Remote Access"}
// --- File Transfer additions (Square, 545-687 Hz) ---
classify.ClassFTP:  {BaseHz: 545.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 545.0, SampleRate), Pan: 0.5, Group: "File Transfer"}
classify.ClassSMB:  {BaseHz: 612.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 612.0, SampleRate), Pan: 0.6, Group: "File Transfer"}
classify.ClassTFTP: {BaseHz: 687.0, WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 687.0, SampleRate), Pan: 0.7, Group: "File Transfer"}
// --- Database additions (Sawtooth, 1543-2182 Hz) ---
classify.ClassMySQL:      {BaseHz: 1543.0, WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 1543.0, SampleRate), Pan: -0.4, Group: "Database"}
classify.ClassPostgreSQL: {BaseHz: 1732.0, WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 1732.0, SampleRate), Pan: -0.2, Group: "Database"}
classify.ClassRedis:      {BaseHz: 1944.0, WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 1944.0, SampleRate), Pan: 0.2, Group: "Database"}
classify.ClassMongoDB:    {BaseHz: 2182.0, WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 2182.0, SampleRate), Pan: 0.4, Group: "Database"}
// --- VoIP (Sine, 2449 Hz) ---
classify.ClassSIP: {BaseHz: 2449.0, WaveformType: WaveformSine, Harmonics: WaveformPresetHarmonics(WaveformSine, 2449.0, SampleRate), Pan: 0.0, Group: "VoIP"}
// --- Infrastructure auto-assigned (Triangle, 2950-3250 Hz) per D-02 ---
classify.ClassLDAP:     {BaseHz: 2950.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 2950.0, SampleRate), Pan: -0.2, Group: "Infrastructure"}
classify.ClassKerberos: {BaseHz: 3250.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 3250.0, SampleRate), Pan: 0.0, Group: "Infrastructure"}
classify.ClassSyslog:   {BaseHz: 3050.0, WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 3050.0, SampleRate), Pan: 0.2, Group: "Infrastructure"}

Place new entries in the map grouped by family with section comments matching the existing pattern (e.g., // --- Infrastructure additions ...). Insert them logically:

  • Infrastructure additions (mDNS, SSDP, SNMP) after ClassDHCP and before ClassDNS (since 93/105/118 Hz come between DHCP=82 and DNS=133)
  • Web addition (QUIC) after ClassHTTP
  • Mail additions after ClassSMTP
  • Remote Access additions after ClassSSH
  • File Transfer after Unknown entries
  • Database after Unknown entries
  • VoIP after Database
  • LDAP/Kerberos/Syslog at end (auto-assigned range)

classify/types.go -- Per D-02 and D-03:

  1. Add ClassLDAP, ClassKerberos, ClassSyslog to AllClasses() in the Infrastructure section, after ClassSNMP.
  2. Remove the comment "Excludes ClassLDAP, ClassKerberos, and ClassSyslog" from the AllClasses() doc comment.
  3. Update the doc comment to say "AllClasses returns all known traffic classes in display order."
  4. The AllClasses() function should now return 35 entries total. cd /home/dev/workspace/yoloyolo && go build ./synth/... ./classify/... <acceptance_criteria>
  • grep -c "classify\.Class" synth/config.go shows at least 35 occurrences in ClassFreqConfigs
  • grep "ClassLDAP" classify/types.go appears in AllClasses() return slice
  • grep "ClassKerberos" classify/types.go appears in AllClasses() return slice
  • grep "ClassSyslog" classify/types.go appears in AllClasses() return slice
  • go build ./synth/... ./classify/... succeeds </acceptance_criteria> ClassFreqConfigs has 35 entries with correct Hz/waveform/pan/group values. AllClasses() returns 35 entries including LDAP/Kerberos/Syslog. Both packages compile.
Task 2: Fix all hardcoded count assertions in tests synth/bank_test.go, config/config_test.go, classify/classifier_test.go synth/bank_test.go, config/config_test.go, classify/classifier_test.go Update all hardcoded count assertions to reflect the new 35-entry state. Per research Pitfall 1 and Pitfall 2:

synth/bank_test.go:

  • Line 10: Rename TestNewBankHas14Layers to TestNewBankHasAllLayers
  • Line 12: Change len(b.layers) != 14 to len(b.layers) != len(classify.AllClasses())
  • Line 13: Change want 14 to a dynamic message using len(classify.AllClasses())

config/config_test.go:

  • Line 120: Change len(cfgs) != 14 to len(cfgs) != len(classify.AllClasses()) in TestLoadNoConfig
  • Line 149: Change len(cfgs) != 14 to len(cfgs) != len(classify.AllClasses()) in TestLoadUnknownClass
  • Line 180: Change len(cfgs) != 14 to len(cfgs) != len(classify.AllClasses()) in TestLoadAllDefaultsPresent
  • Line 617: Change len(result.FreqCfgs) != 14 to len(result.FreqCfgs) != len(classify.AllClasses()) in TestLoadNoConfigReturnsLoadResult
  • Lines 407-416 in TestPrintConfigContainsAllClasses: Replace the hardcoded classNames slice with a loop over classify.AllClasses(). Change to:
    for _, cls := range classify.AllClasses() {
        if !strings.Contains(output, string(cls)) {
            t.Errorf("PrintConfig output missing class %q", cls)
        }
    }
    

classify/classifier_test.go:

  • Line 459 (approximately): Change want 32 to want 35 in TestAllClassesCount. Update the assertion value from 32 to 35.

Use len(classify.AllClasses()) for dynamic counts wherever possible (synth and config tests). For classifier_test.go, use the literal 35 since the test is specifically verifying the count is a known value per D-03. cd /home/dev/workspace/yoloyolo && go test ./synth/... ./classify/... ./config/... <acceptance_criteria>

  • go test ./synth/... passes (0 failures)
  • go test ./classify/... passes (0 failures)
  • go test ./config/... passes (0 failures)
  • grep "14" synth/bank_test.go returns no lines with hardcoded layer counts
  • grep 'want 14' config/config_test.go returns no matches
  • grep 'want 32' classify/classifier_test.go returns no matches </acceptance_criteria> All test suites pass with 35 classes. No hardcoded counts of 14 or 32 remain in test assertions. TestNewBankHas14Layers renamed to TestNewBankHasAllLayers.
```bash cd /home/dev/workspace/yoloyolo && go test ./... ``` All tests pass. ClassFreqConfigs has 35 entries matching AllClasses().

<success_criteria>

  • go test ./... passes fully
  • ClassFreqConfigs map has exactly 35 entries
  • AllClasses() returns exactly 35 entries
  • No hardcoded counts of 14 or 32 remain in test files
  • Every new entry uses WaveformPresetHarmonics() (not hand-tuned harmonics)
  • LDAP/Kerberos/Syslog have Group="Infrastructure" and WaveformTriangle </success_criteria>
After completion, create `.planning/phases/11-synthesis-and-config-layer/11-01-SUMMARY.md`