Preserve target-native cwd in permission approval requests (#42314)

## Why

Permission requests can originate in an environment whose path convention differs from the Codex host. Requiring the request working directory to be host-native prevents those requests from reaching interactive approval.

## What changed

- Carry the request `cwd` as a `LegacyAppPathString` through core events and the app-server protocol so the target environment's native representation is preserved.
- Convert the preserved value back to a `PathUri` when materializing permission grants.
- Regenerate the JSON and TypeScript protocol schemas for the updated `cwd` type.

## Testing

- Exercise the app-server permission request round trip with a target-native working directory across host path conventions.
- Verify remote permission requests retain their environment working directory and granted access still unblocks later execution.

GitOrigin-RevId: 97dc9707d9048883d20bab1b69c93871039f3188
This commit is contained in:
iceweasel-oai authored and copyberry committed 2026-09-02 17:27:50 +00:00
1 parent 1bc8fb16ae
commit eb078b4f44
18 files changed
+44 -50

No files matched your search

+1 -14
View File
@@ -2891,19 +2891,6 @@ impl Session {
return Some(response);
}
// The interactive approval event remains host-native until its public
// app-server/TUI boundary migrates in the next stack stage.
let Ok(native_cwd) = cwd.to_abs_path() else {
warn!(
cwd = %cwd,
"request_permissions interactive approval requires a cwd native to the Codex host"
);
return Some(RequestPermissionsResponse {
permissions: RequestPermissionProfile::default(),
scope: PermissionGrantScope::Turn,
strict_auto_review: false,
});
};
let _elicitation = self.services.elicitations.register();
let (tx_response, rx_response) = oneshot::channel();
let prev_entry = {
@@ -2934,7 +2921,7 @@ impl Session {
started_at_ms: now_unix_timestamp_ms(),
reason: args.reason,
permissions: requested_permissions,
cwd: Some(native_cwd),
cwd: Some(cwd.clone().into()),
});
self.send_event(turn_context.as_ref(), event).await;
tokio::select! {
+4 -3
View File
@@ -7353,7 +7353,7 @@ async fn request_permissions_emits_event_when_granular_policy_allows_requests()
);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(request.cwd, Some(turn_cwd));
assert_eq!(request.cwd, Some(turn_cwd.into()));
session
.notify_request_permissions_response(&request.call_id, expected_response.clone())
@@ -7608,7 +7608,8 @@ async fn request_permissions_response_materializes_session_cwd_grants_before_rec
request.environment_id.as_deref(),
Some(codex_exec_server::LOCAL_ENVIRONMENT_ID)
);
let request_cwd = request.cwd.clone().expect("request cwd");
let request_cwd =
PathUri::try_from(request.cwd.clone().expect("request cwd")).expect("request cwd URI");
session
.notify_request_permissions_response(
@@ -7622,7 +7623,7 @@ async fn request_permissions_response_materializes_session_cwd_grants_before_rec
.await;
let expected_permissions = RequestPermissionProfile {
file_system: Some(FileSystemPermissions::from_read_write_roots(
file_system: Some(FileSystemPermissions::from_read_write_path_uris(
/*read*/ None,
Some(vec![request_cwd]),
)),