From 0c5760b0da3880ce0abcab17ea809c132f915f14 Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 2 Jun 2026 16:46:47 +0200 Subject: [PATCH] feat(#1014): rename manager agent 'root' to 'ruth' in lifecycle + sh4re --- hive-c0re/src/lifecycle.rs | 52 +++++++++++--------------------------- hive-sh4re/src/lib.rs | 2 +- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index 1dcd4866..973d1323 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -11,13 +11,13 @@ use tokio::process::Command; pub const AGENT_PREFIX: &str = "h-"; pub const MAX_AGENT_NAME: usize = 9; /// Logical name of the manager agent (broker recipient, state-dir key, -/// meta flake attribute). All persistent state lives under `root/`. -pub const MANAGER_NAME: &str = "root"; +/// meta flake attribute). All persistent state lives under `ruth/`. +pub const MANAGER_NAME: &str = "ruth"; /// Container name of the manager. Uses the same `h-` prefix as sub-agents /// so `nixos-container list` output is uniform and the list filter is /// a single `starts_with(AGENT_PREFIX)` check. Logical name → container -/// name: `root` → `h-root`. -pub const MANAGER_CONTAINER: &str = "h-root"; +/// name: `ruth` → `h-ruth`. +pub const MANAGER_CONTAINER: &str = "h-ruth"; /// Mount point of the per-agent runtime directory inside the container. pub const CONTAINER_RUNTIME_MOUNT: &str = "/run/hive"; @@ -26,8 +26,8 @@ pub const CONTAINER_RUNTIME_MOUNT: &str = "/run/hive"; /// container. The harness service runs as a non-root unix user /// whose home is `/home//`, so the mount path varies per /// agent — `container_claude_mount(name)` returns -/// `/home//.claude` for sub-agents and `/home/root/.claude` -/// for the manager. `claude` inside the container reads +/// `/home//.claude` for every agent including the manager. +/// `claude` inside the container reads /// `$HOME/.claude` and the service environment sets `HOME` to the /// same path, so the OAuth session survives container restarts. #[must_use] @@ -74,16 +74,7 @@ pub fn agent_web_port(name: &str) -> u16 { #[must_use] pub fn container_name(name: &str) -> String { - if name == MANAGER_NAME { - MANAGER_CONTAINER.to_owned() - } else { - format!("{AGENT_PREFIX}{name}") - } -} - -#[must_use] -pub fn is_manager(name: &str) -> bool { - name == MANAGER_NAME + format!("{AGENT_PREFIX}{name}") } /// Read the agent user's `(uid, gid)` from the container's nixos-managed @@ -143,9 +134,6 @@ fn validate(name: &str) -> Result<()> { if name.is_empty() { bail!("agent name must not be empty"); } - if is_manager(name) { - return Ok(()); - } if name.len() > MAX_AGENT_NAME { bail!( "agent name '{name}' is too long ({} chars); max {MAX_AGENT_NAME}", @@ -164,18 +152,14 @@ async fn port_collision(self_name: &str) -> Option { let port = agent_web_port(self_name); let raw = list().await.unwrap_or_default(); for c in raw { - let other = if c == MANAGER_CONTAINER { - MANAGER_NAME.to_owned() - } else if let Some(n) = c.strip_prefix(AGENT_PREFIX) { - n.to_owned() - } else { + let Some(other) = c.strip_prefix(AGENT_PREFIX) else { continue; }; if other == self_name { continue; } - if agent_web_port(&other) == port && is_running(&other).await { - return Some(other); + if agent_web_port(other) == port && is_running(other).await { + return Some(other.to_owned()); } } None @@ -240,17 +224,11 @@ async fn agents_for_meta(name_to_add: Option<&str>) -> Result = containers .into_iter() .filter_map(|c| { - let (name, is_manager) = if c == MANAGER_CONTAINER { - (MANAGER_NAME.to_owned(), true) - } else if let Some(n) = c.strip_prefix(AGENT_PREFIX) { - (n.to_owned(), false) - } else { - return None; - }; + let name = c.strip_prefix(AGENT_PREFIX)?.to_owned(); Some(crate::meta::AgentSpec { + is_manager: name == MANAGER_NAME, port: agent_web_port(&name), name, - is_manager, }) }) .collect(); @@ -258,9 +236,9 @@ async fn agents_for_meta(name_to_add: Option<&str>) -> Result/.claude` so the diff --git a/hive-sh4re/src/lib.rs b/hive-sh4re/src/lib.rs index 8bfffcc2..4fd307b1 100644 --- a/hive-sh4re/src/lib.rs +++ b/hive-sh4re/src/lib.rs @@ -614,7 +614,7 @@ fn default_true() -> bool { // ----------------------------------------------------------------------------- /// Logical name the broker uses for the manager. -pub const MANAGER_AGENT: &str = "root"; +pub const MANAGER_AGENT: &str = "ruth"; /// Logical name the broker uses for the human operator. Messages with /// `to = OPERATOR_RECIPIENT` accumulate in sqlite and surface on the