From de3f5417291778f686474de4f49c4d5cb613a4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?m=C3=BCde?= Date: Sat, 30 May 2026 22:14:32 +0200 Subject: [PATCH] nix/harness: ExecStartPre chown /run/hive to agent user (#658 fixup) --- nix/templates/agent-base.nix | 8 ++++++++ nix/templates/harness-base.nix | 12 ------------ nix/templates/manager.nix | 8 ++++++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/nix/templates/agent-base.nix b/nix/templates/agent-base.nix index 53b1a315..1894998e 100644 --- a/nix/templates/agent-base.nix +++ b/nix/templates/agent-base.nix @@ -38,6 +38,14 @@ in ExecStart = "${pkgs.hyperhive}/bin/hive-ag3nt serve"; Restart = "on-failure"; RestartSec = 2; + # `/run/hive` is bind-mounted from the host root-owned 0755 + # (hive-c0re's `set_nspawn_flags`). Post-#658 the harness + # runs as the per-agent user and needs to drop mcp.sock + + # claude-{mcp-config,settings,system-prompt} files there. + # `+` runs ExecStartPre as root (before the User= drop) so + # we can chown the bind onto the agent user every start — + # robust against activation-script timing on first boot. + ExecStartPre = "+${pkgs.coreutils}/bin/chown ${userName}:${userName} /run/hive"; # Run the harness as the per-agent user (#658). claude itself # spawned by the harness then runs as that user too — drops # root inside the container while sudo (`NOPASSWD: ALL` by diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index 5d8c2825..6b9331f1 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -687,18 +687,6 @@ in [ -d "$stateDir" ] || continue chown -hR "$userName:$userName" "$stateDir" 2>/dev/null || true done - # Same treatment for the per-agent runtime dir bind - # (`/run/hive` ← host `/run/hyperhive/{manager,agents/}`, - # set by hive-c0re's `set_nspawn_flags`). Host creates it - # root:root 0755; post-#658 the harness service runs as the - # agent user and needs RW to drop `mcp.sock` and the - # claude-{mcp-config,settings,system-prompt} files there. - # Not recursive (-h still, no -R) — the dir itself is what - # the harness writes into; contents are owned by whoever - # created them at runtime. - if [ -d /run/hive ]; then - chown -h "$userName:$userName" /run/hive 2>/dev/null || true - fi ''; # Auto-inject the matrix MCP entry when matrix is enabled (#548 diff --git a/nix/templates/manager.nix b/nix/templates/manager.nix index 2e09dbdd..5fa7fd15 100644 --- a/nix/templates/manager.nix +++ b/nix/templates/manager.nix @@ -48,6 +48,14 @@ in ExecStart = "${pkgs.hyperhive}/bin/hive-m1nd serve"; Restart = "on-failure"; RestartSec = 2; + # `/run/hive` is bind-mounted from the host root-owned 0755 + # (hive-c0re's `set_nspawn_flags`). Post-#658 the harness + # runs as the per-agent user and needs to drop mcp.sock + + # claude-{mcp-config,settings,system-prompt} files there. + # `+` runs ExecStartPre as root (before the User= drop) so + # we can chown the bind onto the agent user every start — + # robust against activation-script timing on first boot. + ExecStartPre = "+${pkgs.coreutils}/bin/chown ${userName}:${userName} /run/hive"; # Same drop-from-root as agent-base.nix (#658). Manager # interactions with the host (rebuild approvals, config # writes) still happen via the dedicated unix sockets