From 5d3a166b9403fbe6b3af7279d8c37c45979b7779 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Mon, 15 Jun 2026 20:49:34 +0000 Subject: [PATCH] =?UTF-8?q?t3-afk:=20fix=20agent=20Bash=20=E2=80=94=20stop?= =?UTF-8?q?=20mounting=20into=20~/.claude?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause of "the agent never commits": the issue-implementer CLAUDE.md was subPath-mounted at /home/node/.claude/CLAUDE.md, which made /home/node/.claude root-owned. The agent (uid 1000) then couldn't create its Bash session-env there, so EVERY Bash/git call failed (Write/Edit worked, so it silently edited but never committed). Found by reading the agent transcripts from state.sqlite -> projection_thread_messages. Fix: don't mount anything into ~/.claude (it's not honored by T3's SDK anyway). Behaviour is injected via the dispatch message preamble by the control plane; files/issue-implementer-CLAUDE.md kept as the canonical source text. Verified post-fix: a preamble-dispatched task edited README and COMMITTED (073ab28) unattended. Co-Authored-By: Claude Opus 4.8 --- stacks/t3-afk/main.tf | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/stacks/t3-afk/main.tf b/stacks/t3-afk/main.tf index 063e42ad..f545271c 100644 --- a/stacks/t3-afk/main.tf +++ b/stacks/t3-afk/main.tf @@ -93,19 +93,11 @@ resource "kubernetes_manifest" "external_secret" { depends_on = [kubernetes_namespace.t3_afk] } -# issue-implementer behaviour. T3 hardcodes the claude_code system-prompt preset -# (no API override), but loads settingSources [user,project,local] — so the -# agent's standing instructions ride in the USER-level ~/.claude/CLAUDE.md, while -# each target repo's own CLAUDE.md provides project context. ADR 0003. -resource "kubernetes_config_map" "agent_claudemd" { - metadata { - name = "issue-implementer-claudemd" - namespace = kubernetes_namespace.t3_afk.metadata[0].name - } - data = { - "CLAUDE.md" = file("${path.module}/files/issue-implementer-CLAUDE.md") - } -} +# issue-implementer behaviour is intentionally NOT mounted as ~/.claude/CLAUDE.md: +# T3's SDK invocation doesn't honor it, and mounting a subPath into ~/.claude +# makes that dir root-owned and breaks the agent's Bash session-env. The control +# plane injects the behaviour as a dispatch message preamble instead; +# files/issue-implementer-CLAUDE.md is kept as the canonical source for that text. # Auto-pair dispatcher script (run by the sidecar container below). Mirrors the # devvm t3-dispatch: on a cookieless, Authentik-gated page load it mints a @@ -290,12 +282,13 @@ resource "kubernetes_deployment" "t3_afk" { name = "data" mount_path = "/data" } - # User-level agent instructions (settingSources: user). - volume_mount { - name = "agent-claudemd" - mount_path = "/home/node/.claude/CLAUDE.md" - sub_path = "CLAUDE.md" - } + # NOTE: do NOT mount anything into /home/node/.claude — a subPath + # mount makes that dir root-owned, which blocks the agent (uid 1000) + # from creating its Bash session-env there and breaks ALL Bash/git for + # the agent (root cause of the 2026-06-15 "agent never commits"). T3's + # SDK invocation doesn't honor ~/.claude/CLAUDE.md anyway, so the + # issue-implementer behaviour is injected via the dispatch message + # preamble by the control plane instead. # Burstable (tier-aux). A live agent thread (node + claude) is memory # heavy; size for a small number of concurrent threads on this pilot @@ -359,13 +352,6 @@ resource "kubernetes_deployment" "t3_afk" { } } - volume { - name = "agent-claudemd" - config_map { - name = kubernetes_config_map.agent_claudemd.metadata[0].name - } - } - volume { name = "dispatcher" config_map {