5.6 KiB
5.6 KiB
Phase 10: Classification Layer - Context
Gathered: 2026-03-27 Status: Ready for planning
## Phase BoundaryAdd ~21 new TrafficClass constants and port-matching rules covering all new protocol families (Mail, File Transfer, Remote Access, Database, Discovery, VoIP, Web extension, Infrastructure extension). All existing 10 protocol classifications remain unchanged — no regression. AllClasses() covers all new classes and DefaultRules maps all new ports.
PROTO-08 Frequency Strategy
- D-01: LDAP, Kerberos, and Syslog get built-in TrafficClass constants and classification rules, but their synthesis frequencies are handled by
autoAssignFreq(FNV hash in [2500, 4000] Hz) rather than designed table slots. No Phase 9 frequency table redesign needed. - D-02: These 3 classes do NOT get entries in
ClassFreqConfigsin this phase — they are treated like user-defined custom classes for frequency purposes. Phase 11 will add theirClassFreqConfigsentries usingautoAssignFreq-compatible Hz values.
Plain vs TLS Port Handling
- D-03: Plaintext and TLS/secure variants of the same protocol share a single TrafficClass. Multiple ports map to the same class constant: IMAP (143) + IMAPS (993) → ClassIMAP, POP3 (110) + POP3S (995) → ClassPOP3, LDAP (389) + LDAPS (636) → ClassLDAP, SIP (5060) + SIPS (5061) → ClassSIP, FTP data (20) + FTP control (21) → ClassFTP.
- D-04: Exception: SMTP (port 25) and SMTP-submission (port 587) remain separate classes (ClassSMTP and ClassSMTPSub) because Phase 9 designed distinct frequency slots for them (214 Hz and 305 Hz respectively).
Naming Convention
- D-05: Follow existing uppercase convention for TrafficClass string values: "IMAP", "POP3", "RDP", "MySQL", etc. Matches existing "ICMP", "DNS", "HTTPS" pattern. SMTP-submission uses "SMTP-sub" to match the Phase 9 frequency table label.
Rule Ordering
- D-06: New port-specific rules insert before the catch-all
{tcp, 0, ClassOtherTCP}and{udp, 0, ClassOtherUDP}entries. Catch-alls remain last. First-match-wins semantics preserved.
Claude's Discretion
- Exact ordering of new rules within the specific-port section (before catch-alls)
- Test structure — whether to extend existing TestClassify or add new test functions
- How to update
TestAllClassesCount(hardcoded to 14) — update the count or make it dynamic - Whether to group rules by family in
DefaultRuleswith comments, or keep flat
<canonical_refs>
Canonical References
Downstream agents MUST read these before planning or implementing.
Classification Package (primary modification target)
classify/types.go— TrafficClass constants,AllClasses()function (currently 14 classes)classify/rules.go—DefaultRulesslice (currently 12 rules, first-match-wins)classify/classifier.go—Classifier.Classify()method,hashBucket()functionclassify/classifier_test.go— Tests for all existing classes,TestAllClassesCount(hardcoded to 14)
Synth Package (reference — not modified in Phase 10)
synth/config.go— Frequency allocation table comment (lines 74-110),ClassFreqConfigsmap,FreqConfigstruct with Group field
Requirements
.planning/REQUIREMENTS.md— PROTO-01 through PROTO-09.planning/ROADMAP.md— Phase 10 success criteria
Research
.planning/research/FEATURES.md— Complete protocol list with ports, families, priorities.planning/research/STACK.md— gopacket layer availability (port-based classification confirmed for all new protocols).planning/research/PITFALLS.md— Rule count scaling (linear scan ~12→~40), PROTO-08 gap.planning/phases/09-frequency-design-and-group-architecture/09-RESEARCH.md— Pitfall 6: PROTO-08 classes not in table
</canonical_refs>
<code_context>
Existing Code Insights
Reusable Assets
buildTCPPacket(t, dstPort)andbuildUDPPacket(t, dstPort)test helpers — reuse for all new protocol testsRulestruct with Protocol/DstPort/Class — same structure works for all new ruleshashBucket()function — unchanged, still handles unmatched packets
Established Patterns
- TrafficClass is a
stringtype withconstdeclarations — add new constants following same pattern AllClasses()returns a hand-maintained slice — must be updated with all new classesDefaultRulesis a[]Ruleliteral — new rules append before catch-alls- Tests use table-driven subtests within
TestClassify— follow same pattern for new protocols
Integration Points
AllClasses()is used bysynth/config_test.goTestClassFreqConfigsMatchAllClassesto verify every class has a FreqConfig entry — new classes added here will fail that test until Phase 11 adds their ClassFreqConfigs entriesTestAllClassesCounthardcodes14— must be updated to new count- Phase 11 depends on these constants existing to add ClassFreqConfigs entries
</code_context>
## Specific Ideas- The complete protocol list with ports is documented in
.planning/research/FEATURES.md(lines 297-311) - Phase 9 frequency table comment in
synth/config.go(lines 74-110) shows exactly which classes are expected with their family groupings - The
TestClassFreqConfigsMatchAllClassescross-check will break when new classes are added without ClassFreqConfigs entries — Phase 10 planner needs to account for this (skip or temporarily adjust the test)
None — discussion stayed within phase scope.
Phase: 10-classification-layer Context gathered: 2026-03-27