From 68ccfdc9056f7305b96a9c33a953bc9177c47a08 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 15 May 2026 08:59:31 -0700 Subject: [PATCH] guardian: use permission profile for review sandbox (#22789) ## Why `SandboxPolicy` is being pushed back toward legacy config loading and compatibility boundaries. Guardian review sessions already want the built-in read-only permission behavior; carrying that as an active `PermissionProfile` makes the review sandbox follow the new permissions path instead of configuring the child session through the legacy policy API. ## What Changed - Configure the guardian review session with `PermissionProfile::read_only()`. - Send the read-only profile through the guardian child `Op::UserTurn`. - Keep the legacy `sandbox_policy` field populated with `SandboxPolicy::new_read_only_policy()` declared next to the profile so the two remain visibly in sync until the compatibility field goes away. ## How To Review Start in `codex-rs/core/src/guardian/review_session.rs`. The important check is that both the guardian config and the child turn now use the read-only permission profile, while the remaining `SandboxPolicy::ReadOnly` assignment is only the compatibility field required by the current turn protocol. ## Verification - `cargo test -p codex-core guardian_review_session_config_clears_parent_developer_instructions` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22789). * #22795 * #22792 * #22791 * #22790 * __->__ #22789 --- codex-rs/core/src/guardian/review_session.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index 2f1554891..afb5882a6 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -9,6 +9,7 @@ use codex_analytics::GuardianReviewAnalyticsResult; use codex_analytics::GuardianReviewSessionKind; use codex_protocol::config_types::Personality; use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig; +use codex_protocol::models::PermissionProfile; use codex_protocol::models::ResponseItem; use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig; use codex_protocol::protocol::AskForApproval; @@ -698,6 +699,9 @@ async fn run_review_on_session( .total_token_usage() .await .unwrap_or_default(); + // The legacy SandboxPolicy should match the PermissionProfile. + let guardian_permission_profile = PermissionProfile::read_only(); + let legacy_sandbox_policy = SandboxPolicy::new_read_only_policy(); let submit_result = run_before_review_deadline( deadline, @@ -709,8 +713,8 @@ async fn run_review_on_session( cwd: params.parent_turn.cwd.to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy: legacy_sandbox_policy, + permission_profile: Some(guardian_permission_profile), model: params.model.clone(), effort: params.reasoning_effort, summary: Some(params.reasoning_summary), @@ -892,12 +896,11 @@ pub(crate) fn build_guardian_review_session_config( ); guardian_config.developer_instructions = None; guardian_config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never); - let sandbox_policy = SandboxPolicy::new_read_only_policy(); guardian_config .permissions - .set_legacy_sandbox_policy(sandbox_policy, guardian_config.cwd.as_path()) + .set_permission_profile(PermissionProfile::read_only()) .map_err(|err| { - anyhow::anyhow!("guardian review session could not set sandbox policy: {err}") + anyhow::anyhow!("guardian review session could not set permission profile: {err}") })?; guardian_config.include_apps_instructions = false; guardian_config