fix(config): add sni_router to root Config — prevents feat-124 boot crash

b9d5f54 (stealth TURN discovery) emits a top-level `sni_router:` block
into node.yaml unconditionally, but only added a lenient ad-hoc parse
in the carry-forward logic — not the field on config.Config that
orama-node strict-decodes (KnownFields(true)) at boot. Identical
failure mode to the v0.122.42 secrets_encryption_key incident: the
unknown key fails the whole node.yaml parse and orama-node crash-loops.

Caught pre-deploy this time by the strict-decode gate check; devnet
never saw it. Regression test added alongside the v0.122.42 one in
decode_test.go.
This commit is contained in:
anonpenguin23 2026-06-11 08:00:31 +03:00
parent b9d5f542e1
commit b425f80efb
2 changed files with 36 additions and 0 deletions

View File

@ -15,6 +15,21 @@ type Config struct {
Security SecurityConfig `yaml:"security"`
Logging LoggingConfig `yaml:"logging"`
HTTPGateway HTTPGatewayConfig `yaml:"http_gateway"`
// SNIRouter is the stealth TURN-over-443 SNI router toggle (feat-124).
// Phase 4 config generation always emits this block into node.yaml, so
// the field MUST exist here: node.yaml is decoded with KnownFields(true)
// and an unknown top-level key fails the whole parse and crash-loops
// orama-node at boot (same failure mode as the v0.122.42
// secrets_encryption_key incident).
SNIRouter SNIRouterConfig `yaml:"sni_router"`
}
// SNIRouterConfig is the top-level stealth SNI router block in node.yaml
// (feat-124). Default-off; when enabled the node runs orama-sni-router on
// :443 and Caddy moves to :8443.
type SNIRouterConfig struct {
Enabled bool `yaml:"enabled"`
}
// ValidationError represents a single validation error with context.

View File

@ -234,3 +234,24 @@ http_gateway:
t.Errorf("SecretsEncryptionKey = %q, want %q", cfg.HTTPGateway.SecretsEncryptionKey, want)
}
}
// TestDecodeStrict_sniRouterBlock guards against a recurrence of the
// v0.122.42-class boot crash for the feat-124 stealth SNI router: Phase 4
// always emits a top-level `sni_router:` block into node.yaml, so the root
// Config struct must carry a matching field or KnownFields(true) rejects
// the whole file and orama-node crash-loops.
func TestDecodeStrict_sniRouterBlock(t *testing.T) {
yamlInput := `
node:
id: "test-node"
sni_router:
enabled: true
`
var cfg Config
if err := DecodeStrict(strings.NewReader(yamlInput), &cfg); err != nil {
t.Fatalf("node.yaml with sni_router block must parse (feat-124): %v", err)
}
if !cfg.SNIRouter.Enabled {
t.Errorf("SNIRouter.Enabled = false, want true")
}
}