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>
14 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 | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10-classification-layer | 01 | execute | 1 |
|
true |
|
|
Purpose: Phase 10 expands protocol coverage from 14 to 35 traffic classes. This plan adds the production code — constants in types.go and rules in rules.go. Tests are added in Plan 02.
Output: Updated classify/types.go with 21 new constants and updated AllClasses(), updated classify/rules.go with 30 new rules organized by family.
<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 @classify/types.go @classify/rules.goFrom classify/types.go:
type TrafficClass string
const (
ClassICMP TrafficClass = "ICMP"
ClassDNS TrafficClass = "DNS"
// ... 12 more existing constants
)
func AllClasses() []TrafficClass {
return []TrafficClass{
ClassICMP, ClassDNS, ClassHTTPS, ClassHTTP, ClassSSH,
ClassSMTP, ClassNTP, ClassDHCP, ClassOtherTCP, ClassOtherUDP,
ClassUnknown1, ClassUnknown2, ClassUnknown3, ClassUnknown4,
}
}
From classify/rules.go:
type Rule struct {
Protocol string
DstPort uint16
Class TrafficClass
}
var DefaultRules = []Rule{
// 10 specific rules + 2 catch-alls (tcp/0 and udp/0 must be last)
}
// --- Mail (PROTO-01) ---
ClassIMAP TrafficClass = "IMAP"
ClassPOP3 TrafficClass = "POP3"
ClassSMTPSub TrafficClass = "SMTP-sub" // D-04: separate from ClassSMTP (port 25)
// --- File Transfer (PROTO-02) ---
ClassFTP TrafficClass = "FTP"
ClassSMB TrafficClass = "SMB"
ClassTFTP TrafficClass = "TFTP"
// --- Remote Access (PROTO-03) ---
ClassRDP TrafficClass = "RDP"
ClassTelnet TrafficClass = "Telnet"
ClassVNC TrafficClass = "VNC"
// --- Database (PROTO-04) ---
ClassMySQL TrafficClass = "MySQL"
ClassPostgreSQL TrafficClass = "PostgreSQL"
ClassRedis TrafficClass = "Redis"
ClassMongoDB TrafficClass = "MongoDB"
// --- Discovery (PROTO-05) ---
ClassMDNS TrafficClass = "mDNS"
ClassSSDP TrafficClass = "SSDP"
ClassSNMP TrafficClass = "SNMP"
// --- VoIP (PROTO-06) ---
ClassSIP TrafficClass = "SIP"
// --- Web extension (PROTO-07) ---
ClassQUIC TrafficClass = "QUIC"
// --- Infrastructure extension (PROTO-08, D-01: no ClassFreqConfigs until Phase 11) ---
ClassLDAP TrafficClass = "LDAP"
ClassKerberos TrafficClass = "Kerberos"
ClassSyslog TrafficClass = "Syslog"
Update AllClasses() to return 32 classes. Add 18 new classes (all except LDAP, Kerberos, Syslog — those are excluded per D-01/D-02 to keep synth/config_test.go green). Organize by group with comments:
func AllClasses() []TrafficClass {
return []TrafficClass{
// Infrastructure
ClassICMP, ClassDNS, ClassNTP, ClassDHCP,
ClassMDNS, ClassSSDP, ClassSNMP,
// Web
ClassHTTPS, ClassHTTP, ClassQUIC,
// Mail
ClassSMTP, ClassIMAP, ClassPOP3, ClassSMTPSub,
// Remote Access
ClassSSH, ClassRDP, ClassTelnet, ClassVNC,
// File Transfer
ClassFTP, ClassSMB, ClassTFTP,
// Database
ClassMySQL, ClassPostgreSQL, ClassRedis, ClassMongoDB,
// VoIP
ClassSIP,
// Unknown / catch-all
ClassUnknown1, ClassUnknown2, ClassUnknown3, ClassUnknown4,
ClassOtherTCP, ClassOtherUDP,
}
}
IMPORTANT: Do NOT add ClassLDAP, ClassKerberos, or ClassSyslog to AllClasses(). They get constants and rules but are excluded from AllClasses() to avoid breaking TestAllClassesHaveConfig in synth/config_test.go. They will be added in Phase 11 when their ClassFreqConfigs entries are created.
cd /home/dev/workspace/yoloyolo && go build ./classify/...
<acceptance_criteria>
- classify/types.go contains ClassIMAP TrafficClass = "IMAP"
- classify/types.go contains ClassPOP3 TrafficClass = "POP3"
- classify/types.go contains ClassSMTPSub TrafficClass = "SMTP-sub"
- classify/types.go contains ClassFTP TrafficClass = "FTP"
- classify/types.go contains ClassSMB TrafficClass = "SMB"
- classify/types.go contains ClassTFTP TrafficClass = "TFTP"
- classify/types.go contains ClassRDP TrafficClass = "RDP"
- classify/types.go contains ClassTelnet TrafficClass = "Telnet"
- classify/types.go contains ClassVNC TrafficClass = "VNC"
- classify/types.go contains ClassMySQL TrafficClass = "MySQL"
- classify/types.go contains ClassPostgreSQL TrafficClass = "PostgreSQL"
- classify/types.go contains ClassRedis TrafficClass = "Redis"
- classify/types.go contains ClassMongoDB TrafficClass = "MongoDB"
- classify/types.go contains ClassMDNS TrafficClass = "mDNS"
- classify/types.go contains ClassSSDP TrafficClass = "SSDP"
- classify/types.go contains ClassSNMP TrafficClass = "SNMP"
- classify/types.go contains ClassSIP TrafficClass = "SIP"
- classify/types.go contains ClassQUIC TrafficClass = "QUIC"
- classify/types.go contains ClassLDAP TrafficClass = "LDAP"
- classify/types.go contains ClassKerberos TrafficClass = "Kerberos"
- classify/types.go contains ClassSyslog TrafficClass = "Syslog"
- AllClasses() body contains ClassSIP but does NOT contain ClassLDAP, ClassKerberos, or ClassSyslog
- go build ./classify/... succeeds
</acceptance_criteria>
21 new TrafficClass constants defined, AllClasses() returns 32 classes (excluding LDAP/Kerberos/Syslog), package compiles
The complete DefaultRules slice:
var DefaultRules = []Rule{
// --- Infrastructure ---
{Protocol: "icmp", DstPort: 0, Class: ClassICMP},
{Protocol: "udp", DstPort: 53, Class: ClassDNS},
{Protocol: "tcp", DstPort: 53, Class: ClassDNS},
{Protocol: "udp", DstPort: 123, Class: ClassNTP},
{Protocol: "udp", DstPort: 67, Class: ClassDHCP},
{Protocol: "udp", DstPort: 68, Class: ClassDHCP},
// --- Discovery (PROTO-05) ---
{Protocol: "udp", DstPort: 5353, Class: ClassMDNS},
{Protocol: "udp", DstPort: 1900, Class: ClassSSDP},
{Protocol: "udp", DstPort: 161, Class: ClassSNMP},
{Protocol: "udp", DstPort: 162, Class: ClassSNMP},
// --- Web (existing + PROTO-07) ---
{Protocol: "tcp", DstPort: 443, Class: ClassHTTPS},
{Protocol: "udp", DstPort: 443, Class: ClassQUIC}, // PROTO-07: must use "udp", NOT "tcp"
{Protocol: "tcp", DstPort: 80, Class: ClassHTTP},
// --- Mail (existing SMTP + PROTO-01) ---
{Protocol: "tcp", DstPort: 25, Class: ClassSMTP},
{Protocol: "tcp", DstPort: 143, Class: ClassIMAP}, // D-03: IMAP plain
{Protocol: "tcp", DstPort: 993, Class: ClassIMAP}, // D-03: IMAPS
{Protocol: "tcp", DstPort: 110, Class: ClassPOP3}, // D-03: POP3 plain
{Protocol: "tcp", DstPort: 995, Class: ClassPOP3}, // D-03: POP3S
{Protocol: "tcp", DstPort: 587, Class: ClassSMTPSub}, // D-04: separate from SMTP
// --- Remote Access (existing SSH + PROTO-03) ---
{Protocol: "tcp", DstPort: 22, Class: ClassSSH},
{Protocol: "tcp", DstPort: 3389, Class: ClassRDP},
{Protocol: "tcp", DstPort: 23, Class: ClassTelnet},
{Protocol: "tcp", DstPort: 5900, Class: ClassVNC},
// --- File Transfer (PROTO-02) ---
{Protocol: "tcp", DstPort: 20, Class: ClassFTP}, // D-03: FTP data
{Protocol: "tcp", DstPort: 21, Class: ClassFTP}, // D-03: FTP control
{Protocol: "tcp", DstPort: 445, Class: ClassSMB},
{Protocol: "udp", DstPort: 69, Class: ClassTFTP},
// --- Database (PROTO-04) ---
{Protocol: "tcp", DstPort: 3306, Class: ClassMySQL},
{Protocol: "tcp", DstPort: 5432, Class: ClassPostgreSQL},
{Protocol: "tcp", DstPort: 6379, Class: ClassRedis},
{Protocol: "tcp", DstPort: 27017, Class: ClassMongoDB},
// --- VoIP (PROTO-06) ---
{Protocol: "tcp", DstPort: 5060, Class: ClassSIP}, // D-03: SIP plain TCP
{Protocol: "tcp", DstPort: 5061, Class: ClassSIP}, // D-03: SIPS TCP
{Protocol: "udp", DstPort: 5060, Class: ClassSIP}, // D-03: SIP plain UDP
{Protocol: "udp", DstPort: 5061, Class: ClassSIP}, // D-03: SIPS UDP
// --- Infrastructure extension (PROTO-08, D-01) ---
{Protocol: "tcp", DstPort: 389, Class: ClassLDAP}, // D-03: LDAP plain
{Protocol: "tcp", DstPort: 636, Class: ClassLDAP}, // D-03: LDAPS
{Protocol: "tcp", DstPort: 88, Class: ClassKerberos},
{Protocol: "udp", DstPort: 88, Class: ClassKerberos},
{Protocol: "udp", DstPort: 514, Class: ClassSyslog},
// Catch-alls (must be last — D-06):
{Protocol: "tcp", DstPort: 0, Class: ClassOtherTCP},
{Protocol: "udp", DstPort: 0, Class: ClassOtherUDP},
}
CRITICAL: The two catch-all rules {tcp, 0, ClassOtherTCP} and {udp, 0, ClassOtherUDP} MUST remain as the last two entries. All 30 new specific-port rules go before them. Do NOT add port 465 (SMTPS) — PROTO-01 only specifies port 587.
cd /home/dev/workspace/yoloyolo && go build ./classify/...
<acceptance_criteria>
- classify/rules.go contains DstPort: 143, Class: ClassIMAP
- classify/rules.go contains DstPort: 993, Class: ClassIMAP
- classify/rules.go contains DstPort: 110, Class: ClassPOP3
- classify/rules.go contains DstPort: 995, Class: ClassPOP3
- classify/rules.go contains DstPort: 587, Class: ClassSMTPSub
- classify/rules.go contains DstPort: 20, Class: ClassFTP
- classify/rules.go contains DstPort: 21, Class: ClassFTP
- classify/rules.go contains DstPort: 445, Class: ClassSMB
- classify/rules.go contains DstPort: 69, Class: ClassTFTP
- classify/rules.go contains DstPort: 3389, Class: ClassRDP
- classify/rules.go contains DstPort: 23, Class: ClassTelnet
- classify/rules.go contains DstPort: 5900, Class: ClassVNC
- classify/rules.go contains DstPort: 3306, Class: ClassMySQL
- classify/rules.go contains DstPort: 5432, Class: ClassPostgreSQL
- classify/rules.go contains DstPort: 6379, Class: ClassRedis
- classify/rules.go contains DstPort: 27017, Class: ClassMongoDB
- classify/rules.go contains DstPort: 5353, Class: ClassMDNS
- classify/rules.go contains DstPort: 1900, Class: ClassSSDP
- classify/rules.go contains DstPort: 161, Class: ClassSNMP
- classify/rules.go contains DstPort: 162, Class: ClassSNMP
- classify/rules.go contains DstPort: 5060, Class: ClassSIP (both tcp and udp)
- classify/rules.go contains DstPort: 5061, Class: ClassSIP (both tcp and udp)
- classify/rules.go contains Protocol: "udp", DstPort: 443, Class: ClassQUIC
- classify/rules.go contains DstPort: 389, Class: ClassLDAP
- classify/rules.go contains DstPort: 636, Class: ClassLDAP
- classify/rules.go contains DstPort: 88, Class: ClassKerberos (both tcp and udp)
- classify/rules.go contains DstPort: 514, Class: ClassSyslog
- classify/rules.go does NOT contain DstPort: 465
- The last two entries in DefaultRules are the catch-all rules (DstPort: 0)
- go build ./classify/... succeeds
</acceptance_criteria>
DefaultRules contains 42 rules (12 existing + 30 new), all specific-port rules before catch-alls, package compiles
<success_criteria>
- All 21 new TrafficClass constants compile
- AllClasses() returns exactly 32 classes
- DefaultRules has exactly 42 rules with catch-alls as last 2 entries
go build ./classify/...passes </success_criteria>