fix(approval): route check_execute_code_guard through the CLI fall-through too - #86270
fix(approval): route check_execute_code_guard through the CLI fall-through too#86270pierrenode wants to merge 1 commit into
Conversation
…rough too e37a032 fixed _run_approval_gate and check_all_command_guards: when HERMES_EXEC_ASK (or a session platform marker) leaks into an interactive CLI process with no gateway notify callback registered, those two functions now prefer the registered CLI Dangerous Command panel over a silent pending_approval nobody can see. check_execute_code_guard — the whole-script gate for execute_code, a separate function with its own copy of the same notify_cb-less short-circuit — never got the same treatment. It doesn't even accept an approval_callback parameter. In the same leaked-ask-mode-into-CLI scenario, execute_code calls still silently drop into pending_approval with the panel never shown, even though a CLI callback is registered. Compute is_cli/approval_callback the same way the two fixed functions do, and when _should_fall_through_to_cli_approval() says yes, run the same hook-fire -> prompt_dangerous_approval -> hook-fire -> choice-branch sequence _run_approval_gate's tail already uses, adapted to this function's own message/persistence conventions (smart-denied session/permanent suppression, denial-breaker addendum). Falls back to the existing pending_approval behavior when no CLI callback is available. Tests: 4 new cases in tests/tools/test_cli_approval_exec_ask_leak.py mirroring the existing check_all_command_guards pair (approve/deny/timeout/ session-persistence). Mutation-verified: all 4 fail against the pre-fix code and pass with it restored. Neighbor suites: tests/tools/*approval* (291+ tests) and tests/gateway/{test_approval_prompt_redaction,test_tui_approval_redaction, test_plaintext_approval_routing,test_discord_exec_approval_content} + tests/cli/test_cli_approval_ui.py all green. The 7 test_approval_mode_parity / test_nonrecursive_verification_artifact_cleanup failures seen in one full batch run are pre-existing and independent of this change — confirmed by re-running the identical batch with tools/approval.py stashed back to pre-fix: the same 7 fail for the same reasons either way. Note on an adjacent open PR: NousResearch#65592 also touches check_execute_code_guard, but an earlier, unrelated region of the function (adding an AST dangerous- operation scanner to the "not is_gateway and not is_ask" auto-approve branch). No semantic overlap with this fix's notify_cb-less branch; a small rebase may be needed depending on merge order.
fix(approval): route check_execute_code_guard through the CLI fall-through too Closing the sibling leak in
|
|
Your commit was cherry-picked with authorship preserved and rebase-merged, so it's on Thanks for catching this — the sibling-guard framing was exactly right. Verification that backed the merge, in case it's useful:
I added one follow-up commit on top rather than sending it back to you, closing three parity gaps found in review:
On the automated review's first observation (extracting a shared helper for the three CLI tails): I looked at it and deliberately left it alone. Profiled side by side, only 4 of 10 behavioural axes match — |
cherry-picking the PR onto current origin/main pulled in NousResearch#86270's execute_code CLI fall-through test class, whose headless no-callback case still asserted the old pending_approval contract. The fix commit now fails closed there too, so flip that case to no_responder, mirroring the check_dangerous_command flip already in this file.
What does this PR do?
e37a032 fixed
_run_approval_gateandcheck_all_command_guards: whenHERMES_EXEC_ASK(or a session platform marker) leaks into an interactive CLI process with no gateway notify callback registered, those two functions now prefer the registered CLI Dangerous Command panel over a silentpending_approvalnobody can see.check_execute_code_guard— the whole-script gate forexecute_code, a separate function with its own copy of the samenotify_cb is Noneshort-circuit — never got the same treatment. It doesn't even accept anapproval_callbackparameter. In the same leaked-ask-mode-into-CLI scenario,execute_codecalls still silently drop intopending_approvalwith the panel never shown, even though a CLI callback is registered.The fix
Compute
is_cli/approval_callbackthe same way the two already-fixed functions do, and when_should_fall_through_to_cli_approval()says yes, run the same hook-fire →prompt_dangerous_approval→ hook-fire → choice-branch sequence_run_approval_gate's tail already uses, adapted to this function's own message/persistence conventions (smart-denied session/permanent suppression, denial-breaker addendum). Falls back to the existingpending_approvalbehavior when no CLI callback is available.Testing
tests/tools/test_cli_approval_exec_ask_leak.pymirroring the existingcheck_all_command_guardspair (approve/deny/timeout/session-persistence).tests/tools/*approval*(291+ tests),tests/gateway/{test_approval_prompt_redaction,test_tui_approval_redaction,test_plaintext_approval_routing,test_discord_exec_approval_content},tests/cli/test_cli_approval_ui.py.test_approval_mode_parity/test_nonrecursive_verification_artifact_cleanupfailures seen in one full batch run are pre-existing and independent of this change — confirmed by re-running the identical batch withtools/approval.pystashed back to pre-fix: the same 7 fail for the same reasons either way (test-order pollution //tmpsymlink resolution, unrelated to this diff).ruff checkclean.Adjacent open PR (checked, no semantic overlap)
#65592 also touches
check_execute_code_guard, but an earlier, unrelated region of the function (adding an AST dangerous-operation scanner to thenot is_gateway and not is_askauto-approve branch). No semantic overlap with this fix'snotify_cb is Nonebranch; a small rebase may be needed depending on merge order.Type of Change