Watch
0
0
Fork
You've already forked hyperhive
0

claude: say on stderr when the hive's pinned claude-code is missing

A set HYPERHIVE_CLAUDE_CODE_PATH whose build is gone (collected after a
bump while the container still holds the old facts) made the wrapper
run the container's own claude-code silently, which can be a different
version. It now prints one line naming the missing path.

Refs #4857
This commit is contained in:
atlas 2026-10-22 01:32:52 +02:00 • committed by mara
commit 9b1fe85706
3 changed files with 17 additions and 7 deletions

View file

@ -40,7 +40,9 @@ let
# store path over at container start as `HYPERHIVE_CLAUDE_CODE_PATH`, and # store path over at container start as `HYPERHIVE_CLAUDE_CODE_PATH`, and
# the host's system closure keeps it alive: nothing in this container # the host's system closure keeps it alive: nothing in this container
# references it. With no pin, or a path that is not there, this container's # references it. With no pin, or a path that is not there, this container's
# own claude-code runs. `exec -a claude` keeps the bare name in argv[0], # own claude-code runs; a pin that is set but gone (collected after a bump
# while this container still holds the old facts) says so on stderr, since
# the two builds can differ. `exec -a claude` keeps the bare name in argv[0],
# which is how the harness finds its claude child (`find_claude_child`). # which is how the harness finds its claude child (`find_claude_child`).
ownClaude = import ../claude-code-no-alsa.nix lib pkgs.claude-code; ownClaude = import ../claude-code-no-alsa.nix lib pkgs.claude-code;
claude = pkgs.writeShellScriptBin "claude" '' claude = pkgs.writeShellScriptBin "claude" ''
@ -48,6 +50,9 @@ let
if [ -n "$pinned" ] && [ -x "$pinned/bin/claude" ]; then if [ -n "$pinned" ] && [ -x "$pinned/bin/claude" ]; then
exec -a claude "$pinned/bin/claude" "$@" exec -a claude "$pinned/bin/claude" "$@"
fi fi
if [ -n "$pinned" ]; then
echo "claude: $pinned/bin/claude, the hive's pinned claude-code, is missing; running this container's own" >&2
fi
exec -a claude ${ownClaude}/bin/claude "$@" exec -a claude ${ownClaude}/bin/claude "$@"
''; '';
in in

View file

@ -366,7 +366,8 @@
that generation's path until its next start, and only the old that generation's path until its next start, and only the old
generation roots it: collect old generations after restarting generation roots it: collect old generations after restarting
the agents, or an agent still running the old path falls back to the agents, or an agent still running the old path falls back to
its own `claude-code` at its next `claude` spawn. its own `claude-code` at its next `claude` spawn, saying so on
stderr.
The swarm's `swarm-claude-login` and `swarm-review-classifier` The swarm's `swarm-claude-login` and `swarm-review-classifier`
containers, where this host runs them, follow the same pin and containers, where this host runs them, follow the same pin and

View file

@ -112,18 +112,22 @@ chmod +x "$dir/own/bin/claude" "$dir/pinned/bin/claude"
printf '%s' "$CLAUDE_WRAPPER" | sed -E "s|/nix/store/[^ ]+/bin/claude|$dir/own/bin/claude|" >"$dir/claude" printf '%s' "$CLAUDE_WRAPPER" | sed -E "s|/nix/store/[^ ]+/bin/claude|$dir/own/bin/claude|" >"$dir/claude"
case="claude setup" case="claude setup"
if ! grep -qF "$dir/own/bin/claude" "$dir/claude"; then fail "the rewrite did not reach the fallback claude"; fi if ! grep -qF "$dir/own/bin/claude" "$dir/claude"; then fail "the rewrite did not reach the fallback claude"; fi
# claude_check <description> <pin or ""> <which ran> <expected stderr>
claude_check() { claude_check() {
case=$1 case=$1
count=$((count + 1)) count=$((count + 1))
local got pin=() local got said pin=()
if [ -n "$2" ]; then pin=("HYPERHIVE_CLAUDE_CODE_PATH=$2"); fi if [ -n "$2" ]; then pin=("HYPERHIVE_CLAUDE_CODE_PATH=$2"); fi
# Under this shell: the shebang names the build's bash, not in this sandbox. # Under this shell: the shebang names the build's bash, not in this sandbox.
got=$(env -i "${pin[@]}" "$BASH" "$dir/claude" -p hi) got=$(env -i "${pin[@]}" "$BASH" "$dir/claude" -p hi 2>"$dir/stderr")
said=$(cat "$dir/stderr")
if [ "$got" != "$3 -p hi" ]; then fail "ran: $got, wanted: $3 -p hi"; fi if [ "$got" != "$3 -p hi" ]; then fail "ran: $got, wanted: $3 -p hi"; fi
if [ "$said" != "$4" ]; then fail "said on stderr: '$said', wanted: '$4'"; fi
} }
claude_check "the pinned claude when the hive hands one over" "$dir/pinned" pinned claude_check "the pinned claude when the hive hands one over, silently" "$dir/pinned" pinned ""
claude_check "the container's own claude with no pin" "" own claude_check "the container's own claude with no pin, silently" "" own ""
claude_check "the container's own claude when the pinned path is gone" "$dir/gone" own claude_check "the container's own claude when the pinned path is gone, saying so" "$dir/gone" own \
"claude: $dir/gone/bin/claude, the hive's pinned claude-code, is missing; running this container's own"
echo "$count cases, $failures failed" echo "$count cases, $failures failed"
[ "$failures" -eq 0 ] [ "$failures" -eq 0 ]