From 414cad772cf06f441c7e86364680e2ec1239cdde Mon Sep 17 00:00:00 2001 From: Dylan Hurd Date: Sat, 16 May 2026 01:56:12 -0700 Subject: [PATCH] chore(permissions) Move approved commands to environment_context --- .../core/src/context/environment_context.rs | 14 ++ .../src/context/environment_context_tests.rs | 31 ++++ .../src/context/permissions_instructions.rs | 29 +-- .../context/permissions_instructions_tests.rs | 46 +---- codex-rs/core/src/context_manager/updates.rs | 6 +- codex-rs/core/src/session/mod.rs | 6 +- .../core/tests/suite/permissions_messages.rs | 174 +++++++++++++++++- 7 files changed, 231 insertions(+), 75 deletions(-) diff --git a/codex-rs/core/src/context/environment_context.rs b/codex-rs/core/src/context/environment_context.rs index 272e3c617d..c562c77748 100644 --- a/codex-rs/core/src/context/environment_context.rs +++ b/codex-rs/core/src/context/environment_context.rs @@ -14,6 +14,7 @@ pub(crate) struct EnvironmentContext { pub(crate) timezone: Option, pub(crate) network: Option, pub(crate) subagents: Option, + pub(crate) approved_command_prefixes: Option, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -130,6 +131,7 @@ impl EnvironmentContext { timezone, network, subagents, + approved_command_prefixes: None, } } @@ -146,6 +148,7 @@ impl EnvironmentContext { timezone, network, subagents, + approved_command_prefixes: None, } } @@ -158,6 +161,7 @@ impl EnvironmentContext { && self.timezone == other.timezone && self.network == other.network && self.subagents == other.subagents + && self.approved_command_prefixes == other.approved_command_prefixes } pub(crate) fn diff_from_turn_context_item( @@ -232,6 +236,11 @@ impl EnvironmentContext { self } + pub(crate) fn with_approved_command_prefixes(mut self, prefixes: Option) -> Self { + self.approved_command_prefixes = prefixes.filter(|prefixes| !prefixes.is_empty()); + self + } + fn network_from_turn_context(turn_context: &TurnContext) -> Option { let network = turn_context .config @@ -318,6 +327,11 @@ impl ContextualUserFragment for EnvironmentContext { lines.extend(subagents.lines().map(|line| format!(" {line}"))); lines.push(" ".to_string()); } + if let Some(prefixes) = &self.approved_command_prefixes { + lines.push(" ".to_string()); + lines.extend(prefixes.lines().map(|line| format!(" {line}"))); + lines.push(" ".to_string()); + } format!("\n{}\n", lines.join("\n")) } } diff --git a/codex-rs/core/src/context/environment_context_tests.rs b/codex-rs/core/src/context/environment_context_tests.rs index 68ff7c9d44..761f6b8b9d 100644 --- a/codex-rs/core/src/context/environment_context_tests.rs +++ b/codex-rs/core/src/context/environment_context_tests.rs @@ -211,6 +211,37 @@ fn serialize_environment_context_with_subagents() { assert_eq!(context.render(), expected); } +#[test] +fn serialize_environment_context_with_approved_command_prefixes() { + let context = EnvironmentContext::new( + vec![EnvironmentContextEnvironment { + id: "local".to_string(), + cwd: test_path_buf("/repo").abs(), + shell: fake_shell_name(), + }], + Some("2026-02-26".to_string()), + Some("America/Los_Angeles".to_string()), + /*network*/ None, + /*subagents*/ None, + ) + .with_approved_command_prefixes(Some("- [\"git\", \"pull\"]".to_string())); + + let expected = format!( + r#" + {} + bash + 2026-02-26 + America/Los_Angeles + + - ["git", "pull"] + +"#, + test_path_buf("/repo").display() + ); + + assert_eq!(context.render(), expected); +} + #[test] fn serialize_environment_context_with_multiple_selected_environments() { let local_cwd = test_path_buf("/repo/local"); diff --git a/codex-rs/core/src/context/permissions_instructions.rs b/codex-rs/core/src/context/permissions_instructions.rs index e982ca17d2..f30c067b36 100644 --- a/codex-rs/core/src/context/permissions_instructions.rs +++ b/codex-rs/core/src/context/permissions_instructions.rs @@ -1,9 +1,7 @@ use super::ContextualUserFragment; -use codex_execpolicy::Policy; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::SandboxMode; use codex_protocol::models::PermissionProfile; -use codex_protocol::models::format_allow_prefixes; use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::GranularApprovalConfig; @@ -43,10 +41,9 @@ static SANDBOX_MODE_READ_ONLY_TEMPLATE: LazyLock