From b425f80efb7db59c190e561fbbe17f72a82f41da Mon Sep 17 00:00:00 2001 From: anonpenguin23 Date: Thu, 11 Jun 2026 08:00:31 +0300 Subject: [PATCH] =?UTF-8?q?fix(config):=20add=20sni=5Frouter=20to=20root?= =?UTF-8?q?=20Config=20=E2=80=94=20prevents=20feat-124=20boot=20crash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- core/pkg/config/config.go | 15 +++++++++++++++ core/pkg/config/decode_test.go | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/core/pkg/config/config.go b/core/pkg/config/config.go index 6a1007c..9996f7e 100644 --- a/core/pkg/config/config.go +++ b/core/pkg/config/config.go @@ -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. diff --git a/core/pkg/config/decode_test.go b/core/pkg/config/decode_test.go index 37f27cc..018b089 100644 --- a/core/pkg/config/decode_test.go +++ b/core/pkg/config/decode_test.go @@ -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") + } +}