From f85e81d30be6a57705bbd957e287de000a4870d2 Mon Sep 17 00:00:00 2001 From: sayan-oai Date: Sun, 16 Aug 2026 20:22:06 +0000 Subject: [PATCH] Move requirements policy ownership to execpolicy (#38899) ## What changed - Define and export `RequirementsExecPolicy` from `codex-execpolicy`, alongside the underlying `Policy` type. - Re-export the type from `codex-config` so existing config consumers retain the same API. - Preserve its order-independent equality and `AsRef` behavior. GitOrigin-RevId: e94c56b36824d07f2bc7ba14ce40bdb770d4ab46 --- codex-rs/config/src/config_requirements.rs | 2 +- codex-rs/config/src/lib.rs | 2 +- .../config/src/requirements_exec_policy.rs | 37 +------------------ codex-rs/execpolicy/src/lib.rs | 1 + codex-rs/execpolicy/src/policy.rs | 37 +++++++++++++++++++ 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/codex-rs/config/src/config_requirements.rs b/codex-rs/config/src/config_requirements.rs index 5cb8112097..b3154ca056 100644 --- a/codex-rs/config/src/config_requirements.rs +++ b/codex-rs/config/src/config_requirements.rs @@ -17,12 +17,12 @@ use std::fmt; use std::path::PathBuf; use wildmatch::WildMatchPattern; -use super::requirements_exec_policy::RequirementsExecPolicy; use super::requirements_exec_policy::RequirementsExecPolicyToml; use crate::Constrained; use crate::ConstraintError; use crate::ManagedAuthPolicy; use crate::ManagedHooksRequirementsToml; +use crate::RequirementsExecPolicy; use crate::config_toml::ConfigToml; use crate::mcp_requirements::McpServerRequirement; use crate::mcp_types::AppToolApproval; diff --git a/codex-rs/config/src/lib.rs b/codex-rs/config/src/lib.rs index bbe0e17acc..5baef30168 100644 --- a/codex-rs/config/src/lib.rs +++ b/codex-rs/config/src/lib.rs @@ -48,6 +48,7 @@ pub use cloud_config_layers::CloudConfigFragment; pub use cloud_config_layers::CloudConfigFragmentSource; pub use cloud_config_layers::CloudConfigLayerError; pub use cloud_config_layers::cloud_config_layers_from_fragments; +pub use codex_execpolicy::RequirementsExecPolicy; pub use codex_protocol::config_types::ProfileV2Name; pub use codex_protocol::config_types::ProfileV2NameParseError; pub use codex_protocol::config_types::ToolExposureSurface; @@ -144,7 +145,6 @@ pub use plugin_edit::clear_user_plugin; pub use plugin_edit::set_user_plugin_enabled; pub use project_root_markers::default_project_root_markers; pub use project_root_markers::project_root_markers_from_config; -pub use requirements_exec_policy::RequirementsExecPolicy; pub use requirements_exec_policy::RequirementsExecPolicyDecisionToml; pub use requirements_exec_policy::RequirementsExecPolicyParseError; pub use requirements_exec_policy::RequirementsExecPolicyPatternTokenToml; diff --git a/codex-rs/config/src/requirements_exec_policy.rs b/codex-rs/config/src/requirements_exec_policy.rs index 95f02b249f..4bdd425236 100644 --- a/codex-rs/config/src/requirements_exec_policy.rs +++ b/codex-rs/config/src/requirements_exec_policy.rs @@ -1,5 +1,6 @@ use codex_execpolicy::Decision; use codex_execpolicy::Policy; +use codex_execpolicy::RequirementsExecPolicy; use codex_execpolicy::RuleRef; use codex_execpolicy::rule::PatternToken; use codex_execpolicy::rule::PrefixPattern; @@ -9,42 +10,6 @@ use serde::Deserialize; use std::sync::Arc; use thiserror::Error; -#[derive(Debug, Clone)] -pub struct RequirementsExecPolicy { - policy: Policy, -} - -impl RequirementsExecPolicy { - pub fn new(policy: Policy) -> Self { - Self { policy } - } -} - -impl PartialEq for RequirementsExecPolicy { - fn eq(&self, other: &Self) -> bool { - policy_fingerprint(&self.policy) == policy_fingerprint(&other.policy) - } -} - -impl Eq for RequirementsExecPolicy {} - -impl AsRef for RequirementsExecPolicy { - fn as_ref(&self) -> &Policy { - &self.policy - } -} - -fn policy_fingerprint(policy: &Policy) -> Vec { - let mut entries = Vec::new(); - for (program, rules) in policy.rules().iter_all() { - for rule in rules { - entries.push(format!("{program}:{rule:?}")); - } - } - entries.sort(); - entries -} - /// TOML representation of `[rules]` within `requirements.toml`. #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] pub struct RequirementsExecPolicyToml { diff --git a/codex-rs/execpolicy/src/lib.rs b/codex-rs/execpolicy/src/lib.rs index 495c0d74a3..293e275058 100644 --- a/codex-rs/execpolicy/src/lib.rs +++ b/codex-rs/execpolicy/src/lib.rs @@ -22,6 +22,7 @@ pub use parser::PolicyParser; pub use policy::Evaluation; pub use policy::MatchOptions; pub use policy::Policy; +pub use policy::RequirementsExecPolicy; pub use rule::NetworkRuleProtocol; pub use rule::PatternToken; pub use rule::PrefixPattern; diff --git a/codex-rs/execpolicy/src/policy.rs b/codex-rs/execpolicy/src/policy.rs index 3102264e39..cf268ac6e7 100644 --- a/codex-rs/execpolicy/src/policy.rs +++ b/codex-rs/execpolicy/src/policy.rs @@ -31,6 +31,43 @@ pub struct Policy { host_executables_by_name: HashMap>, } +/// A requirements-owned execution policy with order-independent equality. +#[derive(Debug, Clone)] +pub struct RequirementsExecPolicy { + policy: Policy, +} + +impl RequirementsExecPolicy { + pub fn new(policy: Policy) -> Self { + Self { policy } + } +} + +impl PartialEq for RequirementsExecPolicy { + fn eq(&self, other: &Self) -> bool { + policy_fingerprint(&self.policy) == policy_fingerprint(&other.policy) + } +} + +impl Eq for RequirementsExecPolicy {} + +impl AsRef for RequirementsExecPolicy { + fn as_ref(&self) -> &Policy { + &self.policy + } +} + +fn policy_fingerprint(policy: &Policy) -> Vec { + let mut entries = Vec::new(); + for (program, rules) in policy.rules().iter_all() { + for rule in rules { + entries.push(format!("{program}:{rule:?}")); + } + } + entries.sort(); + entries +} + impl Policy { pub fn new(rules_by_program: MultiMap) -> Self { Self::from_parts(rules_by_program, Vec::new(), HashMap::new())