feat(core): plumb distinct approval ids for command approvals (#12051)

zsh fork PR stack:
- https://github.com/openai/codex/pull/12051 👈 
- https://github.com/openai/codex/pull/12052

With upcoming support for a fork of zsh that allows us to intercept
`execve` and run execpolicy checks for each subcommand as part of a
`CommandExecution`, it will be possible for there to be multiple
approval requests for a shell command like `/path/to/zsh -lc 'git status
&& rg \"TODO\" src && make test'`.

To support that, this PR introduces a new `approval_id` field across
core, protocol, and app-server so that we can associate approvals
properly for subcommands.
This commit is contained in:
Owen Lin
2026-02-17 17:55:57 -08:00
committed by GitHub
parent b3a8571219
commit db4d2599b5
33 changed files with 331 additions and 114 deletions

View File

@@ -213,16 +213,19 @@ async fn run_codex_tool_session_inner(
.await;
match event.msg {
EventMsg::ExecApprovalRequest(ExecApprovalRequestEvent {
turn_id: _,
command,
cwd,
call_id,
reason: _,
proposed_execpolicy_amendment: _,
parsed_cmd,
network_approval_context: _,
}) => {
EventMsg::ExecApprovalRequest(ev) => {
let approval_id = ev.effective_approval_id();
let ExecApprovalRequestEvent {
turn_id: _,
command,
cwd,
call_id,
approval_id: _,
reason: _,
proposed_execpolicy_amendment: _,
parsed_cmd,
network_approval_context: _,
} = ev;
handle_exec_approval_request(
command,
cwd,
@@ -232,6 +235,7 @@ async fn run_codex_tool_session_inner(
request_id_str.clone(),
event.id.clone(),
call_id,
approval_id,
parsed_cmd,
thread_id,
)
@@ -254,9 +258,6 @@ async fn run_codex_tool_session_inner(
EventMsg::Warning(_) => {
continue;
}
EventMsg::ModelReroute(_) => {
continue;
}
EventMsg::ElicitationRequest(_) => {
// TODO: forward elicitation requests to the client?
continue;
@@ -361,6 +362,7 @@ async fn run_codex_tool_session_inner(
| EventMsg::RequestUserInput(_)
| EventMsg::DynamicToolCallRequest(_)
| EventMsg::ContextCompacted(_)
| EventMsg::ModelReroute(_)
| EventMsg::ThreadRolledBack(_)
| EventMsg::CollabAgentSpawnBegin(_)
| EventMsg::CollabAgentSpawnEnd(_)

View File

@@ -57,10 +57,10 @@ pub(crate) async fn handle_exec_approval_request(
tool_call_id: String,
event_id: String,
call_id: String,
approval_id: String,
codex_parsed_cmd: Vec<ParsedCommand>,
thread_id: ThreadId,
) {
let approval_id = call_id.clone();
let escaped_command =
shlex::try_join(command.iter().map(String::as_str)).unwrap_or_else(|_| command.join(" "));
let message = format!(