fix(#2033): gate matrix mcp bridge startup on token, not daemon socket

This commit is contained in:
damocles 2026-06-26 23:56:20 +02:00 committed by mara
commit 652acf8c6e

View file

@ -576,16 +576,28 @@ async fn main() -> Result<()> {
.with_writer(std::io::stderr) .with_writer(std::io::stderr)
.init(); .init();
// Standalone-degraded boot: missing daemon socket → exit 0 // Standalone-degraded boot: matrix isn't provisioned for this agent
// cleanly so claude doesn't see an MCP startup error when matrix // (no token file) → exit 0 cleanly so claude doesn't register a
// hasn't been provisioned for this agent yet. The daemon will // matrix MCP server it can never use.
// appear once hive-c0re writes the token + systemd starts the //
// daemon unit. // Gate on the TOKEN, not the daemon socket. The daemon binds its
let socket = paths::daemon_socket(); // socket only AFTER restoring its matrix session (~10s on a cold
if !tokio::fs::try_exists(&socket).await.unwrap_or(false) { // boot), so an exists-check on the socket here raced the daemon's
// startup: during that window the socket was absent, the bridge
// exited, and claude lost the matrix tools for the WHOLE session
// (the bridge isn't respawned mid-turn). The token, by contrast, is
// written by hive-c0re at provisioning time and is present well
// before the daemon finishes booting — so it cleanly distinguishes
// "matrix not set up for this agent" (token absent → exit) from
// "daemon still coming up" (token present → keep serving). When the
// token exists we serve regardless of socket state: tool calls
// `connect()` per-call and simply error until the daemon is up, but
// the tools stay registered for the session. (#2033)
let token_file = paths::token_file();
if !tokio::fs::try_exists(&token_file).await.unwrap_or(false) {
tracing::warn!( tracing::warn!(
path = %socket.display(), path = %token_file.display(),
"matrix daemon socket absent; exiting cleanly so MCP startup doesn't fail" "matrix not provisioned (no token file); exiting cleanly so MCP startup doesn't fail"
); );
return Ok(()); return Ok(());
} }