Skip to content

Never blocking on a human

The entire point of an autonomous runner is that it doesn't need anyone present. A run that stalls silently waiting for terminal input is worse than one that fails loudly — at least a failure shows up in monitoring.

Every stall path and its mitigation

Stall path Mitigation
Permission prompts permission_mode="bypassPermissions" (the Python Agent SDK has no dangerously_skip_permissions field — this is the equivalent)
An unexpected permission path slipping through anyway A can_use_tool callback that returns PermissionResultAllow without ever awaiting input — belt-and-suspenders
AskUserQuestion Intercepted and denied with guidance — not auto-answered. See ADR 0007 for why fabricating an answer is worse than declining with a stated constraint.
ExitPlanMode Auto-approved, so a plan-mode turn can't park waiting for confirmation
Notification hooks Logged, never awaited
The model asking "Shall I proceed?" in plain text No tool call exists to intercept here — handled by an appended system-prompt fragment establishing autonomous operation, and by the completion evaluator treating an incomplete-with-no-progress turn as a continuation, not a stop
A TTY-dependent stdin read The runner never inherits a TTY; it's designed to run safely under nohup or as a systemd unit
MCP OAuth flows Genuinely can't complete unattended — claudeloop doctor checks configured MCP servers before a run starts and fails fast, naming the servers that need attention, rather than discovering the problem hours in

Why "deny with guidance" instead of "fabricate an answer"

It would be easy to make AskUserQuestion always return, say, the first listed option. That silently invents a decision nobody made. Instead, claudeloop denies the call with a message along the lines of:

"Running autonomously, no user available — choose the option you would recommend, note the assumption, and proceed."

This puts the choice back where it belongs — with the model's own reasoning, visible in the transcript — rather than with an arbitrary default a human reviewing the run later would have no way to distinguish from a real answer.

Testing this guarantee

The planned M2/M3 verification includes running a plan that explicitly instructs the model to ask a clarifying question, and asserting the runner denies the tool call with guidance and continues rather than hanging. See the Verification section of ../plans/architecture-and-roadmap.md.