hive-c0re: extract agent-socket-plumbing prose (#715 batch 5)

This commit is contained in:
damocles 2026-05-31 17:29:38 +02:00 committed by mara
commit d2f1a9d291
3 changed files with 44 additions and 98 deletions

View file

@ -30,11 +30,12 @@ pub fn start(agent: &str, socket_path: &Path, coord: Arc<Coordinator>) -> Result
let listener = UnixListener::bind(socket_path)
.with_context(|| format!("bind agent socket {}", socket_path.display()))?;
// The socket is bind-mounted into exactly one container as
// `/run/hive/mcp.sock` (`lifecycle::set_nspawn_flags`); post-#658
// the in-container harness connects as the per-agent unix user,
// not root, so the default `tokio::net::UnixListener::bind` perms
// (0755) lock it out. 0666 lets the agent user connect; the bind
// source dir is per-agent on host so blast radius is unchanged.
// `/run/hive/mcp.sock` (`lifecycle::set_nspawn_flags`); the
// in-container harness connects as the per-agent unix user,
// not root, so the default `tokio::net::UnixListener::bind`
// perms (0755) lock it out. 0666 lets the agent user connect;
// the bind source dir is per-agent on host so blast radius is
// unchanged.
use std::os::unix::fs::PermissionsExt as _;
std::fs::set_permissions(socket_path, std::fs::Permissions::from_mode(0o666))
.with_context(|| format!("chmod agent socket {}", socket_path.display()))?;
@ -230,7 +231,7 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
}
}
AgentRequest::SetStatus { text } => {
// #720: cap length + reject multi-line so a confused caller
// Cap length + reject multi-line so a confused caller
// can't dump a multi-paragraph session report into the
// dashboard chip.
if let Err(message) = crate::limits::check_status_text(text) {
@ -261,10 +262,10 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
}
AgentRequest::GetAgentMeta { name } => {
let target = name.as_deref().unwrap_or(agent);
// #432: gate status on the target's running state so a
// stopped container's stale on-disk status doesn't leak
// through. Also surface `running` itself so callers can
// tell (e.g. "iris is down" vs "iris has no status set").
// Gate status on the target's running state so a stopped
// container's stale on-disk status doesn't leak through.
// Also surface `running` itself so callers can tell
// (e.g. "iris is down" vs "iris has no status set").
let (status_text, status_set_at, running) =
crate::container_view::read_agent_status_live(target).await;
let role = if target == hive_sh4re::MANAGER_AGENT {
@ -339,8 +340,9 @@ fn handle_send(
}
// Resolve magic-recipient sentinels (currently `<parent>`) against
// topology.json; no-op for ordinary names. Lets agents address
// structural roles without learning the label — runtime reparenting
// (#486) propagates for free (#692).
// structural roles without learning the label — runtime
// reparenting propagates for free. See `docs/conventions.md::
// Recipient sentinels`.
let resolved = crate::topology::resolve_recipient(agent, to);
match coord.broker.send(&Message {
from: agent.to_owned(),