diff --git a/.claude/scripts/loop-daemon.sh b/.claude/scripts/loop-daemon.sh index bc1f7ff..7022f39 100644 --- a/.claude/scripts/loop-daemon.sh +++ b/.claude/scripts/loop-daemon.sh @@ -531,8 +531,17 @@ run_driver() { # running/lingering). Both failure modes otherwise look identical: some # nonzero rc, no driver output, no other signal to tell them apart. local start_marker; start_marker="$(mktemp -u "$state_dir/.driver-started.XXXXXX")" + # --working-directory is NOT optional: a transient --user unit defaults its + # WorkingDirectory to $HOME, and a driver started there never loads the + # repo's .claude/settings.local.json (bypassPermissions) — every gh call + # then dies on "requires approval" with no approver in headless mode, and + # the driver exits phantom. Burned 5 attempts on issue #97 (2026-07-16) + # before this line existed. The setsid fallback below doesn't need it: a + # plain child inherits the daemon's own cwd (the repo, per the service + # unit's WorkingDirectory). systemd-run --user --wait --collect --quiet \ --unit="$unit" \ + --working-directory="$root" \ -p "RuntimeMaxSec=$timeout_dur" \ --setenv="CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=$CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS" \ --setenv="PATH=$PATH" \ diff --git a/.claude/scripts/loop-daemon.test.sh b/.claude/scripts/loop-daemon.test.sh index 5e0cbbe..7f0e0e4 100644 --- a/.claude/scripts/loop-daemon.test.sh +++ b/.claude/scripts/loop-daemon.test.sh @@ -619,6 +619,8 @@ check "scenario 11: RuntimeMaxSec threaded from LOOP_DRIVER_TIMEOUT=45m" bash -c grep -qF -- "RuntimeMaxSec=45m" "$1"' _ "$dir11/systemd-run.args" check "scenario 11: CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS passed via --setenv (issue #111 pt 4 preserved)" bash -c ' grep -qF -- "--setenv=CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0" "$1"' _ "$dir11/systemd-run.args" +check "scenario 11: --working-directory pins the transient unit to the repo root (not \$HOME)" bash -c ' + grep -qF -- "--working-directory=$2" "$1"' _ "$dir11/systemd-run.args" "$dir11" check "scenario 11: claude stub was invoked (under the transient unit)" [ -f "$dir11/claude.marker" ] check "scenario 11: claude stub received the prompt text" bash -c 'grep -qF "issue #200" "$1"' _ "$dir11/claude.marker" check "scenario 11: setsid (fallback path) was NOT invoked" [ ! -f "$dir11/setsid.marker" ]