Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.7 KiB
6.7 KiB
Phase 7: Custom Rules and Print-Config - Context
Gathered: 2026-03-26 Status: Ready for planning
## Phase BoundaryAdd user-defined traffic classification rules in TOML ([[rules]] array-of-tables) that prepend before built-in rules, with automatic synthesis layer creation for new class names. Add --print-config flag that outputs the full effective config as commented TOML to stdout without starting a capture.
Requirements covered: RULE-01, RULE-02, RULE-03, CFG-06.
## Implementation DecisionsCustom Rule TOML Schema
- D-01: Custom rules use TOML array-of-tables
[[rules]]with three fields:port(uint16, optional — omit to match any port),protocol(string, required — "tcp", "udp", or "icmp"), andclass(string, required — the TrafficClass name). Sound configuration for the class goes in a separate[sounds.<class>]block. - D-02: Port is optional. When omitted (or 0), the rule matches all traffic for the given protocol, mirroring the existing
Rule.DstPort = 0semantics inclassify.DefaultRules. - D-03: Protocol is required. No implicit "match both TCP and UDP" behavior. User must write separate rules for each protocol.
Rule Ordering and Priority
- D-04: User-defined rules are prepended before built-in
DefaultRules(RULE-02). First-match-wins semantics are preserved. A user rule for port 443/tcp fires before the built-in HTTPS rule. - D-05: Rules within the TOML
[[rules]]array maintain their file order. First rule in the file is first to match.
Class Name Collision Policy
- D-06: User-defined class names that match built-in names (e.g.,
class = "HTTPS") are treated as overrides, not errors. The user's rule fires first (prepended), so traffic matching it gets classified under the same built-in class name via the user rule. Sound config in[sounds.HTTPS]still applies. This resolves the design question flagged in STATE.md.
Sound Assignment for Custom Classes
- D-07: New class names that have no
[sounds.<class>]entry automatically get sensible defaults: a frequency from an unused range and sine waveform. This satisfies RULE-03 (no silent gaps for user-defined classes). - D-08: (Claude's Discretion) The auto-assignment algorithm — how to pick frequencies for new classes that don't collide with built-in frequencies. Could use a hash of the class name, a sequential pool, or a deterministic spread across an unused frequency band.
Print-Config
- D-09:
--print-configoutputs the full effective config (defaults merged with user overrides and custom rules) as commented TOML. Comments indicate which values are defaults vs overrides. This satisfies CFG-06. - D-10: Output goes to stdout (pipeable). User can do
netsynth --print-config > template.tomlto create a config template. The command exits without starting a capture. - D-11: If a config file is loaded (via auto-discovery or
--config), show its source path in a header comment.
Config Package Extension
- D-12: The existing
config.Load()function must be extended to parse[[rules]]blocks in addition to[sounds.*]. TherawConfigstruct gains aRules []RawRulefield. - D-13:
config.Load()returns both the mergedFreqConfigmap and the user rules (as[]classify.Rule). The caller prepends user rules beforeclassify.DefaultRules.
Claude's Discretion
- How to extend
rawConfigstruct andLoad()return type (tuple, struct, or new function) - Auto-frequency assignment algorithm for custom classes without explicit sound config
- Whether
--print-configis a Cobra subcommand or a flag on the root command - How to format the commented TOML output (manual string building vs TOML encoder + post-processing)
<canonical_refs>
Canonical References
Downstream agents MUST read these before planning or implementing.
Classification System
classify/rules.go—Rulestruct (Protocol, DstPort, Class),DefaultRulesordered slice, first-match-winsclassify/types.go—TrafficClassstring type,AllClasses(),ClassifiedPacket,WindowSnapshotclassify/classifier.go—NewClassifier(rules []Rule)— accepts injected rule slice
Config System (Phase 6 output)
config/config.go—Load(),rawConfig,SoundOverride,merge(),validate(),parseWaveform()config/config_test.go— Existing test patterns for TOML loading
Synthesis Pipeline
synth/config.go—FreqConfig,ClassFreqConfigs,WaveformType,WaveformPresetHarmonics()synth/bank.go—NewBank(tau, cfgs map[TrafficClass]FreqConfig)— injection point for merged configencode/mp3.go—RunSynthesis(snapshots, outputPath, freqCfgs)— pipeline entry
CLI
cmd/netsynth/main.go— Cobra command,--configflag,run()dispatches to live/pcap modes
Prior Context
.planning/phases/06-config-package-and-sound-overrides/06-CONTEXT.md— Phase 6 decisions (TOML schema, merge semantics, validation)
No external specs — requirements fully captured in decisions above.
</canonical_refs>
<code_context>
Existing Code Insights
Reusable Assets
classify.Rulestruct — Already has Protocol, DstPort, Class fields matching the TOML schemaclassify.NewClassifier(rules []Rule)— Accepts any rule slice, so prepending user rules is straightforwardconfig.Load()— Existing TOML loading with BurntSushi/toml, validation, and merge pipelineconfig.rawConfig— Top-level decode struct, needsRulesfield addedconfig.parseWaveform()— Reusable for validating waveform strings in sound overridessynth.NewBank(tau, cfgs)— Already accepts arbitrary config maps (Phase 5 injection seam)
Established Patterns
- First-match-wins rule ordering in
classify.DefaultRules - TOML strict decoding with
Undecoded()for unknown key detection - Pointer fields (
*float64,*string) for partial override semantics - Config loaded once at startup before capture (fail-fast)
Integration Points
config.Load()return value must expand to include user rulescmd/netsynth/main.go:run()— Prepend user rules before passing toclassify.NewClassifier()config.merge()— Must handle new class names by creatingFreqConfigentries with auto-assigned frequencies--print-config— New flag or subcommand in Cobra root command
</code_context>
## Specific Ideas- Print-config should show commented TOML with
# default/# overrideannotations and source path header - Output to stdout so users can pipe to a file as a template
None — discussion stayed within phase scope.
Phase: 07-custom-rules-and-print-config Context gathered: 2026-03-26