Skip to content

Containerized/wrapped provider agents (podman exec / PATH-shim) can't initialize: host-path prompt files, unhandled slow startup dialogs, herdr agent_status stuck 'unknown' #400

Description

@arikon

Summary

When a provider agent (e.g. claude_code) is executed inside a container — via a PATH-shadow shim that does podman exec <task-container> claude "$@" on the host, so CAO/herdr run on the host and the agent process lives in the container — CAO cannot complete terminal initialization. The agent binary itself runs fine and completes real turns, but three assumptions in the provider/herdr layer break for wrapped (containerized/remote) execution. I got a full turn to complete only by manually driving the startup dialogs and delivering the task; CAO's own auto-init/auto-delivery never succeeds.

This is a "run agents in isolated containers" use case (one container + worktree per task) on a shared host; the shim is what makes CAO's host-side provider detection resolve (shutil.which("claude") → shim). Filing so the wrapped-execution path can be supported (or documented).

Environment

  • CAO: git main (also repro on v2.2.0), --terminal herdr
  • herdr: 0.7.x, host-side, session cao
  • Agent: Claude Code 2.1.204, launched inside a rootless-podman container via podman exec -it -e IS_SANDBOX=1 -w /home/.../arcadia at-<task> claude "$@"
  • Host: Linux, rootless podman 3.4.4

Blockers (in order hit)

1. Host-written --append-system-prompt-file / --mcp-config are inaccessible to a containerized agent

claude_code._build_claude_command() writes the profile system prompt and MCP config to host temp files under ~/.aws/cli-agent-orchestrator/tmp/<id>.prompt / .mcp.json and passes those host paths to the claude command. When claude runs in a container, that path does not exist there:

claude --dangerously-skip-permissions --append-system-prompt-file /home/<user>/.aws/cli-agent-orchestrator/tmp/<id>.prompt --mcp-config .../<id>.mcp.json --strict-mcp-config
Error: Append system prompt file not found: /home/<user>/.aws/cli-agent-orchestrator/tmp/<id>.prompt

claude exits immediately → herdr never registers an agent → init times out.

Workaround (integration side): bind-mount ~/.aws/cli-agent-orchestrator/tmp into the container at the same path. Works, but couples the container to CAO's host layout. A CAO-side option to pass the system prompt/MCP config inline (already shlex-escaped), or to make the temp dir configurable, would remove the host-filesystem coupling for wrapped execution.

2. Startup trust / bypass-permissions dialogs are not auto-accepted for slow-starting agents

After (1) is worked around, claude starts but shows two interactive dialogs: the workspace-trust dialog ("Yes, I trust this folder") and the --dangerously-skip-permissions bypass confirmation ("Yes, I accept"). _handle_startup_prompts() is meant to answer both (its TRUST_PROMPT_PATTERN / BYPASS_PROMPT_PATTERN do match the current wording), but it runs once for startup_prompt_handler_timeout (~20 s) before wait_until_status, and a containerized claude renders those dialogs after that window (cold-ish node start + gateway connect). Result: Startup prompt handler timed out, dialogs left unanswered, then Claude Code initialization timed out after 60s.

Manually sending Enter (trust) then Down+Enter (bypass) via herdr pane send-keys cleared both and claude reached its REPL normally. Suggestion: keep answering trust/bypass prompts during the wait_until_status wait (not only in a fixed pre-window), so agents that start slower than the handler timeout are still handled.

3. get_native_status maps herdr agent_status="unknown"ERROR, blocking init/inbox for wrapped agents

HerdrBackend.get_native_status() maps herdr agent_status="unknown" to TerminalStatus.ERROR ("pane exists but no agent registered yet"). For a containerized agent the pane's foreground process is podman exec …; herdr's native agent detection never registers the nested claude, so agent_status stays "unknown" permanently → CAO reports ERRORwait_until_status({IDLE, COMPLETED}) never succeeds → init fails and inbox auto-delivery is blocked. Even with blockers (1) and (2) resolved and claude's REPL fully up (verified: banner + bypass permissions on + a real turn), agent_status remained "unknown".

"unknown" at startup is arguably transient rather than a terminal error; mapping it to ERROR (instead of e.g. a not-yet-ready state, or falling through) turns "herdr can't classify this pane" into a hard init failure. This is the core blocker for any agent herdr can't natively introspect (containerized / remote / wrapped).

Repro sketch

  1. Put a wrapper named claude on the CAO host PATH that execs podman exec -it -e IS_SANDBOX=1 -w <container-workdir> <container> claude "$@".
  2. cao launch --agents <profile-with-system-prompt> --provider claude_code --headless --yolo --working-directory <dir> "<task>".
  3. Observe: Append system prompt file not found in the pane (herdr pane read), then—after bind-mounting the temp dir—Startup prompt handler timed outClaude Code initialization timed out after 60s; herdr pane get shows agent_status: "unknown" throughout.

What already works

The agent and turn themselves are fine: driving the two dialogs and delivering the task by hand via herdr pane send-text/send-keys produced a correct, completed turn (tool use + file write) inside the container. Only CAO's automatic init/status/delivery is blocked by the three items above.

Happy to provide full logs or test a patch.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions