fix(mesh): fail closed after proven relay tightening

Keep relay-mode evidence distinct from roster availability so an open runtime restarts once NIP-11 proves membership enforcement, even when the first roster snapshot is unavailable. Run the feature-enabled desktop mesh tests in CI and correct the newly exercised wire-model expectation.

Co-authored-by: Jimmy <1fe240cd1a8cf775f6f3060f115e5a303181f3abf28ad4cb0c2515f4a02b36a8@meshllm.communities.buzz.xyz>
Signed-off-by: Jimmy <1fe240cd1a8cf775f6f3060f115e5a303181f3abf28ad4cb0c2515f4a02b36a8@meshllm.communities.buzz.xyz>
This commit is contained in:
Jimmy
2026-08-28 09:44:44 +10:00
parent dd4346437d
commit 0f1798e207
4 changed files with 88 additions and 19 deletions

View File

@@ -214,6 +214,10 @@ jobs:
run: just desktop-tauri-test
env:
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
- name: Desktop Mesh admission tests
run: cargo test --manifest-path desktop/src-tauri/Cargo.toml --features mesh-llm --lib
env:
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
- name: Desktop Tauri compiled-flag verification
run: just desktop-tauri-test-compiled-flags
env:

View File

@@ -209,7 +209,9 @@ async fn probe_relay_mesh_mode(relay_url: &str) -> Result<mesh_llm::MeshRelayMod
/// HTTP, and document errors remain errors so callers can preserve a running
/// admission policy instead of turning an observation failure into a mode
/// transition.
async fn resolved_relay_mesh_mode(relay_url: &str) -> Result<mesh_llm::MeshRelayMode, String> {
pub(crate) async fn resolved_relay_mesh_mode(
relay_url: &str,
) -> Result<mesh_llm::MeshRelayMode, String> {
probe_relay_mesh_mode(relay_url).await
}

View File

@@ -507,7 +507,7 @@ fn inherited_shared_compute_translates_to_supported_agent_transport() {
);
assert_eq!(
effective.env.get("BUZZ_AGENT_MODEL").map(String::as_str),
Some("auto")
Some(super::super::RELAY_MESH_VIRTUAL_MODEL_ID)
);
assert_eq!(
effective

View File

@@ -301,8 +301,46 @@ fn runtime_needs_mode_probe(current_owners: Option<&[String]>) -> bool {
current_owners.is_none_or(<[String]>::is_empty)
}
fn open_runtime_should_restart(query: &Result<Option<Vec<String>>, String>) -> bool {
matches!(query, Ok(Some(_)))
#[derive(Debug, PartialEq, Eq)]
enum OpenRuntimeObservation {
Open,
ClosedWithRoster,
ClosedWithoutRoster(String),
Unknown(String),
}
fn open_runtime_should_restart(observation: &OpenRuntimeObservation) -> bool {
matches!(
observation,
OpenRuntimeObservation::ClosedWithRoster | OpenRuntimeObservation::ClosedWithoutRoster(_)
)
}
fn classify_open_runtime_observation(
mode: Result<crate::mesh_llm::MeshRelayMode, String>,
closed_roster: Option<Result<Vec<String>, String>>,
) -> OpenRuntimeObservation {
match mode {
Ok(mode) if mode.is_open() => OpenRuntimeObservation::Open,
Ok(_) => match closed_roster {
Some(Ok(_)) => OpenRuntimeObservation::ClosedWithRoster,
Some(Err(error)) => OpenRuntimeObservation::ClosedWithoutRoster(error),
None => OpenRuntimeObservation::ClosedWithoutRoster(
"closed relay roster was not queried".to_string(),
),
},
Err(error) => OpenRuntimeObservation::Unknown(error),
}
}
async fn observe_open_runtime_relay(state: &AppState, relay_url: &str) -> OpenRuntimeObservation {
let mode = crate::commands::mesh_llm::resolved_relay_mesh_mode(relay_url).await;
let closed_roster = if matches!(&mode, Ok(mode) if !mode.is_open()) {
Some(crate::commands::mesh_llm::resolve_closed_trusted_owner_ids_at(state, relay_url).await)
} else {
None
};
classify_open_runtime_observation(mode, closed_roster)
}
async fn reconcile_roster(
@@ -330,14 +368,19 @@ async fn reconcile_roster(
.map(str::to_owned)
.unwrap_or_else(|| crate::relay::relay_ws_url_with_override(&state));
if current_owners.is_none() {
let query =
crate::commands::mesh_llm::resolve_trusted_owner_ids_at(&state, &relay_url).await;
if open_runtime_should_restart(&query) {
eprintln!(
"buzz-mesh: relay now enforces membership; restarting Buzz to apply its allowlist"
);
let observation = observe_open_runtime_relay(&state, &relay_url).await;
if open_runtime_should_restart(&observation) {
match &observation {
OpenRuntimeObservation::ClosedWithRoster => eprintln!(
"buzz-mesh: relay now enforces membership; restarting Buzz to apply its allowlist"
),
OpenRuntimeObservation::ClosedWithoutRoster(error) => eprintln!(
"buzz-mesh: relay now enforces membership but its roster is unavailable; restarting Buzz fail-closed: {error}"
),
OpenRuntimeObservation::Open | OpenRuntimeObservation::Unknown(_) => {}
}
app.request_restart();
} else if let Err(error) = query {
} else if let OpenRuntimeObservation::Unknown(error) = observation {
eprintln!(
"buzz-mesh: open-relay mode recheck failed; keeping the running policy: {error}"
);
@@ -732,14 +775,34 @@ mod tests {
}
#[test]
fn open_runtime_restarts_only_for_a_proven_closed_roster() {
assert!(open_runtime_should_restart(&Ok(Some(vec![
"owner-a".to_string()
]))));
assert!(!open_runtime_should_restart(&Ok(None)));
assert!(!open_runtime_should_restart(&Err(
"NIP-11 timed out".to_string()
)));
fn open_to_closed_with_unavailable_roster_fails_closed() {
let observation = classify_open_runtime_observation(
Ok(crate::mesh_llm::MeshRelayMode::ClosedMembershipEnforced),
Some(Err("relay returned no membership snapshot".to_string())),
);
assert_eq!(
observation,
OpenRuntimeObservation::ClosedWithoutRoster(
"relay returned no membership snapshot".to_string()
)
);
assert!(open_runtime_should_restart(&observation));
}
#[test]
fn open_runtime_restarts_for_any_proven_closed_mode() {
assert!(!open_runtime_should_restart(&OpenRuntimeObservation::Open));
assert!(open_runtime_should_restart(
&OpenRuntimeObservation::ClosedWithRoster
));
assert!(open_runtime_should_restart(
&OpenRuntimeObservation::ClosedWithoutRoster(
"relay returned no membership snapshot".to_string()
)
));
assert!(!open_runtime_should_restart(
&OpenRuntimeObservation::Unknown("NIP-11 timed out".to_string())
));
}
#[test]