diff --git a/codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs b/codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs index f0a34c6616..34ca82e138 100644 --- a/codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs +++ b/codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs @@ -1,6 +1,7 @@ use std::path::Path; use std::sync::Arc; +use crate::exec_policy::prompt_is_rejected_by_policy; use crate::function_tool::FunctionCallError; use crate::maybe_emit_implicit_skill_invocation; use crate::tools::context::ExecCommandToolOutput; @@ -279,10 +280,11 @@ impl ExecCommandHandler { .sandbox_permissions .requests_sandbox_override() && !effective_additional_permissions.permissions_preapproved - && !matches!( + && prompt_is_rejected_by_policy( context.step_context.turn.approval_policy(), - codex_protocol::protocol::AskForApproval::OnRequest + /*prompt_is_rule*/ false, ) + .is_some() { let approval_policy = context.step_context.turn.approval_policy(); manager.release_process_id(process_id).await; diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index c5b67c61b5..ace9b004ac 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -1074,6 +1074,34 @@ fn scenarios() -> Vec { output_contains: "rejected by user", }, }, + ScenarioSpec { + name: "simple_command_escalation_granular_sandbox_enabled_requires_approval", + approval_policy: Granular(GranularApprovalConfig { + sandbox_approval: true, + rules: true, + skill_approval: true, + request_permissions: true, + mcp_elicitations: true, + }), + sandbox_policy: workspace_write(false), + action: ActionKind::RunCommand { + command: "echo known-safe-escalation", + }, + sandbox_permissions: SandboxPermissions::RequireEscalated, + features: vec![], + model_override: Some("gpt-5.2"), + outcome: Outcome::ExecApprovalWithAmendment { + decision: ReviewDecision::denied("rejected by user"), + expected_reason: None, + expected_execpolicy_amendment: Some(ExpectedExecPolicyAmendment::Prefix(&[ + "echo", + "known-safe-escalation", + ])), + }, + expectation: Expectation::CommandFailure { + output_contains: "rejected by user", + }, + }, ScenarioSpec { name: "simple_command_escalation_granular_sandbox_disabled_rejects", approval_policy: Granular(GranularApprovalConfig {