From 9a24af8aa929d1e39bbc44f39bcc28f84530ad83 Mon Sep 17 00:00:00 2001 From: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> Date: Wed, 8 Jul 2026 10:34:45 -0400 Subject: [PATCH] =?UTF-8?q?feat(relay):=20mesh=20config=20seam=20=E2=80=94?= =?UTF-8?q?=20BUZZ=5FMESH=20/=20BUZZ=5FMESH=5FBIND=5FADDR=20env=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires buzz-relay-mesh into buzz-relay: workspace + crate dependency, and Config.mesh (buzz_relay_mesh::MeshConfig) resolved from env. - BUZZ_MESH: on by default; 'off'/'false'/'0' is the incident kill switch — the relay must behave exactly like a single-instance deploy. - BUZZ_MESH_BIND_ADDR: UDP bind for the iroh endpoint, default 0.0.0.0:3478 (excluded from istio sidecar capture in k8s). - registry_refresh fixed at 15s (ready-registry heartbeat; expiry 3x). No behavior change yet: nothing constructs a mesh from this config — AppState handle, /_mesh mount, and startup/drain wiring follow. Co-authored-by: Tyler Longwell Signed-off-by: Tyler Longwell --- Cargo.lock | 1 + Cargo.toml | 1 + crates/buzz-relay/Cargo.toml | 1 + crates/buzz-relay/src/config.rs | 27 +++++++++++++++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ebe0a69e1..39af7d3cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1049,6 +1049,7 @@ dependencies = [ "buzz-db", "buzz-media", "buzz-pubsub", + "buzz-relay-mesh", "buzz-sdk", "buzz-search", "buzz-workflow", diff --git a/Cargo.toml b/Cargo.toml index b752a466e..908521c17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,6 +130,7 @@ buzz-workflow = { path = "crates/buzz-workflow" } buzz-media = { path = "crates/buzz-media" } buzz-sdk = { path = "crates/buzz-sdk" } buzz-ws-client = { path = "crates/buzz-ws-client" } +buzz-relay-mesh = { path = "crates/buzz-relay-mesh" } # CI profile — builds the relay for desktop e2e. Dependencies keep full # release optimization (warm from main's cache; they carry the runtime hot diff --git a/crates/buzz-relay/Cargo.toml b/crates/buzz-relay/Cargo.toml index 1134b2c70..8173525e2 100644 --- a/crates/buzz-relay/Cargo.toml +++ b/crates/buzz-relay/Cargo.toml @@ -23,6 +23,7 @@ buzz-auth = { workspace = true } buzz-pubsub = { workspace = true } buzz-audit = { workspace = true } buzz-search = { workspace = true } +buzz-relay-mesh = { workspace = true } axum = { workspace = true } tokio = { workspace = true } # `io` (ReaderStream) is needed to stream git subprocess stdout straight into diff --git a/crates/buzz-relay/src/config.rs b/crates/buzz-relay/src/config.rs index eaa67a052..a18cf1ee8 100644 --- a/crates/buzz-relay/src/config.rs +++ b/crates/buzz-relay/src/config.rs @@ -93,6 +93,13 @@ pub struct Config { /// service lands. pub huddle_audio_available: bool, + /// Inter-relay mesh configuration (`BUZZ_MESH`, `BUZZ_MESH_BIND_ADDR`). + /// `mesh.enabled=false` (`BUZZ_MESH=off`) is the incident kill switch: the + /// relay must behave exactly like a single-instance deployment. Even when + /// enabled, the mesh only forms once peer registry records exist, so + /// N=1 deployments carry no mesh at runtime. + pub mesh: buzz_relay_mesh::MeshConfig, + /// Optional hex-encoded pubkey of the relay owner. /// When set, this pubkey is automatically bootstrapped into `relay_members` /// with the `owner` role on first startup. @@ -236,6 +243,25 @@ impl Config { .map(|v| !(v == "false" || v == "0")) .unwrap_or(true); + // Mesh kill switch: default enabled — the mesh is inert until peer + // registry records exist, so N=1 deployments pay nothing. `off` + // hard-disables for incidents (single-instance behavior guaranteed). + let mesh_enabled = std::env::var("BUZZ_MESH") + .map(|v| !(v.eq_ignore_ascii_case("off") || v == "false" || v == "0")) + .unwrap_or(true); + let mesh_bind_addr = std::env::var("BUZZ_MESH_BIND_ADDR") + .map(|raw| { + raw.parse::().map_err(|e| { + ConfigError::InvalidValue(format!("invalid BUZZ_MESH_BIND_ADDR: {e}")) + }) + }) + .unwrap_or_else(|_| Ok("0.0.0.0:3478".parse().expect("static default parses")))?; + let mesh = buzz_relay_mesh::MeshConfig { + enabled: mesh_enabled, + bind_addr: mesh_bind_addr, + registry_refresh: std::time::Duration::from_secs(15), + }; + let allow_nip_oa_auth = std::env::var("BUZZ_ALLOW_NIP_OA_AUTH") .map(|v| v == "true" || v == "1") .unwrap_or(false); @@ -427,6 +453,7 @@ impl Config { pubkey_allowlist_enabled, require_relay_membership, huddle_audio_available, + mesh, relay_owner_pubkey, allow_nip_oa_auth, media,