fix(fleet): pre-trust claude agent workdir to clear the folder-trust gate (#644) #645

Merged
jason.woltje merged 2 commits from fix/fleet-claude-trust-gate-644 into main 2026-06-24 05:16:47 +00:00
Owner

Summary

Fleet-launched Claude agents stall forever at Claude Code's one-time "Is this a project you trust?" folder-trust prompt — no human is in the pane to answer it, and the heartbeat keeps reporting healthy because the pane process is alive (just blocked). This is the most common fleet outage (F1 / premature stop), tracked in #644.

Root cause (verified empirically 2026-06-24 on w-jarvis)

  • --dangerously-skip-permissions does not bypass the folder-trust gate.
  • trustedProjectDirectories in settings.json does not either (tested: launched Claude in a dir listed there → gate still appeared).
  • The only record the gate honors is the per-project entry in ~/.claude.json: projects["<dir>"].hasTrustDialogAccepted == true — exactly what answering the prompt writes.

Note: this corrects the original #644 hypothesis, which proposed trustedProjectDirectories. That approach is a no-op.

Fix

start-agent-session.sh pre-seeds the trust record for the claude runtime before launching the pane. Seeding is:

  • claude-only (codex/pi have no such gate),
  • idempotent (no-op when already trusted),
  • atomic (tempfile + os.replace; never corrupts a partial/unreadable file),
  • flock-serialized across concurrent agent launches sharing ~/.claude.json,
  • best-effort (any failure is non-fatal — agent still launches, worst case the pre-fix behavior).

Verification

End-to-end on w-jarvis: with /home/jarvis reset to untrusted, the modified launcher flipped hasTrustDialogAccepted to true and Claude booted straight to the ready prompt with no gate. bash -n clean.

🤖 Generated with Claude Code

## Summary Fleet-launched **Claude** agents stall forever at Claude Code's one-time *"Is this a project you trust?"* folder-trust prompt — no human is in the pane to answer it, and the heartbeat keeps reporting **healthy** because the pane process is alive (just blocked). This is the most common fleet outage (F1 / premature stop), tracked in #644. ## Root cause (verified empirically 2026-06-24 on w-jarvis) - `--dangerously-skip-permissions` does **not** bypass the folder-trust gate. - `trustedProjectDirectories` in `settings.json` does **not** either (tested: launched Claude in a dir listed there → gate still appeared). - The **only** record the gate honors is the per-project entry in `~/.claude.json`: `projects["<dir>"].hasTrustDialogAccepted == true` — exactly what answering the prompt writes. > Note: this corrects the original #644 hypothesis, which proposed `trustedProjectDirectories`. That approach is a no-op. ## Fix `start-agent-session.sh` pre-seeds the trust record for the **claude** runtime before launching the pane. Seeding is: - claude-only (codex/pi have no such gate), - idempotent (no-op when already trusted), - atomic (tempfile + `os.replace`; never corrupts a partial/unreadable file), - flock-serialized across concurrent agent launches sharing `~/.claude.json`, - best-effort (any failure is non-fatal — agent still launches, worst case the pre-fix behavior). ## Verification End-to-end on w-jarvis: with `/home/jarvis` reset to untrusted, the modified launcher flipped `hasTrustDialogAccepted` to `true` and Claude booted **straight to the ready prompt with no gate**. `bash -n` clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jason.woltje added 1 commit 2026-06-24 03:59:43 +00:00
fix(fleet): pre-trust claude agent workdir to clear the folder-trust gate (#644)
Some checks failed
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline failed
9a183fcd4f
Fleet-launched Claude agents stall forever at Claude Code's one-time
"Is this a project you trust?" folder-trust prompt: there is no human in
the pane to answer it, yet the heartbeat keeps reporting "healthy" because
the pane process is alive — it's just blocked. This is the most common
fleet outage (F1 / premature stop).

--dangerously-skip-permissions does NOT bypass this gate, and neither does
`trustedProjectDirectories` in settings.json (both verified empirically on
2026-06-24). The only record the gate honors is the per-project entry in
~/.claude.json: projects["<dir>"].hasTrustDialogAccepted == true — exactly
what answering the prompt writes.

start-agent-session.sh now pre-seeds that record for the claude runtime
before launching the pane. The seeding is:
- claude-only (codex/pi have no such gate),
- idempotent (no-op when already trusted),
- atomic (tempfile + os.replace; never corrupts a partial/unreadable file),
- flock-serialized across concurrent agent launches sharing ~/.claude.json,
- best-effort (any failure is non-fatal — the agent still launches, worst
  case it falls back to the pre-fix behavior).

Verified end-to-end: with /home/jarvis untrusted, the modified launcher
flips hasTrustDialogAccepted to true and Claude boots straight to the ready
prompt with no gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jason.woltje added 1 commit 2026-06-24 04:16:09 +00:00
ci: re-trigger pipeline (flaky pglite WASM OOM in packages/db, unrelated)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline failed
7633bec2b4
The push/ci run for the prior commit failed only in packages/db's
src/migrate.test.ts with 'memory access out of bounds' inside the pglite
WASM module — a known-flaky in-memory-Postgres crash under CI memory
pressure. The pr/ci pipeline passed on the identical tree, and this PR
changes only a bash launcher script (no TS / no db package), so the
failure cannot originate here. Empty commit to re-run CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jason.woltje force-pushed fix/fleet-claude-trust-gate-644 from 7633bec2b4 to af7dd3fa7c 2026-06-24 05:05:25 +00:00 Compare
jason.woltje merged commit aa27c42129 into main 2026-06-24 05:16:47 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#645