#!/usr/bin/env bash # check_the_checker for scripts/agent-git (improvise-1xfb.3). A throwaway repo # whose only identity is its own config; no global or system git config. set -uo pipefail here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" RUN="$here/agent-git" work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT export GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL pass=0; fail=0 ok() { printf ' ok %s\n' "$1"; pass=$((pass+1)); } bad() { printf ' FAIL %s (%s)\n' "$1" "$2"; fail=$((fail+1)); } # $1 name, $2 wanted, $3 got same() { if [ "$2" = "$3" ]; then ok "$1"; else bad "$1" "got '$3', wanted '$2'"; fi; } repo="$work/repo" git init -q "$repo" git -C "$repo" config user.name Owner git -C "$repo" config user.email owner@example.com git -C "$repo" commit -q --allow-empty -m base cd "$repo" || exit 1 base="$(git rev-parse HEAD)" # The refusals: nothing may be committed, since the commit would be the owner's. (unset BEADS_ACTOR; "$RUN" commit -q --allow-empty -m unset) > "$work/out" 2>&1 same "an unset BEADS_ACTOR is refused" 2 "$?" grep -q 'BEADS_ACTOR is unset' "$work/out" && ok "the refusal names BEADS_ACTOR" \ || bad "the refusal names BEADS_ACTOR" "$(head -c 200 "$work/out")" BEADS_ACTOR='' "$RUN" commit -q --allow-empty -m empty > /dev/null 2>&1 same "an empty BEADS_ACTOR is refused" 2 "$?" same "a refusal commits nothing" "$base" "$(git rev-parse HEAD)" # A commit: the author is the agent, and nothing else about the identity moves. BEADS_ACTOR=agent-a1 "$RUN" commit -q --allow-empty -m one same "the author is Claude ()" 'Claude (agent-a1)' "$(git log -1 --format=%an)" same "the author email is the configured one" owner@example.com "$(git log -1 --format=%ae)" same "the committer is untouched" 'Owner ' "$(git log -1 --format='%cn <%ce>')" same "shared config is untouched" Owner "$(git config user.name)" # A merge commit is authored too; a plain amend keeps the agent as author. git checkout -q -b side "$base" BEADS_ACTOR=agent-b2 "$RUN" commit -q --allow-empty -m side git checkout -q - BEADS_ACTOR=agent-a1 "$RUN" merge -q --no-edit side same "a merge commit is authored by the agent" 'Claude (agent-a1)' "$(git log -1 --format=%an)" same "the merge has two parents" 2 "$(git log -1 --format=%P | wc -w | tr -d ' ')" # A cherry-pick keeps its source's author, whatever the wrapper sets. git checkout -q -b pick "$base" BEADS_ACTOR=agent-a1 "$RUN" cherry-pick -x --allow-empty "$(git rev-parse side)" > /dev/null 2>&1 same "a cherry-pick keeps its source's author" 'Claude (agent-b2)' "$(git log -1 --format=%an)" git checkout -q - # git's own failure is passed through, not swallowed. BEADS_ACTOR=agent-a1 "$RUN" commit -q -m nothing-staged > /dev/null 2>&1 rc=$? [ "$rc" != 0 ] && ok "git's own failure is passed through" \ || bad "git's own failure is passed through" "exit 0" printf '\nagent-git-test: %d passed, %d failed\n' "$pass" "$fail" [ "$fail" = 0 ]