From 6ff348d88b43635f465d61555a3ce19f31161061 Mon Sep 17 00:00:00 2001 From: atlas Date: Mon, 5 Oct 2026 13:10:18 +0200 Subject: [PATCH] agents: define the work dir name once and test its creation --- hive-c0re/src/coordinator.rs | 2 +- hive-c0re/src/lifecycle/host_config.rs | 2 +- hive-c0re/src/lifecycle/setup.rs | 2 +- hive-c0re/src/lifecycle/tests.rs | 11 +++++++++++ hive-c0re/src/paths.rs | 4 ++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/hive-c0re/src/coordinator.rs b/hive-c0re/src/coordinator.rs index b56e4722..a22e1528 100644 --- a/hive-c0re/src/coordinator.rs +++ b/hive-c0re/src/coordinator.rs @@ -1135,7 +1135,7 @@ impl Coordinator { /// destroy/recreate. A sibling of `state/` rather than inside it, so a /// claude started under `work/` never walks up into `state/CLAUDE.md`. pub fn agent_work_dir(name: &hive_types::Ident) -> PathBuf { - crate::paths::agent_state_dir(name).join("work") + crate::paths::agent_state_dir(name).join(crate::paths::WORK_SUBDIR) } /// Per-agent harness-internal state dir. Bind-mounted RW into the diff --git a/hive-c0re/src/lifecycle/host_config.rs b/hive-c0re/src/lifecycle/host_config.rs index 38f92fcc..a65df250 100644 --- a/hive-c0re/src/lifecycle/host_config.rs +++ b/hive-c0re/src/lifecycle/host_config.rs @@ -198,7 +198,7 @@ fn bind_own_agent_dirs(agent_name: &str, notes_dir: &Path, binds: &mut Vec Result<()> { } // Harness and work dirs are siblings of the agent-visible state dir. if let Some(parent) = notes_dir.parent() { - for sibling in ["harness", "work"] { + for sibling in ["harness", crate::paths::WORK_SUBDIR] { let dir = parent.join(sibling); if !dir.exists() { std::fs::create_dir_all(&dir) diff --git a/hive-c0re/src/lifecycle/tests.rs b/hive-c0re/src/lifecycle/tests.rs index 8bea8469..8fffe65d 100644 --- a/hive-c0re/src/lifecycle/tests.rs +++ b/hive-c0re/src/lifecycle/tests.rs @@ -410,3 +410,14 @@ async fn a_prebuild_inside_its_limit_returns_its_status() { .expect("a fast child must not time out"); assert_eq!(status.code(), Some(3)); } + +/// The setup path creates the agent's `work/` dir beside `state/`, so the +/// bind source exists before nspawn starts the container. +#[test] +fn ensure_state_dir_creates_the_work_dir() { + let root = tempfile::tempdir().expect("tempdir"); + let notes_dir = root.path().join("state"); + ensure_state_dir(¬es_dir).expect("ensure_state_dir"); + assert!(notes_dir.is_dir()); + assert!(root.path().join(crate::paths::WORK_SUBDIR).is_dir()); +} diff --git a/hive-c0re/src/paths.rs b/hive-c0re/src/paths.rs index c1806bef..b281d9d7 100644 --- a/hive-c0re/src/paths.rs +++ b/hive-c0re/src/paths.rs @@ -30,6 +30,10 @@ use std::path::{Path, PathBuf}; // its own callsites. pub use hive_host_sock::{AGENTS_ROOT, GATEWAY_HTPASSWD, HOST_SOCKET, agent_state_dir}; +/// Name of the per-agent working dir under `agents//`, a sibling of +/// `state/`. Bound RW into the container at `/agents//work`. +pub const WORK_SUBDIR: &str = "work"; + /// Root of all hive-c0re persistent state. // nix: the same literal is written in `nix/host-modules/hive-c0re/default.nix` — must match. // Not option-driven: there is no `statePath` option, the path is hardcoded both sides.