Deprecate TurnContext cwd and resolve_path (#22519)

## Why

`TurnContext::cwd` and `TurnContext::resolve_path` are being phased out
in favor of using the selected turn environment cwd directly.
Deprecating both APIs makes any new direct dependency visible while
preserving the existing migration path for current callers.

## What Changed

- Marked `TurnContext::cwd` and `TurnContext::resolve_path` as
deprecated with guidance to use the selected turn environment cwd
instead.
- Added exact `#[allow(deprecated)]` suppressions at each existing
direct usage site, including tests, rather than adding crate-wide
suppression.
- Kept the change behavior-preserving: current cwd reads, writes, and
path resolution continue to use the same values.

## Verification

- `just fmt`
- `cargo check -p codex-core`
- `cargo check -p codex-core --tests`
- `git diff --check`
This commit is contained in:
pakrym-oai
2026-05-13 11:15:25 -07:00
committed by GitHub
Unverified
parent 610b86fefb
commit 4454e1411b
32 changed files with 183 additions and 45 deletions
+9 -2
View File
@@ -530,7 +530,10 @@ async fn handle_patch_approval(
let guardian_decision = if routes_approval_to_guardian(parent_ctx) {
let files = changes
.keys()
.map(|path| parent_ctx.cwd.join(path))
.map(|path| {
#[allow(deprecated)]
parent_ctx.cwd.join(path)
})
.collect::<Vec<_>>();
let review_cancel = cancel_token.child_token();
let patch = changes
@@ -566,6 +569,7 @@ async fn handle_patch_approval(
new_guardian_review_id(),
GuardianApprovalRequest::ApplyPatch {
id: approval_id.clone(),
#[allow(deprecated)]
cwd: parent_ctx.cwd.clone(),
files,
patch,
@@ -739,7 +743,10 @@ async fn handle_request_permissions(
reason: event.reason,
permissions: event.permissions,
};
let cwd = event.cwd.unwrap_or_else(|| parent_ctx.cwd.clone());
let cwd = event.cwd.unwrap_or_else(|| {
#[allow(deprecated)]
parent_ctx.cwd.clone()
});
let response_fut = parent_session.request_permissions_for_cwd(
parent_ctx,
call_id.clone(),
@@ -207,6 +207,7 @@ async fn handle_request_permissions_uses_tool_call_id_for_round_trip() {
scope: PermissionGrantScope::Turn,
strict_auto_review: false,
};
#[allow(deprecated)]
let delegated_cwd = parent_ctx.cwd.join("delegated-cwd");
let cancel_token = CancellationToken::new();
let request_call_id = call_id.clone();
@@ -61,6 +61,7 @@ fn build_permissions_update_item(
next.approval_policy.value(),
next.config.approvals_reviewer,
exec_policy,
#[allow(deprecated)]
&next.cwd,
next.features.enabled(Feature::ExecPermissionApprovals),
next.features.enabled(Feature::RequestPermissionsTool),
@@ -708,6 +708,7 @@ async fn run_review_on_session(
Box::pin(review_session.codex.submit(Op::UserTurn {
environments: None,
items: prompt_items.items,
#[allow(deprecated)]
cwd: params.parent_turn.cwd.to_path_buf(),
approval_policy: AskForApproval::Never,
approvals_reviewer: None,
@@ -1086,6 +1087,7 @@ mod tests {
let reasoning_effort = turn.reasoning_effort;
let reasoning_summary = turn.reasoning_summary;
let personality = turn.personality;
#[allow(deprecated)]
let cwd = turn.cwd.clone();
let spawn_config = build_guardian_review_session_config(
turn.config.as_ref(),
+7
View File
@@ -116,6 +116,7 @@ pub(crate) async fn run_pending_session_start_hooks(
let request = codex_hooks::SessionStartRequest {
session_id: sess.session_id().into(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -150,6 +151,7 @@ pub(crate) async fn run_pre_tool_use_hooks(
let request = PreToolUseRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -209,6 +211,7 @@ pub(crate) async fn run_permission_request_hooks(
let request = PermissionRequestRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -249,6 +252,7 @@ pub(crate) async fn run_post_tool_use_hooks(
let request = PostToolUseRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -276,6 +280,7 @@ pub(crate) async fn run_pre_compact_hooks(
let request = codex_hooks::PreCompactRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -313,6 +318,7 @@ pub(crate) async fn run_post_compact_hooks(
let request = codex_hooks::PostCompactRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -338,6 +344,7 @@ pub(crate) async fn run_user_prompt_submit_hooks(
let request = UserPromptSubmitRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
+13 -3
View File
@@ -102,6 +102,7 @@ async fn build_uploaded_local_argument_value(
index: Option<usize>,
file_path: &str,
) -> Result<JsonValue, String> {
#[allow(deprecated)]
let resolved_path = turn_context.resolve_path(Some(file_path.to_string()));
let Some(auth) = auth else {
return Err(
@@ -216,7 +217,10 @@ mod tests {
tokio::fs::write(&local_path, b"hello")
.await
.expect("write local file");
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
#[allow(deprecated)]
{
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
}
let mut config = (*turn_context.config).clone();
config.chatgpt_base_url = format!("{}/backend-api", server.uri());
@@ -297,7 +301,10 @@ mod tests {
tokio::fs::write(&local_path, b"hello")
.await
.expect("write local file");
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
#[allow(deprecated)]
{
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
}
let mut config = (*turn_context.config).clone();
config.chatgpt_base_url = format!("{}/backend-api", server.uri());
@@ -411,7 +418,10 @@ mod tests {
tokio::fs::write(dir.path().join("two.csv"), b"two")
.await
.expect("write second local file");
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
#[allow(deprecated)]
{
turn_context.cwd = AbsolutePathBuf::try_from(dir.path()).expect("absolute path");
}
let mut config = (*turn_context.config).clone();
config.chatgpt_base_url = format!("{}/backend-api", server.uri());
+1
View File
@@ -732,6 +732,7 @@ async fn augment_mcp_tool_request_meta_with_sandbox_state(
permission_profile: Some(turn_context.permission_profile()),
sandbox_policy: turn_context.sandbox_policy(),
codex_linux_sandbox_exe: turn_context.codex_linux_sandbox_exe.clone(),
#[allow(deprecated)]
sandbox_cwd: turn_context.cwd.to_path_buf(),
use_legacy_landlock: turn_context.features.use_legacy_landlock(),
})?;
+14 -4
View File
@@ -1221,7 +1221,10 @@ async fn install_host_owned_codex_apps_manager(session: &Session, turn_context:
turn_context.sub_id.clone(),
session.get_tx_event(),
turn_context.permission_profile(),
codex_mcp::McpRuntimeEnvironment::new(environment, turn_context.cwd.to_path_buf()),
codex_mcp::McpRuntimeEnvironment::new(environment, {
#[allow(deprecated)]
turn_context.cwd.to_path_buf()
}),
turn_context.config.codex_home.to_path_buf(),
codex_mcp::codex_apps_tools_cache_key(auth.as_ref()),
/*host_owned_codex_apps_enabled*/ true,
@@ -2230,7 +2233,10 @@ async fn maybe_persist_mcp_tool_approval_writes_project_config_for_project_serve
.build()
.await
.expect("load project config");
turn_context.cwd = config.cwd.clone();
#[allow(deprecated)]
{
turn_context.cwd = config.cwd.clone();
}
turn_context.config = Arc::new(config);
let key = McpToolApprovalKey {
server: "docs".to_string(),
@@ -2431,12 +2437,14 @@ async fn permission_request_hook_allows_mcp_tool_call() {
.lines()
.map(|line| serde_json::from_str::<serde_json::Value>(line).expect("parse hook input"))
.collect::<Vec<_>>();
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(
inputs,
vec![serde_json::json!({
"session_id": session.session_id(),
"turn_id": "turn_id",
"cwd": turn_context.cwd,
"cwd": turn_cwd,
"transcript_path": null,
"model": turn_context.model_info.slug,
"permission_mode": "default",
@@ -2491,12 +2499,14 @@ async fn permission_request_hook_uses_hook_tool_name_without_metadata() {
.lines()
.map(|line| serde_json::from_str::<serde_json::Value>(line).expect("parse hook input"))
.collect::<Vec<_>>();
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(
inputs,
vec![serde_json::json!({
"session_id": session.session_id(),
"turn_id": "turn_id",
"cwd": turn_context.cwd,
"cwd": turn_cwd,
"transcript_path": null,
"model": turn_context.model_info.slug,
"permission_mode": "default",
+9 -12
View File
@@ -44,10 +44,9 @@ fn shell_command_for_invocation(invocation: &ToolInvocation) -> Option<(Vec<Stri
.ok()
.map(|params| {
if !invocation.turn.tools_config.allow_login_shell && params.login == Some(true) {
return (
Vec::new(),
invocation.turn.resolve_path(params.workdir).to_path_buf(),
);
#[allow(deprecated)]
let cwd = invocation.turn.resolve_path(params.workdir).to_path_buf();
return (Vec::new(), cwd);
}
let use_login_shell = params
.login
@@ -56,10 +55,9 @@ fn shell_command_for_invocation(invocation: &ToolInvocation) -> Option<(Vec<Stri
.session
.user_shell()
.derive_exec_args(&params.command, use_login_shell);
(
command,
invocation.turn.resolve_path(params.workdir).to_path_buf(),
)
#[allow(deprecated)]
let cwd = invocation.turn.resolve_path(params.workdir).to_path_buf();
(command, cwd)
}),
(None, "exec_command") => serde_json::from_str::<ExecCommandArgs>(arguments)
.ok()
@@ -71,10 +69,9 @@ fn shell_command_for_invocation(invocation: &ToolInvocation) -> Option<(Vec<Stri
invocation.turn.tools_config.allow_login_shell,
)
.ok()?;
Some((
command,
invocation.turn.resolve_path(params.workdir).to_path_buf(),
))
#[allow(deprecated)]
let cwd = invocation.turn.resolve_path(params.workdir).to_path_buf();
Some((command, cwd))
}),
(Some(_), _) | (None, _) => None,
}
+1
View File
@@ -699,6 +699,7 @@ pub async fn review(
.await;
sess.refresh_mcp_servers_if_requested(&turn_context, Some(sess.mcp_elicitation_reviewer()))
.await;
#[allow(deprecated)]
match resolve_review_request(review_request, &turn_context.cwd) {
Ok(resolved) => {
spawn_review_thread(
+1
View File
@@ -296,6 +296,7 @@ impl Session {
.environment_manager
.default_environment()
.unwrap_or_else(|| self.services.environment_manager.local_environment()),
#[allow(deprecated)]
turn_context.cwd.to_path_buf(),
),
};
+3
View File
@@ -2051,6 +2051,7 @@ impl Session {
turn_context,
call_id,
args,
#[allow(deprecated)]
turn_context.cwd.clone(),
cancellation_token,
)
@@ -2630,6 +2631,7 @@ impl Session {
turn_context.approval_policy.value(),
turn_context.config.approvals_reviewer,
self.services.exec_policy.current().as_ref(),
#[allow(deprecated)]
&turn_context.cwd,
turn_context
.features
@@ -2763,6 +2765,7 @@ impl Session {
contextual_user_sections.push(
UserInstructions {
text: user_instructions.to_string(),
#[allow(deprecated)]
directory: turn_context.cwd.to_string_lossy().into_owned(),
}
.render(),
+2
View File
@@ -107,6 +107,7 @@ pub(super) async fn spawn_review_thread(
sess.thread_id().to_string(),
parent_turn_context.thread_source,
review_turn_id.clone(),
#[allow(deprecated)]
parent_turn_context.cwd.clone(),
&parent_turn_context.permission_profile,
parent_turn_context.windows_sandbox_level,
@@ -143,6 +144,7 @@ pub(super) async fn spawn_review_thread(
network: parent_turn_context.network.clone(),
windows_sandbox_level: parent_turn_context.windows_sandbox_level,
shell_environment_policy: parent_turn_context.shell_environment_policy.clone(),
#[allow(deprecated)]
cwd: parent_turn_context.cwd.clone(),
final_output_json_schema: None,
codex_self_exe: parent_turn_context.codex_self_exe.clone(),
@@ -60,6 +60,7 @@ async fn record_initial_history_resumed_bare_turn_context_does_not_hydrate_previ
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -101,6 +102,7 @@ async fn record_initial_history_resumed_hydrates_previous_turn_settings_from_lif
let mut previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -911,6 +913,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -989,6 +992,7 @@ async fn record_initial_history_resumed_turn_context_after_compaction_reestablis
serde_json::to_value(Some(TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -1020,6 +1024,7 @@ async fn record_initial_history_resumed_aborted_turn_without_id_clears_active_tu
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -1135,6 +1140,7 @@ async fn record_initial_history_resumed_unmatched_abort_preserves_active_turn_fo
let current_context_item = TurnContextItem {
turn_id: Some(current_turn_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -1249,6 +1255,7 @@ async fn record_initial_history_resumed_trailing_incomplete_turn_compaction_clea
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -1401,6 +1408,7 @@ async fn record_initial_history_resumed_replaced_incomplete_compacted_turn_clear
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
+35 -10
View File
@@ -2216,6 +2216,7 @@ async fn record_initial_history_forked_hydrates_previous_turn_settings() {
let previous_context_item = TurnContextItem {
turn_id: Some(turn_context.sub_id.clone()),
trace_id: turn_context.trace_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.to_path_buf(),
current_date: turn_context.current_date.clone(),
timezone: turn_context.timezone.clone(),
@@ -3769,6 +3770,7 @@ async fn session_configuration_apply_preserves_absolute_cwd_write_root_on_cwd_up
#[tokio::test]
async fn session_update_settings_does_not_rewrite_sticky_environment_cwds() {
let (session, turn_context) = make_session_and_context().await;
#[allow(deprecated)]
let updated_cwd = turn_context.cwd.join("project");
std::fs::create_dir_all(updated_cwd.as_path()).expect("create project dir");
@@ -3788,8 +3790,12 @@ async fn session_update_settings_does_not_rewrite_sticky_environment_cwds() {
let next_turn = session.new_default_turn().await;
assert_eq!(session_cwd, updated_cwd);
assert_eq!(config.cwd, turn_context.cwd);
assert_eq!(next_turn.cwd, updated_cwd);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
#[allow(deprecated)]
let next_turn_cwd = next_turn.cwd.clone();
assert_eq!(config.cwd, turn_cwd);
assert_eq!(next_turn_cwd, updated_cwd);
assert_eq!(next_turn.config.cwd, updated_cwd);
}
@@ -3873,7 +3879,9 @@ async fn absolute_cwd_update_with_turn_environment_is_allowed() {
.await
.expect("absolute cwd with explicit environments should succeed");
assert_eq!(turn_context.cwd, absolute_cwd);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(turn_cwd, absolute_cwd);
assert_eq!(turn_context.config.cwd, absolute_cwd);
assert_eq!(turn_context.environments.turn_environments.len(), 1);
}
@@ -4674,7 +4682,9 @@ async fn request_permissions_emits_event_when_granular_policy_allows_requests()
panic!("expected request_permissions event");
};
assert_eq!(request.call_id, call_id);
assert_eq!(request.cwd, Some(turn_context.cwd.clone()));
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(request.cwd, Some(turn_cwd));
session
.notify_request_permissions_response(&request.call_id, expected_response.clone())
@@ -5103,7 +5113,9 @@ async fn turn_environments_set_primary_environment() {
&turn_environments.turn_environments[0].environment
));
assert!(!turn_context.environments.turn_environments.is_empty());
assert_eq!(turn_context.cwd.as_path(), selected_cwd.as_path());
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(turn_cwd.as_path(), selected_cwd.as_path());
assert_eq!(turn_context.config.cwd.as_path(), selected_cwd.as_path());
}
@@ -5134,7 +5146,9 @@ async fn default_turn_overlays_session_cwd_onto_stored_thread_environments() {
&turn_environment.environment,
&turn_environments.turn_environments[0].environment
));
assert_eq!(turn_context.cwd, session_cwd);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(turn_cwd, session_cwd);
assert_eq!(turn_context.config.cwd, session_cwd);
}
@@ -5152,7 +5166,9 @@ async fn default_turn_honors_empty_stored_thread_environments() {
assert!(turn_context.environments.primary().is_none());
assert!(turn_context.environments.turn_environments.is_empty());
assert_eq!(turn_context.cwd, session_cwd);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(turn_cwd, session_cwd);
assert_eq!(turn_context.config.cwd, session_cwd);
assert_eq!(turn_context.environments.turn_environments.len(), 0);
}
@@ -5161,6 +5177,7 @@ async fn default_turn_honors_empty_stored_thread_environments() {
async fn primary_environment_uses_first_turn_environment() {
let (_session, mut turn_context) = make_session_and_context().await;
let first_environment = turn_context.environments.turn_environments[0].clone();
#[allow(deprecated)]
let second_cwd = turn_context.cwd.join("second");
turn_context
.environments
@@ -5214,7 +5231,9 @@ async fn empty_turn_environments_clear_primary_environment() {
assert!(turn_context.environments.primary().is_none());
assert!(turn_context.environments.turn_environments.is_empty());
assert_eq!(turn_context.cwd, session.get_config().await.cwd);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
assert_eq!(turn_cwd, session.get_config().await.cwd);
assert_eq!(turn_context.config.cwd, session.get_config().await.cwd);
}
@@ -7033,13 +7052,16 @@ async fn build_initial_context_restates_realtime_start_when_reference_context_is
}
fn file_system_policy_with_unreadable_glob(turn_context: &TurnContext) -> FileSystemSandboxPolicy {
#[allow(deprecated)]
let mut policy = FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(
&turn_context.sandbox_policy(),
&turn_context.cwd,
);
#[allow(deprecated)]
let cwd_display = turn_context.cwd.as_path().display().to_string();
policy.entries.push(FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
pattern: format!("{}/**/*.env", turn_context.cwd.as_path().display()),
pattern: format!("{cwd_display}/**/*.env"),
},
access: FileSystemAccessMode::None,
});
@@ -9381,6 +9403,8 @@ async fn rejects_escalated_permissions_when_policy_not_on_request() {
let call_id = "test-call".to_string();
let handler = ShellCommandHandler::from(ShellCommandBackendConfig::Classic);
#[allow(deprecated)]
let workdir = Some(turn_context.cwd.to_string_lossy().to_string());
let resp = handler
.handle(ToolInvocation {
session: Arc::clone(&session),
@@ -9393,7 +9417,7 @@ async fn rejects_escalated_permissions_when_policy_not_on_request() {
payload: ToolPayload::Function {
arguments: serde_json::json!({
"command": command_script,
"workdir": Some(turn_context.cwd.to_string_lossy().to_string()),
"workdir": workdir,
"timeout_ms": timeout_ms,
"sandbox_permissions": sandbox_permissions,
"justification": Some("test"),
@@ -9433,6 +9457,7 @@ async fn rejects_escalated_permissions_when_policy_not_on_request() {
approval_policy: turn_context.approval_policy.value(),
permission_profile: turn_context.permission_profile(),
file_system_sandbox_policy: &file_system_sandbox_policy,
#[allow(deprecated)]
sandbox_cwd: turn_context.cwd.as_path(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
@@ -291,6 +291,8 @@ async fn guardian_allows_shell_command_additional_permissions_requests_past_poli
let handler = crate::tools::handlers::ShellCommandHandler::from(
codex_tools::ShellCommandBackendConfig::Classic,
);
#[allow(deprecated)]
let workdir = Some(turn_context.cwd.to_string_lossy().to_string());
let resp = handler
.handle(ToolInvocation {
session: Arc::clone(&session),
@@ -304,7 +306,7 @@ async fn guardian_allows_shell_command_additional_permissions_requests_past_poli
arguments: serde_json::json!({
"command": "echo hi",
"login": false,
"workdir": Some(turn_context.cwd.to_string_lossy().to_string()),
"workdir": workdir,
"timeout_ms": expiration_ms,
"sandbox_permissions": SandboxPermissions::WithAdditionalPermissions,
"additional_permissions": PermissionProfile {
@@ -392,6 +394,8 @@ async fn strict_auto_review_turn_grant_forces_guardian_for_shell_command_policy_
let handler = crate::tools::handlers::ShellCommandHandler::from(
codex_tools::ShellCommandBackendConfig::Classic,
);
#[allow(deprecated)]
let workdir = Some(turn_context.cwd.to_string_lossy().to_string());
let resp = handler
.handle(ToolInvocation {
session: Arc::clone(&session),
@@ -405,7 +409,7 @@ async fn strict_auto_review_turn_grant_forces_guardian_for_shell_command_policy_
arguments: serde_json::json!({
"command": "echo hi",
"login": false,
"workdir": Some(turn_context.cwd.to_string_lossy().to_string()),
"workdir": workdir,
"timeout_ms": 1_000_u64,
})
.to_string(),
@@ -558,6 +562,8 @@ async fn shell_command_allows_sticky_turn_permissions_without_inline_request_per
let handler = crate::tools::handlers::ShellCommandHandler::from(
codex_tools::ShellCommandBackendConfig::Classic,
);
#[allow(deprecated)]
let workdir = Some(turn_context.cwd.to_string_lossy().to_string());
let resp = handler
.handle(ToolInvocation {
session: Arc::clone(&session),
@@ -572,7 +578,7 @@ async fn shell_command_allows_sticky_turn_permissions_without_inline_request_per
"command": "echo hi",
"login": false,
"timeout_ms": 1_000_u64,
"workdir": Some(turn_context.cwd.to_string_lossy().to_string()),
"workdir": workdir,
})
.to_string(),
},
+5
View File
@@ -366,6 +366,7 @@ pub(crate) async fn run_turn(
let mut stop_hook_active = false;
// Although from the perspective of codex.rs, TurnDiffTracker has the lifecycle of a Task which contains
// many turns, from the perspective of the user, it is a single turn.
#[allow(deprecated)]
let display_root = get_git_repo_root(turn_context.cwd.as_path())
.unwrap_or_else(|| turn_context.cwd.clone().into_path_buf());
let turn_diff_tracker = Arc::new(tokio::sync::Mutex::new(TurnDiffTracker::with_display_root(
@@ -524,6 +525,7 @@ pub(crate) async fn run_turn(
let stop_request = codex_hooks::StopRequest {
session_id: sess.session_id().into(),
turn_id: turn_context.sub_id.clone(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
transcript_path: sess.hook_transcript_path().await,
model: turn_context.model_info.slug.clone(),
@@ -573,6 +575,7 @@ pub(crate) async fn run_turn(
.hooks()
.dispatch(HookPayload {
session_id: sess.session_id().into(),
#[allow(deprecated)]
cwd: turn_context.cwd.clone(),
client: turn_context.app_server_client_name.clone(),
triggered_at: chrono::Utc::now(),
@@ -697,6 +700,7 @@ async fn track_turn_resolved_config_analytics(
model: turn_context.model_info.slug.clone(),
model_provider: turn_context.config.model_provider_id.clone(),
permission_profile: turn_context.permission_profile(),
#[allow(deprecated)]
permission_profile_cwd: turn_context.cwd.to_path_buf(),
reasoning_effort: turn_context.reasoning_effort,
reasoning_summary: Some(turn_context.reasoning_summary),
@@ -993,6 +997,7 @@ pub(crate) fn build_prompt(
}
#[allow(clippy::too_many_arguments)]
#[allow(deprecated)]
#[instrument(level = "trace",
skip_all,
fields(
@@ -69,6 +69,7 @@ pub struct TurnContext {
/// The session's absolute working directory. All relative paths provided
/// by the model as well as sandbox policies are resolved against this path
/// instead of `std::env::current_dir()`.
#[deprecated(note = "use the selected turn environment cwd instead")]
pub(crate) cwd: AbsolutePathBuf,
pub(crate) current_date: Option<String>,
pub(crate) timezone: Option<String>,
@@ -118,6 +119,7 @@ impl TurnContext {
&self.permission_profile,
&file_system_sandbox_policy,
network_sandbox_policy,
#[allow(deprecated)]
&self.cwd,
)
}
@@ -253,6 +255,7 @@ impl TurnContext {
session_source: self.session_source.clone(),
thread_source: self.thread_source,
environments: self.environments.clone(),
#[allow(deprecated)]
cwd: self.cwd.clone(),
current_date: self.current_date.clone(),
timezone: self.timezone.clone(),
@@ -288,7 +291,9 @@ impl TurnContext {
}
}
#[deprecated(note = "resolve paths from the selected turn environment cwd instead")]
pub(crate) fn resolve_path(&self, path: Option<String>) -> AbsolutePathBuf {
#[allow(deprecated)]
path.as_ref()
.map_or_else(|| self.cwd.clone(), |path| self.cwd.join(path))
}
@@ -314,6 +319,7 @@ impl TurnContext {
);
FileSystemSandboxContext {
permissions,
#[allow(deprecated)]
cwd: Some(self.cwd.clone()),
windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: self
@@ -332,6 +338,7 @@ impl TurnContext {
let legacy_file_system_sandbox_policy =
FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(
&self.sandbox_policy(),
#[allow(deprecated)]
&self.cwd,
);
let file_system_sandbox_policy = self.file_system_sandbox_policy();
@@ -349,6 +356,7 @@ impl TurnContext {
TurnContextItem {
turn_id: Some(self.sub_id.clone()),
trace_id: self.trace_id.clone(),
#[allow(deprecated)]
cwd: self.cwd.to_path_buf(),
current_date: self.current_date.clone(),
timezone: self.timezone.clone(),
@@ -566,6 +574,7 @@ impl Session {
session_source,
thread_source: session_configuration.thread_source,
environments,
#[allow(deprecated)]
cwd,
current_date: Some(current_date),
timezone: Some(timezone),
+2
View File
@@ -148,6 +148,7 @@ pub(crate) async fn execute_user_shell_command(
let exec_command = maybe_wrap_shell_lc_with_snapshot(
&display_command,
session_shell.as_ref(),
#[allow(deprecated)]
&turn_context.cwd,
&turn_context.shell_environment_policy.r#set,
&exec_env_map,
@@ -155,6 +156,7 @@ pub(crate) async fn execute_user_shell_command(
let call_id = Uuid::new_v4().to_string();
let raw_command = command;
#[allow(deprecated)]
let cwd = turn_context.cwd.clone();
let parsed_cmd = parse_command(&display_command);
@@ -68,6 +68,7 @@ pub async fn handle(
}
let db = required_state_db(&session)?;
#[allow(deprecated)]
let input_path = turn.resolve_path(Some(args.csv_path));
let input_path_display = input_path.display().to_string();
let csv_content = tokio::fs::read_to_string(&input_path)
@@ -141,7 +142,10 @@ pub async fn handle(
let job_id = Uuid::new_v4().to_string();
let output_csv_path = args.output_csv_path.map_or_else(
|| default_output_csv_path(&input_path, job_id.as_str()),
|path| turn.resolve_path(Some(path)),
|path| {
#[allow(deprecated)]
turn.resolve_path(Some(path))
},
);
let job_suffix = &job_id[..8];
let job_name = format!("agent-job-{job_suffix}");
@@ -268,7 +268,9 @@ pub(crate) fn apply_spawn_agent_runtime_overrides(
})?;
config.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
config.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
config.cwd = turn.cwd.clone();
#[allow(deprecated)]
let turn_cwd = turn.cwd.clone();
config.cwd = turn_cwd;
config
.permissions
.set_permission_profile(turn.permission_profile())
@@ -2088,6 +2088,7 @@ async fn spawn_agent_reapplies_runtime_sandbox_after_role_config() {
let manager = thread_manager();
session.services.agent_control = manager.agent_control();
let expected_sandbox = turn.config.legacy_sandbox_policy();
#[allow(deprecated)]
let mut expected_file_system_sandbox_policy =
FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(&expected_sandbox, &turn.cwd);
expected_file_system_sandbox_policy
@@ -3767,15 +3768,20 @@ async fn build_agent_spawn_config_uses_turn_context_values() {
..ShellEnvironmentPolicy::default()
};
let temp_dir = tempfile::tempdir().expect("temp dir");
turn.cwd = temp_dir.abs();
#[allow(deprecated)]
{
turn.cwd = temp_dir.abs();
}
turn.codex_linux_sandbox_exe = Some(PathBuf::from("/bin/echo"));
#[allow(deprecated)]
let turn_cwd = turn.cwd.clone();
let sandbox_policy = pick_allowed_sandbox_policy(
&turn.config.permissions.permission_profile,
turn.config.legacy_sandbox_policy(),
turn.cwd.as_path(),
turn_cwd.as_path(),
);
let file_system_sandbox_policy =
FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(&sandbox_policy, &turn.cwd);
FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(&sandbox_policy, &turn_cwd);
let network_sandbox_policy = NetworkSandboxPolicy::from(&sandbox_policy);
let permission_profile = PermissionProfile::from_runtime_permissions_with_enforcement(
SandboxEnforcement::from_legacy_sandbox_policy(&sandbox_policy),
@@ -3798,7 +3804,10 @@ async fn build_agent_spawn_config_uses_turn_context_values() {
expected.compact_prompt = turn.compact_prompt.clone();
expected.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
expected.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
expected.cwd = turn.cwd.clone();
#[allow(deprecated)]
{
expected.cwd = turn.cwd.clone();
}
expected
.permissions
.approval_policy
@@ -3849,7 +3858,10 @@ async fn build_agent_resume_config_clears_base_instructions() {
expected.compact_prompt = turn.compact_prompt.clone();
expected.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
expected.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
expected.cwd = turn.cwd.clone();
#[allow(deprecated)]
{
expected.cwd = turn.cwd.clone();
}
expected
.permissions
.approval_policy
@@ -47,6 +47,7 @@ impl ToolExecutor<ToolInvocation> for RequestPermissionsHandler {
}
};
#[allow(deprecated)]
let mut args: RequestPermissionsArgs =
parse_arguments_with_base_path(&arguments, &turn.cwd)?;
args.permissions = normalize_additional_permissions(args.permissions.into())
@@ -92,6 +92,7 @@ async fn run_exec_like(args: RunExecLikeArgs) -> Result<FunctionToolOutput, Func
let exec_permission_approvals_enabled =
session.features().enabled(Feature::ExecPermissionApprovals);
let requested_additional_permissions = additional_permissions.clone();
#[allow(deprecated)]
let effective_additional_permissions = apply_granted_turn_permissions(
session.as_ref(),
turn.cwd.as_path(),
@@ -181,6 +182,7 @@ async fn run_exec_like(args: RunExecLikeArgs) -> Result<FunctionToolOutput, Func
approval_policy: turn.approval_policy.value(),
permission_profile: turn.permission_profile(),
file_system_sandbox_policy: &file_system_sandbox_policy,
#[allow(deprecated)]
sandbox_cwd: turn.cwd.as_path(),
sandbox_permissions: if effective_additional_permissions.permissions_preapproved {
codex_protocol::models::SandboxPermissions::UseDefault
@@ -92,10 +92,12 @@ impl ShellCommandHandler {
let shell = session.user_shell();
let use_login_shell = Self::resolve_use_login_shell(params.login, allow_login_shell)?;
let command = Self::base_command(shell.as_ref(), &params.command, use_login_shell);
#[allow(deprecated)]
let cwd = turn_context.resolve_path(params.workdir.clone());
Ok(ExecParams {
command,
cwd: turn_context.resolve_path(params.workdir.clone()),
cwd,
expiration: params.timeout_ms.into(),
capture_policy: ExecCapturePolicy::ShellTool,
env: create_env(&turn_context.shell_environment_policy, Some(thread_id)),
@@ -162,8 +164,10 @@ impl ToolExecutor<ToolInvocation> for ShellCommandHandler {
)));
};
#[allow(deprecated)]
let cwd = resolve_workdir_base_path(&arguments, &turn.cwd)?;
let params: ShellCommandToolCallParams = parse_arguments_with_base_path(&arguments, &cwd)?;
#[allow(deprecated)]
let workdir = turn.resolve_path(params.workdir.clone());
maybe_emit_implicit_skill_invocation(
session.as_ref(),
@@ -88,6 +88,7 @@ async fn shell_command_handler_to_exec_params_uses_session_shell_and_turn_contex
let expected_command = session
.user_shell()
.derive_exec_args(&command, /*use_login_shell*/ true);
#[allow(deprecated)]
let expected_cwd = turn_context.resolve_path(workdir.clone());
let expected_env = create_env(
&turn_context.shell_environment_policy,
@@ -282,7 +282,10 @@ mod tests {
let (session, mut turn) = make_session_and_context().await;
let image_dir = tempfile::tempdir().expect("create image temp dir");
let image_cwd = image_dir.abs();
turn.cwd = image_cwd.clone();
#[allow(deprecated)]
{
turn.cwd = image_cwd.clone();
}
turn.environments
.turn_environments
.first_mut()
@@ -525,6 +525,7 @@ impl NetworkApprovalService {
guardian_approval_id,
/*approval_id*/ None,
prompt_command,
#[allow(deprecated)]
turn_context.cwd.clone(),
Some(prompt_reason),
Some(network_approval_context.clone()),
+1
View File
@@ -234,6 +234,7 @@ impl ToolOrchestrator {
// Platform-specific flag gating is handled by SandboxManager::select_initial.
let use_legacy_landlock = turn_ctx.features.use_legacy_landlock();
#[allow(deprecated)]
let sandbox_cwd = tool.sandbox_cwd(req).unwrap_or(&turn_ctx.cwd);
let initial_attempt = SandboxAttempt {
sandbox: initial_sandbox,
+1
View File
@@ -409,6 +409,7 @@ impl ToolRegistry {
"sandbox_policy",
permission_profile_policy_tag(
&invocation.turn.permission_profile,
#[allow(deprecated)]
invocation.turn.cwd.as_path(),
),
),
+7 -2
View File
@@ -83,6 +83,7 @@ async fn exec_command_with_tty(
) -> Result<ExecCommandToolOutput, UnifiedExecError> {
let manager = &session.services.unified_exec_manager;
let process_id = manager.allocate_process_id().await;
#[allow(deprecated)]
let cwd = workdir
.as_ref()
.map_or_else(|| turn.cwd.clone(), |workdir| turn.cwd.join(workdir));
@@ -501,10 +502,12 @@ async fn reusing_completed_process_returns_unknown_process() -> anyhow::Result<(
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn completed_pipe_commands_preserve_exit_code() -> anyhow::Result<()> {
let (_, turn) = make_session_and_context().await;
#[allow(deprecated)]
let cwd = turn.cwd.clone();
let request = test_exec_request(
&turn,
vec!["bash".to_string(), "-lc".to_string(), "exit 17".to_string()],
turn.cwd.clone(),
cwd,
shell_env(),
);
@@ -598,10 +601,12 @@ async fn remote_exec_server_rejects_inherited_fd_launches() -> anyhow::Result<()
turn.environments.turn_environments[0].environment =
Arc::new(remote_test_env.environment().clone());
#[allow(deprecated)]
let cwd = turn.cwd.clone();
let request = test_exec_request(
&turn,
vec!["bash".to_string(), "-lc".to_string(), "echo ok".to_string()],
turn.cwd.clone(),
cwd,
shell_env(),
);
@@ -175,7 +175,9 @@ async fn failed_initial_end_for_unstored_process_uses_fallback_output() {
process_id: 123,
yield_time_ms: 1000,
max_output_tokens: None,
#[allow(deprecated)]
cwd: turn.cwd.clone(),
#[allow(deprecated)]
sandbox_cwd: turn.cwd.clone(),
environment: turn
.environments
@@ -200,6 +202,7 @@ async fn failed_initial_end_for_unstored_process_uses_fallback_output() {
/*process_started_alive*/ false,
&context,
&request,
#[allow(deprecated)]
turn.cwd.clone(),
transcript,
"PRE_DENIAL_MARKER".to_string(),