diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index 376575a565..c1c9384c95 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -714,7 +714,7 @@ async fn run_review_on_session( approval_policy: AskForApproval::Never, approvals_reviewer: None, sandbox_policy: None, - permission_profile: Some(permission_profile), + permission_profile, model: params.model.clone(), effort: params.reasoning_effort, summary: Some(params.reasoning_summary), diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index e2dce6e693..12f1451d89 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -134,7 +134,7 @@ pub(super) async fn user_input_or_turn_inner( cwd, approval_policy, approvals_reviewer, - sandbox_policy, + sandbox_policy: _, permission_profile, model, effort, @@ -156,24 +156,15 @@ pub(super) async fn user_input_or_turn_inner( }, }) }); - let clear_active_permission_profile = - permission_profile.is_none() && sandbox_policy.is_some(); - let permission_profile = permission_profile_with_legacy_fallback( - sess, - sandbox_policy.as_ref(), - permission_profile, - Some(cwd.as_path()), - ) - .await; ( items, SessionSettingsUpdate { cwd: Some(cwd), approval_policy: Some(approval_policy), approvals_reviewer, - permission_profile, + permission_profile: Some(permission_profile), active_permission_profile: None, - clear_active_permission_profile, + clear_active_permission_profile: false, windows_sandbox_level: None, collaboration_mode, reasoning_summary: summary, diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 2b36346292..6b21c7c0c5 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -4248,7 +4248,7 @@ async fn user_turn_updates_approvals_reviewer() { approval_policy: config.permissions.approval_policy.value(), approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), sandbox_policy: None, - permission_profile: Some(config.permissions.permission_profile()), + permission_profile: config.permissions.permission_profile(), model: turn_context.model_info.slug.clone(), effort: config.model_reasoning_effort, summary: config.model_reasoning_summary, diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index be4e8000bb..1d334b9593 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -212,9 +212,9 @@ pub fn turn_permission_fields( _cwd: &Path, ) -> ( Option, - Option, + PermissionProfile, ) { - (None, Some(permission_profile)) + (None, permission_profile) } pub struct TestCodexBuilder { @@ -704,8 +704,6 @@ impl TestCodex { service_tier: Option>, environments: Option>, ) -> Result<()> { - let (sandbox_policy, permission_profile) = - turn_permission_fields(permission_profile, self.config.cwd.as_path()); let session_model = self.session_configured.model.clone(); self.codex .submit(Op::UserTurn { @@ -718,7 +716,7 @@ impl TestCodex { cwd: self.config.cwd.to_path_buf(), approval_policy, approvals_reviewer: None, - sandbox_policy, + sandbox_policy: None, permission_profile, model: session_model, effort: None, diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 09f3cc7b18..ea90b3ab97 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -447,7 +447,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy, - permission_profile, + permission_profile: Some(permission_profile), windows_sandbox_level: None, model: None, effort: Some(Some(ReasoningEffort::High)), diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 3f3c29fc95..d70f0669bc 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -541,20 +541,17 @@ pub enum Op { /// When omitted, the session keeps the current setting approvals_reviewer: Option, - /// Legacy sandbox policy to use for tool calls such as `local_shell`. + /// Deprecated legacy sandbox policy field. /// - /// When omitted, `permission_profile` is used as the canonical source - /// of permissions. This field is kept only as a compatibility fallback - /// for older callers that have not migrated to `permission_profile`. + /// `permission_profile` is required and is the canonical source for + /// `UserTurn` operations. This field is ignored by core and remains + /// only as a temporary compatibility slot while callers finish + /// migrating. #[serde(default, skip_serializing_if = "Option::is_none")] sandbox_policy: Option, /// Full permissions profile to use for tool calls such as `local_shell`. - /// - /// When omitted, `sandbox_policy` is used as a legacy compatibility - /// projection. - #[serde(default, skip_serializing_if = "Option::is_none")] - permission_profile: Option, + permission_profile: PermissionProfile, /// Must be a valid model slug for the configured client session /// associated with this conversation. diff --git a/codex-rs/tui/src/app_command.rs b/codex-rs/tui/src/app_command.rs index 87d0c75be4..92df9d1d91 100644 --- a/codex-rs/tui/src/app_command.rs +++ b/codex-rs/tui/src/app_command.rs @@ -24,8 +24,6 @@ use codex_protocol::user_input::UserInput; use serde::Serialize; use serde_json::Value; -use crate::permission_compat::legacy_compatible_sandbox_policy; - #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Serialize)] pub(crate) enum AppCommand { @@ -377,7 +375,7 @@ impl AppCommand { approval_policy, approvals_reviewer, sandbox_policy: None, - permission_profile: Some(permission_profile), + permission_profile, model, effort, summary, @@ -592,7 +590,7 @@ impl From for AppCommand { approval_policy, approvals_reviewer, sandbox_policy, - permission_profile: Some(permission_profile), + permission_profile, model, effort, summary, @@ -601,12 +599,7 @@ impl From for AppCommand { collaboration_mode, personality, } => { - if environments.is_none() - && sandbox_policy.as_ref().is_none_or(|sandbox_policy| { - legacy_compatible_sandbox_policy(&permission_profile, cwd.as_path()) - == *sandbox_policy - }) - { + if environments.is_none() { Self::UserTurn { items, cwd, @@ -628,7 +621,7 @@ impl From for AppCommand { approval_policy, approvals_reviewer, sandbox_policy, - permission_profile: Some(permission_profile), + permission_profile, model, effort, summary, diff --git a/codex-rs/tui/src/chatwidget/tests/composer_submission.rs b/codex-rs/tui/src/chatwidget/tests/composer_submission.rs index e2ac788da2..bda33bc17c 100644 --- a/codex-rs/tui/src/chatwidget/tests/composer_submission.rs +++ b/codex-rs/tui/src/chatwidget/tests/composer_submission.rs @@ -150,7 +150,7 @@ async fn submission_includes_configured_permission_profile() { } => permission_profile, other => panic!("expected Op::UserTurn, got {other:?}"), }; - assert_eq!(permission_profile, Some(expected_permission_profile)); + assert_eq!(permission_profile, expected_permission_profile); } #[tokio::test] @@ -198,7 +198,7 @@ async fn submission_keeps_profile_when_legacy_projection_is_external() { } => permission_profile, other => panic!("expected Op::UserTurn, got {other:?}"), }; - assert_eq!(permission_profile, Some(expected_permission_profile)); + assert_eq!(permission_profile, expected_permission_profile); } #[tokio::test]