Wire the settings overlay into the live config path:
- AppState.config: Config -> Arc<ArcSwap<Config>> (hot-swappable effective config) +
config_base: Arc<Config> (immutable env-only). New AppState::cfg() accessor; every
config read goes through it (state.cfg().field), so a runtime-safe operator edit is
seen on the next request. One Config type, no parallel path.
- Boot (main.rs): load_settings_overlay -> Config::apply_overlay(validate) -> build
every client/worker/router from the EFFECTIVE config. A persisted overlay that no
longer validates is ignored (boot env-only + loud log), never bricks. Env-only when
ADMIN_KEY_INTEGRITY_SECRET is unset.
- Migrated ~59 state.config.X reads to state.cfg().X across api/*; bound guards where a
reference outlives the statement; integrity_secret returns owned String.
- Test harness builds AppState with ArcSwap + config_base (arc-swap dev-dep).
Behavior-preserving: with no operator_settings rows, effective == env config.
cargo check --all-targets clean; lib tests 256/0.
nostr-rs-relay's [grpc] event_admission_server calls Authorization.EventAdmit
once per inbound event; we answer PERMIT/DENY so the write policy is enforced at
ingest (dynamic, per-event — a static pubkey whitelist can't do inbox/PoW).
- proto/nauthz.proto (matches nostr-rs-relay's contract) compiled by build.rs;
protoc is vendored (protoc-bin-vendored) so a source build needs no system
protobuf-compiler. tonic/prost added (reuse the hyper/tower/h2 stack axum
already pulls in); server-only codegen.
- infra/relay/nauthz: AdmissionService resolves author + recipient (p-tag)
registration via the DB, runs the pure policy engine, returns the decision;
served on a loopback socket (spawned in main only when relay enabled + policy
!= open), mirroring the admin plane. Fail-closed on a malformed request.
- db: is_registered_npub(hex) — a no-PII membership check safe to call per event.
- tests/relay_admission.rs: L1 handler tests (is_registered_npub membership +
outbox/inbox/deny-non-giftwrap/deny-unregistered-recipient through the real
event_admit handler against live Postgres).