Files
yoloyolo/.planning/milestones/v1.2-phases/10-classification-layer/10-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

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
classify/types.go
classify/rules.go
true
PROTO-01
PROTO-02
PROTO-03
PROTO-04
PROTO-05
PROTO-06
PROTO-07
PROTO-08
truths artifacts key_links
21 new TrafficClass constants exist with correct string values per D-05
AllClasses() returns 32 classes (18 new + 14 existing, excluding LDAP/Kerberos/Syslog per D-01/D-02)
DefaultRules contains 30 new port-matching rules before the catch-alls per D-06
Plain/TLS variants share a single class constant per D-03
SMTP (port 25) and SMTP-sub (port 587) remain separate classes per D-04
path provides contains
classify/types.go 21 new TrafficClass constants and updated AllClasses() ClassIMAP
path provides contains
classify/rules.go 30 new port-matching rules ClassMongoDB
from to via pattern
classify/rules.go classify/types.go Rule.Class references TrafficClass constants Class:\s+Class(IMAP|POP3|FTP|RDP|MySQL)
Add all 21 new TrafficClass constants and 30 new port-matching rules to the classify package.

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.go

From 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)
}
Task 1: Add 21 new TrafficClass constants and update AllClasses() classify/types.go - classify/types.go (current constants and AllClasses implementation) - synth/config.go lines 74-110 (frequency table comment showing expected class names) Add 21 new TrafficClass constants to the existing const block in classify/types.go. Group them by family with comments. The exact constants and string values (per D-05 naming convention):
// --- 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

Task 2: Add 30 new port-matching rules to DefaultRules classify/rules.go - classify/rules.go (current DefaultRules with 12 entries) - classify/types.go (after Task 1 — verify new constants exist) Replace the DefaultRules slice in classify/rules.go with the expanded version containing all 42 rules (12 existing + 30 new). All new specific-port rules MUST appear BEFORE the two catch-all entries (per D-06). Group rules by family with comments for readability.

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

- `go build ./classify/...` compiles without errors - 21 new constants exist in types.go - AllClasses() has 32 entries (14 existing + 18 new, excluding LDAP/Kerberos/Syslog) - DefaultRules has 42 entries (12 existing + 30 new) with catch-alls last

<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>
After completion, create `.planning/phases/10-classification-layer/10-01-SUMMARY.md`