refactor(geode): split config into StaticConfig + RuntimeConfig with seeding

Rename RelayConfig → StaticConfig and the persistence/RelayStateStore →
config/RuntimeConfig so the two configuration tiers — boot-time TOML
versus operator-mutable runtime state — are obvious from the class
names. The `persistence/` package is gone; everything related to config
lives in `config/`.

For overlapping fields (NIP-11 info doc, pubkey / kind allow-deny
lists), StaticConfig now seeds RuntimeConfig on first boot via the new
RuntimeConfig(seed = …) constructor and an AuthorizationSeed type. The
runtime file wins from then on: later edits to [authorization] in the
TOML are ignored once an admin RPC has written the snapshot. As a
consequence, KindAllowDenyPolicy and PubkeyAllowDenyPolicy are no
longer stacked in geode's policy chain — BanListPolicy already reads
the same lists from the BanStore, and double-stacking would silently
diverge after the first admin mutation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vitor Pamplona
2026-05-12 15:51:19 -04:00
parent 9c0873b178
commit b0ad540453
11 changed files with 408 additions and 173 deletions
@@ -127,7 +127,7 @@ for unlimited). 500_000 is well above the floor. Pure config change in
for operators who tune it down to fit smaller WS frame budgets.
Note: `LimitsSection.max_ws_frame_bytes`
(`geode/src/main/kotlin/com/vitorpamplona/geode/config/RelayConfig.kt:148`)
(`geode/src/main/kotlin/com/vitorpamplona/geode/config/StaticConfig.kt:148`)
applies to the WebSocket layer. After hex-encoding a 500_000-byte
negentropy payload doubles to ~1_000_000 bytes on the wire; ensure
`max_ws_frame_bytes` is at least 2 MB (or unlimited) in default