Skip to content

Approvals: no answer in two minutes is a no - #387

Merged
rromenskyi merged 3 commits into
mainfrom
approval-timeout
Oct 19, 2026
Merged

rromenskyi merged 3 commits into
mainfrom
approval-timeout

Conversation

@rromenskyi

@rromenskyi rromenskyi commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

A prompt nobody answered held the task until someone came back. Now it waits two minutes, with a countdown in the status line, then denies the call and the run carries on without it. Only an explicit yes runs anything.

  • TUI: the deadline is checked on the spinner tick, which runs for the life of the program, so the countdown redraws there too. On expiry the bridge's ApproveAnswered returns (false, false). A timeout is nobody's judgement, so the risk model learns nothing from it. A panel open over the prompt stays open, and the approval reader is re-armed for the next one.
  • Plain REPL: the prompt runs out the same way. Its stdin read is cancelled with the deadline, so a line typed afterwards goes to the REPL and not to the dead prompt.
  • The tool still reports "denied by user". The model can't tell a timeout from a refusal.

Tests: cmd/agent/approval_timeout_test.go. A sabotage pass ran 9 mutations: never expire, expire early, bridge ignores expiry, timeout counted as an answer, timeout says yes, reader not re-armed, panel closed, plain prompt never times out, plain read outlives the deadline. Each one failed a test.

Review fixes (codex, muse, devin):

  • An expired prompt finalizes a task that finished behind it, including after esc dropped back to typing. Without this the view sat on "running" with nothing behind it. A task behind an open panel still waits for the panel to close.
  • A stdin read whose reader gave up now returns. Before, every expired plain-mode prompt leaked a goroutine.
  • A prompt asked after esc is not shown, because the tool already has its "no". esc also denies the prompt it drops, even one holding an abort signal from an earlier task.
  • The panel's "approval waiting" line shows the countdown.

Left as is: a line typed in the same instant the deadline fires can be dropped. It is a microsecond window and resolves to deny either way.

🤖 Generated with Claude Code

A prompt nobody answered held the task until someone came back. Now it
waits two minutes, counting down in the status line, then denies the call
and lets the run go on without it. Only an explicit yes runs anything.

The timeout is not an answer: the risk model learns nothing from it, and a
panel open over the prompt stays open. The plain prompt runs out the same
way, and its stdin read gives up with it so the next line goes to the REPL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has no extra usage available to pay for this review.

If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.

Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

rromenskyi and others added 2 commits October 18, 2026 20:01
- An expired prompt finalizes a task that finished behind it only when it
  was the modal: one behind a panel waits for the panel to close.
- A stdin read whose reader gave up returns instead of waiting for a reply
  that never comes — one leaked goroutine per expired prompt.
- A prompt asked after esc is not shown: the tool already has its no, and
  an answer or a countdown on it meant nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After esc dropped back to typing, a task that had finished behind the
prompt was left unfinalized when the prompt ran out, and the view sat on
"running" with nothing behind it. It is now finalized unless a panel is
open over it.

esc also denies the prompt it drops outright: one asked before the
current task began holds an earlier abort signal that Abort never closes,
and its tool waited forever. The panel's "approval waiting" line shows
the countdown too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rromenskyi
rromenskyi merged commit 4006b6c into main Oct 19, 2026
2 checks passed
@rromenskyi
rromenskyi deleted the approval-timeout branch October 19, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant