Skip to content

Prefer explicit exec approvals over ToolStarted proxy-cancel in untrusted (always-ask) mode#3

Closed
poseidonchan wants to merge 3 commits intocopilot/fix-approval-command-bugfrom
codex/github-mention-fix-approval-request-handling-priority-in-ev
Closed

Prefer explicit exec approvals over ToolStarted proxy-cancel in untrusted (always-ask) mode#3
poseidonchan wants to merge 3 commits intocopilot/fix-approval-command-bugfrom
codex/github-mention-fix-approval-request-handling-priority-in-ev

Conversation

@poseidonchan
Copy link
Owner

Motivation

  • Fix a race where ToolStarted events could trigger a proxy-cancel approval flow before an explicit ExecApprovalRequest arrived, causing commands to execute (or be cancelled) incorrectly in approval_policy="untrusted" (Always ask) mode.

Description

  • Defer handling of untrusted ToolStarted events in on_text_message by introducing pending_untrusted_tool_start so an imminent ExecApprovalRequest can take precedence.
  • Add a shared helper _prompt_proxy_exec_approval() to centralize the proxy-approval prompt, set ActiveRun state, send the Telegram prompt, and cancel the run as needed.
  • Clear the pending tool-start when an ExecApprovalRequest is received so the explicit approval path wins; trigger the proxy prompt only if no explicit approval arrives (including at stream end).
  • Add a regression test test_untrusted_prefers_explicit_exec_approval_after_tool_started in tests/test_proxy_approval_flow.py and adjust test harness imports accordingly.

Testing

  • Ran python -m pytest tests/test_proxy_approval_flow.py tests/test_events.py which completed successfully with 16 passed (regression test included).
  • The change was validated against the approval/exec event sequences to ensure explicit ExecApprovalRequest events win over deferred ToolStarted proxy logic.

Codex Task

@poseidonchan
Copy link
Owner Author

@copilot did this PR fix the issues#1

Copy link
Contributor

Copilot AI commented Feb 13, 2026

@poseidonchan I've opened a new pull request, #4, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 069a14c5be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1164 to +1167
if pending_untrusted_tool_start is not None and not isinstance(ev, ExecApprovalRequest):
await _prompt_proxy_exec_approval(command=pending_untrusted_tool_start.command)
pending_untrusted_tool_start = None
break

Choose a reason for hiding this comment

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

P1 Badge Prompt proxy approval before consuming next event

Deferring ToolStarted handling until a later non-ExecApprovalRequest event means the command can already finish before cancellation is attempted. With an event order like ToolStarted -> TurnCompleted (or any fast completion signal), this branch calls _prompt_proxy_exec_approval() only after the completion event is read, so rejecting no longer prevents execution and accepting can re-run the same command via the proxy_exec callback path. In approval_policy="untrusted", this weakens the intended always-ask gate for short/silent commands.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

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

@codex try to address the issues

Choose a reason for hiding this comment

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

Summary

  • Updated untrusted-mode tool handling to prompt proxy approval immediately on ToolStarted (and then break), instead of deferring to a later event; this closes the race where short commands could finish before cancellation was attempted. src/tgcodex/bot/commands.pyL1265-L1280
  • Kept proxy approval prompt/cancel behavior centralized in _prompt_proxy_exec_approval, which still sets pending action state and cancels the run after sending the prompt. src/tgcodex/bot/commands.pyL1003-L1049
  • Replaced the prior explicit-approval-preference regression test with a new regression test that simulates ToolStarted -> TurnCompleted -> ExecApprovalRequest and asserts we still stop immediately for proxy approval in untrusted mode. tests/test_proxy_approval_flow.pyL521-L597
  • Added TurnCompleted to test imports for the new scenario. tests/test_proxy_approval_flow.pyL10

Testing

  • ⚠️ curl -I -s 'https://duckduckgo.com/?q=python%20async%20event%20handling%20race%20condition%20tool%20started%20turn%20completed%20approval%20flow' | head (returned HTTP 403 in this environment, but web search was attempted per instruction)
  • python -m pytest tests/test_proxy_approval_flow.py tests/test_events.py

Committed on the current branch (e0b1cef) and created a follow-up PR via make_pr with title: “Follow-up: gate untrusted ToolStarted events immediately before completion races”.

View task →

Reply to comment on PR #3 regarding issue #1 fix
@poseidonchan
Copy link
Owner Author

This PR basically proposed a never working way to solve the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants