harness: write claude configs to systemd RuntimeDirectory + chown ~/.claude on activation (#658 fixup)

This commit is contained in:
müde 2026-05-30 22:57:26 +02:00
commit b8647cf7dc
6 changed files with 52 additions and 24 deletions

View file

@ -38,14 +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 -R ${userName}:${userName} /run/hive";
# `/run/hive-config/` is a per-service runtime dir owned by
# the agent user (`User=` below), auto-cleared by systemd on
# stop. The harness writes its regenerated
# claude-{mcp-config,settings,system-prompt} files there
# (see `paths::config_dir`). Kept separate from `/run/hive`
# — that bind comes in root-owned from the host and holds
# hive-c0re's `mcp.sock` we only connect to (#658 fixup).
RuntimeDirectory = "hive-config";
# 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

View file

@ -687,6 +687,18 @@ in
[ -d "$stateDir" ] || continue
chown -hR "$userName:$userName" "$stateDir" 2>/dev/null || true
done
# Same treatment for the bind-mounted `~/.claude/` dir. Pre-#658
# the harness ran as root and `claude` wrote `.credentials.json`
# there 0600 root:root; post-#658 the harness reads
# `~/.claude/` as the agent user to decide Online vs
# NeedsLogin (`login::has_session`), and the host-side bind
# source is still root-owned 0700 from those legacy writes.
# Chown recursively so the existing credentials are readable
# under the new identity instead of getting silently treated
# as "no session" and re-prompting login every boot.
if [ -d "$homeDir/.claude" ]; then
chown -hR "$userName:$userName" "$homeDir/.claude" 2>/dev/null || true
fi
'';
# Auto-inject the matrix MCP entry when matrix is enabled (#548

View file

@ -48,14 +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 -R ${userName}:${userName} /run/hive";
# `/run/hive-config/` is a per-service runtime dir owned by
# the agent user (`User=` below), auto-cleared by systemd on
# stop. The harness writes its regenerated
# claude-{mcp-config,settings,system-prompt} files there
# (see `paths::config_dir`). Kept separate from `/run/hive`
# — that bind comes in root-owned from the host and holds
# hive-c0re's `mcp.sock` we only connect to (#658 fixup).
RuntimeDirectory = "hive-config";
# 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