diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index 77c009d5..dd635bf8 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -242,7 +242,13 @@ pub async fn spawn(name: &str, hive: &HiveEnv, paths: &AgentPaths) -> Result<()> crate::meta::sync_agents(hive, &agents).await?; let container = container_name(name); priv_run("create", name).await?; - set_nspawn_flags(&container, &paths.agent_dir, &paths.claude_dir, &paths.notes_dir).await?; + set_nspawn_flags( + &container, + &paths.agent_dir, + &paths.claude_dir, + &paths.notes_dir, + ) + .await?; set_resource_limits(&container, &hive.agent_cpu_quota, &hive.agent_memory_max).await?; systemd_daemon_reload().await?; priv_run("start", name).await @@ -418,7 +424,13 @@ pub async fn rebuild_no_meta( // Rebuild strategy: stop-before-update + pre-build. // See `docs/coordinator.md::Container lifecycle`. let was_running = is_running(name).await; - set_nspawn_flags(&container, &paths.agent_dir, &paths.claude_dir, &paths.notes_dir).await?; + set_nspawn_flags( + &container, + &paths.agent_dir, + &paths.claude_dir, + &paths.notes_dir, + ) + .await?; set_resource_limits(&container, &hive.agent_cpu_quota, &hive.agent_memory_max).await?; systemd_daemon_reload().await?; if was_running { @@ -490,7 +502,13 @@ pub async fn rebuild_no_meta( // See `docs/coordinator.md::Spawn path`. on_step("nixos-container create"); priv_run("create", name).await?; - set_nspawn_flags(&container, &paths.agent_dir, &paths.claude_dir, &paths.notes_dir).await?; + set_nspawn_flags( + &container, + &paths.agent_dir, + &paths.claude_dir, + &paths.notes_dir, + ) + .await?; set_resource_limits(&container, &hive.agent_cpu_quota, &hive.agent_memory_max).await?; systemd_daemon_reload().await?; on_step("nixos-container start"); @@ -758,12 +776,16 @@ pub fn ensure_claude_dir(claude_dir: &Path) -> Result<()> { if !claude_dir.exists() { std::fs::create_dir_all(claude_dir) .with_context(|| format!("create {}", claude_dir.display()))?; - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - std::fs::set_permissions(claude_dir, std::fs::Permissions::from_mode(0o700)) - .with_context(|| format!("chmod {}", claude_dir.display()))?; - } + } + // 0755: hive-core (different user from the agent) needs read+execute to + // list the directory so `claude_has_session` can detect a valid session. + // The credential files inside (`.credentials.json` etc.) are 0600 so the + // secrets themselves stay private regardless of the directory mode. + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + std::fs::set_permissions(claude_dir, std::fs::Permissions::from_mode(0o755)) + .with_context(|| format!("chmod 755 {}", claude_dir.display()))?; } Ok(()) }