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.