Codex Handbook
config/src/config_requirements.rs 3522 lines
use codex_protocol::config_types::ApprovalsReviewer;use codex_protocol::config_types::SandboxMode;use codex_protocol::config_types::WebSearchMode;use codex_protocol::models::PermissionProfile;use codex_protocol::protocol::AskForApproval;use codex_utils_absolute_path::AbsolutePathBuf;use serde::Deserialize;use serde::Serialize;use serde::de::Error as _;use serde::de::value::Error as ValueDeserializerError;use serde::de::value::StrDeserializer;use std::collections::BTreeMap;use std::fmt;use wildmatch::WildMatchPattern;use super::requirements_exec_policy::RequirementsExecPolicy;use super::requirements_exec_policy::RequirementsExecPolicyToml;use crate::Constrained;use crate::ConstraintError;use crate::ManagedHooksRequirementsToml;use crate::mcp_types::AppToolApproval;use crate::permissions_toml::PermissionProfileToml;use crate::types::WindowsSandboxModeToml;#[derive(Debug, Clone, PartialEq, Eq)]pub enum RequirementSource {    Unknown,    MdmManagedPreferences {        domain: String,        key: String,    },    /// Multiple requirements layers contributed to the final value. Sources are    /// stored highest-priority first, matching the order surfaced in errors.    Composite {        sources: Vec<RequirementSource>,    },    /// A backend-delivered enterprise-managed layer. `id` is the stable backend    /// identifier; `name` is the admin-facing display name.    EnterpriseManaged {        id: String,        name: String,    },    SystemRequirementsToml {        file: AbsolutePathBuf,    },    LegacyManagedConfigTomlFromFile {        file: AbsolutePathBuf,    },    LegacyManagedConfigTomlFromMdm,}impl RequirementSource {    pub fn composite(sources: impl IntoIterator<Item = RequirementSource>) -> Self {        let mut flattened = Vec::new();        for source in sources {            source.append_to_composite(&mut flattened);        }        match flattened.len() {            0 => RequirementSource::Unknown,            1 => flattened.remove(0),            _ => RequirementSource::Composite { sources: flattened },        }    }    fn append_to_composite(self, flattened: &mut Vec<RequirementSource>) {        match self {            RequirementSource::Composite { sources } => {                for source in sources {                    source.append_to_composite(flattened);                }            }            source => {                if !flattened.contains(&source) {                    flattened.push(source);                }            }        }    }}impl fmt::Display for RequirementSource {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        match self {            RequirementSource::Unknown => write!(f, "<unspecified>"),            RequirementSource::MdmManagedPreferences { domain, key } => {                write!(f, "MDM {domain}:{key}")            }            RequirementSource::Composite { sources } => {                write!(f, "requirements layers: ")?;                for (index, source) in sources.iter().enumerate() {                    if index > 0 {                        write!(f, ", ")?;                    }                    write!(f, "{source}")?;                }                Ok(())            }            RequirementSource::EnterpriseManaged { id, name } => {                write!(f, "enterprise-managed requirements {name} ({id})")            }            RequirementSource::SystemRequirementsToml { file } => {                write!(f, "{}", file.as_path().display())            }            RequirementSource::LegacyManagedConfigTomlFromFile { file } => {                write!(f, "{}", file.as_path().display())            }            RequirementSource::LegacyManagedConfigTomlFromMdm => {                write!(f, "MDM managed_config.toml (legacy)")            }        }    }}#[derive(Debug, Clone, PartialEq)]pub struct ConstrainedWithSource<T> {    pub value: Constrained<T>,    pub source: Option<RequirementSource>,}impl<T> ConstrainedWithSource<T> {    pub fn new(value: Constrained<T>, source: Option<RequirementSource>) -> Self {        Self { value, source }    }}impl<T> std::ops::Deref for ConstrainedWithSource<T> {    type Target = Constrained<T>;    fn deref(&self) -> &Self::Target {        &self.value    }}impl<T> std::ops::DerefMut for ConstrainedWithSource<T> {    fn deref_mut(&mut self) -> &mut Self::Target {        &mut self.value    }}/// Normalized version of [`ConfigRequirementsToml`] after deserialization and/// normalization.#[derive(Debug, Clone, PartialEq)]pub struct ConfigRequirements {    pub approval_policy: ConstrainedWithSource<AskForApproval>,    pub approvals_reviewer: ConstrainedWithSource<ApprovalsReviewer>,    pub permission_profile: ConstrainedWithSource<PermissionProfile>,    pub windows_sandbox_mode: ConstrainedWithSource<Option<WindowsSandboxModeToml>>,    pub web_search_mode: ConstrainedWithSource<WebSearchMode>,    pub allow_managed_hooks_only: Option<Sourced<bool>>,    pub allow_appshots: Option<Sourced<bool>>,    pub allow_remote_control: Option<Sourced<bool>>,    pub computer_use: Option<Sourced<ComputerUseRequirementsToml>>,    pub feature_requirements: Option<Sourced<FeatureRequirementsToml>>,    pub managed_hooks: Option<ConstrainedWithSource<ManagedHooksRequirementsToml>>,    pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,    pub plugins: Option<Sourced<BTreeMap<String, PluginRequirementsToml>>>,    pub exec_policy: Option<Sourced<RequirementsExecPolicy>>,    pub enforce_residency: ConstrainedWithSource<Option<ResidencyRequirement>>,    /// Managed network constraints derived from requirements.    pub network: Option<Sourced<NetworkConstraints>>,    /// Managed filesystem constraints derived from requirements.    pub filesystem: Option<Sourced<FilesystemConstraints>>,    /// Source for the managed guardian policy config, when one is configured.    pub guardian_policy_config_source: Option<RequirementSource>,}impl Default for ConfigRequirements {    fn default() -> Self {        Self {            approval_policy: ConstrainedWithSource::new(                Constrained::allow_any_from_default(),                /*source*/ None,            ),            approvals_reviewer: ConstrainedWithSource::new(                Constrained::allow_any_from_default(),                /*source*/ None,            ),            permission_profile: ConstrainedWithSource::new(                Constrained::allow_any(PermissionProfile::read_only()),                /*source*/ None,            ),            windows_sandbox_mode: ConstrainedWithSource::new(                Constrained::allow_any(/*initial_value*/ None),                /*source*/ None,            ),            web_search_mode: ConstrainedWithSource::new(                Constrained::allow_any(WebSearchMode::Cached),                /*source*/ None,            ),            allow_managed_hooks_only: None,            allow_appshots: None,            allow_remote_control: None,            computer_use: None,            feature_requirements: None,            managed_hooks: None,            mcp_servers: None,            plugins: None,            exec_policy: None,            enforce_residency: ConstrainedWithSource::new(                Constrained::allow_any(/*initial_value*/ None),                /*source*/ None,            ),            network: None,            filesystem: None,            guardian_policy_config_source: None,        }    }}impl ConfigRequirements {    pub fn exec_policy_source(&self) -> Option<&RequirementSource> {        self.exec_policy.as_ref().map(|policy| &policy.source)    }}#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]#[serde(untagged)]pub enum McpServerIdentity {    Command { command: String },    Url { url: String },}#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]pub struct McpServerRequirement {    pub identity: McpServerIdentity,}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct PluginRequirementsToml {    pub mcp_servers: Option<BTreeMap<String, McpServerRequirement>>,}impl PluginRequirementsToml {    pub fn is_empty(&self) -> bool {        self.mcp_servers.as_ref().is_none_or(BTreeMap::is_empty)    }}#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct NetworkDomainPermissionsToml {    #[serde(flatten)]    pub entries: BTreeMap<String, NetworkDomainPermissionToml>,}impl NetworkDomainPermissionsToml {    pub fn is_empty(&self) -> bool {        self.entries.is_empty()    }    pub fn allowed_domains(&self) -> Option<Vec<String>> {        let allowed_domains: Vec<String> = self            .entries            .iter()            .filter(|(_, permission)| matches!(permission, NetworkDomainPermissionToml::Allow))            .map(|(pattern, _)| pattern.clone())            .collect();        (!allowed_domains.is_empty()).then_some(allowed_domains)    }    pub fn denied_domains(&self) -> Option<Vec<String>> {        let denied_domains: Vec<String> = self            .entries            .iter()            .filter(|(_, permission)| matches!(permission, NetworkDomainPermissionToml::Deny))            .map(|(pattern, _)| pattern.clone())            .collect();        (!denied_domains.is_empty()).then_some(denied_domains)    }}#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]#[serde(rename_all = "lowercase")]pub enum NetworkDomainPermissionToml {    Allow,    Deny,}impl std::fmt::Display for NetworkDomainPermissionToml {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        let permission = match self {            Self::Allow => "allow",            Self::Deny => "deny",        };        f.write_str(permission)    }}#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct NetworkUnixSocketPermissionsToml {    #[serde(flatten)]    pub entries: BTreeMap<String, NetworkUnixSocketPermissionToml>,}impl NetworkUnixSocketPermissionsToml {    pub fn is_empty(&self) -> bool {        self.entries.is_empty()    }    pub fn allow_unix_sockets(&self) -> Vec<String> {        self.entries            .iter()            .filter(|(_, permission)| matches!(permission, NetworkUnixSocketPermissionToml::Allow))            .map(|(path, _)| path.clone())            .collect()    }}#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]#[serde(rename_all = "lowercase")]pub enum NetworkUnixSocketPermissionToml {    Allow,    Deny,}impl std::fmt::Display for NetworkUnixSocketPermissionToml {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        let permission = match self {            Self::Allow => "allow",            Self::Deny => "deny",        };        f.write_str(permission)    }}#[derive(Serialize, Debug, Clone, Default, PartialEq, Eq)]pub struct NetworkRequirementsToml {    pub enabled: Option<bool>,    pub http_port: Option<u16>,    pub socks_port: Option<u16>,    pub allow_upstream_proxy: Option<bool>,    pub dangerously_allow_non_loopback_proxy: Option<bool>,    pub dangerously_allow_all_unix_sockets: Option<bool>,    pub domains: Option<NetworkDomainPermissionsToml>,    /// When true, only managed `allowed_domains` are respected while managed    /// network enforcement is active. User allowlist entries are ignored.    pub managed_allowed_domains_only: Option<bool>,    pub unix_sockets: Option<NetworkUnixSocketPermissionsToml>,    pub allow_local_binding: Option<bool>,}#[derive(Deserialize)]struct RawNetworkRequirementsToml {    enabled: Option<bool>,    http_port: Option<u16>,    socks_port: Option<u16>,    allow_upstream_proxy: Option<bool>,    dangerously_allow_non_loopback_proxy: Option<bool>,    dangerously_allow_all_unix_sockets: Option<bool>,    domains: Option<NetworkDomainPermissionsToml>,    #[serde(default)]    allowed_domains: Option<Vec<String>>,    /// When true, only managed `allowed_domains` are respected while managed    /// network enforcement is active. User allowlist entries are ignored.    managed_allowed_domains_only: Option<bool>,    #[serde(default)]    denied_domains: Option<Vec<String>>,    unix_sockets: Option<NetworkUnixSocketPermissionsToml>,    #[serde(default)]    allow_unix_sockets: Option<Vec<String>>,    allow_local_binding: Option<bool>,}impl<'de> Deserialize<'de> for NetworkRequirementsToml {    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>    where        D: serde::Deserializer<'de>,    {        let raw = RawNetworkRequirementsToml::deserialize(deserializer)?;        let RawNetworkRequirementsToml {            enabled,            http_port,            socks_port,            allow_upstream_proxy,            dangerously_allow_non_loopback_proxy,            dangerously_allow_all_unix_sockets,            domains,            allowed_domains,            managed_allowed_domains_only,            denied_domains,            unix_sockets,            allow_unix_sockets,            allow_local_binding,        } = raw;        if domains.is_some() && (allowed_domains.is_some() || denied_domains.is_some()) {            return Err(D::Error::custom(                "`experimental_network.domains` cannot be combined with legacy `allowed_domains` or `denied_domains`",            ));        }        if unix_sockets.is_some() && allow_unix_sockets.is_some() {            return Err(D::Error::custom(                "`experimental_network.unix_sockets` cannot be combined with legacy `allow_unix_sockets`",            ));        }        Ok(Self {            enabled,            http_port,            socks_port,            allow_upstream_proxy,            dangerously_allow_non_loopback_proxy,            dangerously_allow_all_unix_sockets,            domains: domains                .or_else(|| legacy_domain_permissions_from_lists(allowed_domains, denied_domains)),            managed_allowed_domains_only,            unix_sockets: unix_sockets                .or_else(|| legacy_unix_socket_permissions_from_list(allow_unix_sockets)),            allow_local_binding,        })    }}/// Legacy list normalization is intentionally lossy: explicit empty legacy/// lists are treated as unset when converted to the canonical network/// permission shape.fn legacy_domain_permissions_from_lists(    allowed_domains: Option<Vec<String>>,    denied_domains: Option<Vec<String>>,) -> Option<NetworkDomainPermissionsToml> {    let mut entries = BTreeMap::new();    for pattern in allowed_domains.unwrap_or_default() {        entries.insert(pattern, NetworkDomainPermissionToml::Allow);    }    for pattern in denied_domains.unwrap_or_default() {        entries.insert(pattern, NetworkDomainPermissionToml::Deny);    }    (!entries.is_empty()).then_some(NetworkDomainPermissionsToml { entries })}fn legacy_unix_socket_permissions_from_list(    allow_unix_sockets: Option<Vec<String>>,) -> Option<NetworkUnixSocketPermissionsToml> {    let entries = allow_unix_sockets        .unwrap_or_default()        .into_iter()        .map(|path| (path, NetworkUnixSocketPermissionToml::Allow))        .collect::<BTreeMap<_, _>>();    (!entries.is_empty()).then_some(NetworkUnixSocketPermissionsToml { entries })}/// Normalized network constraints derived from requirements TOML.#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]pub struct NetworkConstraints {    pub enabled: Option<bool>,    pub http_port: Option<u16>,    pub socks_port: Option<u16>,    pub allow_upstream_proxy: Option<bool>,    pub dangerously_allow_non_loopback_proxy: Option<bool>,    pub dangerously_allow_all_unix_sockets: Option<bool>,    pub domains: Option<NetworkDomainPermissionsToml>,    /// When true, only managed `allowed_domains` are respected while managed    /// network enforcement is active. User allowlist entries are ignored.    pub managed_allowed_domains_only: Option<bool>,    pub unix_sockets: Option<NetworkUnixSocketPermissionsToml>,    pub allow_local_binding: Option<bool>,}impl<'de> Deserialize<'de> for NetworkConstraints {    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>    where        D: serde::Deserializer<'de>,    {        let requirements = NetworkRequirementsToml::deserialize(deserializer)?;        Ok(requirements.into())    }}impl From<NetworkRequirementsToml> for NetworkConstraints {    fn from(value: NetworkRequirementsToml) -> Self {        let NetworkRequirementsToml {            enabled,            http_port,            socks_port,            allow_upstream_proxy,            dangerously_allow_non_loopback_proxy,            dangerously_allow_all_unix_sockets,            domains,            managed_allowed_domains_only,            unix_sockets,            allow_local_binding,        } = value;        Self {            enabled,            http_port,            socks_port,            allow_upstream_proxy,            dangerously_allow_non_loopback_proxy,            dangerously_allow_all_unix_sockets,            domains,            managed_allowed_domains_only,            unix_sockets,            allow_local_binding,        }    }}#[derive(Debug, Clone, Default, PartialEq, Eq)]pub struct FilesystemRequirementsToml {    pub deny_read: Option<Vec<FilesystemDenyReadPattern>>,}#[derive(Deserialize)]struct RawFilesystemRequirementsToml {    deny_read: Option<Vec<FilesystemDenyReadPattern>>,    description: Option<serde::de::IgnoredAny>,    extends: Option<serde::de::IgnoredAny>,    workspace_roots: Option<serde::de::IgnoredAny>,    filesystem: Option<serde::de::IgnoredAny>,    network: Option<serde::de::IgnoredAny>,}impl<'de> Deserialize<'de> for FilesystemRequirementsToml {    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>    where        D: serde::Deserializer<'de>,    {        let raw = RawFilesystemRequirementsToml::deserialize(deserializer)?;        let RawFilesystemRequirementsToml {            deny_read,            description,            extends,            workspace_roots,            filesystem,            network,        } = raw;        if description.is_some()            || extends.is_some()            || workspace_roots.is_some()            || filesystem.is_some()            || network.is_some()        {            return Err(D::Error::custom(                "`permissions.filesystem` is reserved for requirements-level filesystem constraints and cannot define a profile",            ));        }        Ok(Self { deny_read })    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct PermissionsRequirementsToml {    pub filesystem: Option<FilesystemRequirementsToml>,    // For legacy reasons, `filesystem` stays reserved for requirements-level    // filesystem constraints and cannot name a profile.    #[serde(default, flatten)]    pub profiles: BTreeMap<String, PermissionProfileToml>,}#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]pub struct FilesystemConstraints {    pub deny_read: Vec<FilesystemDenyReadPattern>,}impl From<PermissionsRequirementsToml> for FilesystemConstraints {    fn from(value: PermissionsRequirementsToml) -> Self {        let deny_read = value            .filesystem            .and_then(|filesystem| filesystem.deny_read)            .unwrap_or_default();        Self { deny_read }    }}#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]#[serde(transparent)]pub struct FilesystemDenyReadPattern(String);impl FilesystemDenyReadPattern {    pub fn as_str(&self) -> &str {        &self.0    }    pub fn contains_glob(&self) -> bool {        self.0.chars().any(is_glob_metacharacter)    }    pub fn from_input(input: &str) -> Result<Self, String> {        if !input.chars().any(is_glob_metacharacter) {            let path = deserialize_absolute_path(input)?;            return Ok(Self(path.to_string_lossy().into_owned()));        }        let (directory_prefix, suffix) = split_glob_pattern(input);        let normalized_prefix = if directory_prefix.is_empty() {            deserialize_absolute_path(".")?        } else {            deserialize_absolute_path(directory_prefix)?        };        let normalized_prefix = normalized_prefix.to_string_lossy();        let normalized = if suffix.is_empty() {            normalized_prefix.into_owned()        } else if normalized_prefix == "/" {            format!("/{suffix}")        } else {            format!("{normalized_prefix}/{suffix}")        };        Ok(Self(normalized))    }}impl From<AbsolutePathBuf> for FilesystemDenyReadPattern {    fn from(value: AbsolutePathBuf) -> Self {        Self(value.to_string_lossy().into_owned())    }}impl<'de> Deserialize<'de> for FilesystemDenyReadPattern {    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>    where        D: serde::Deserializer<'de>,    {        let input = String::deserialize(deserializer)?;        Self::from_input(&input).map_err(D::Error::custom)    }}fn deserialize_absolute_path(input: &str) -> Result<AbsolutePathBuf, String> {    AbsolutePathBuf::deserialize(StrDeserializer::<ValueDeserializerError>::new(input))        .map_err(|err| err.to_string())}fn split_glob_pattern(input: &str) -> (&str, &str) {    let Some(first_glob) = input.find(is_glob_metacharacter) else {        return ("", input);    };    let separator_index = input[..first_glob]        .char_indices()        .rev()        .find(|(_, ch)| is_path_separator(*ch))        .map(|(index, _)| index);    match separator_index {        Some(0) => ("/", &input[1..]),        Some(index)            if cfg!(windows)                && index == 2                && input.as_bytes().get(1) == Some(&b':')                && input.as_bytes().get(2).is_some() =>        {            (&input[..=index], &input[index + 1..])        }        Some(index) => (&input[..index], &input[index + 1..]),        None => ("", input),    }}fn is_path_separator(ch: char) -> bool {    if cfg!(windows) {        ch == '/' || ch == '\\'    } else {        ch == '/'    }}fn is_glob_metacharacter(ch: char) -> bool {    matches!(ch, '*' | '?' | '[')}#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]#[serde(rename_all = "lowercase")]pub enum WebSearchModeRequirement {    Disabled,    Cached,    Live,}impl From<WebSearchMode> for WebSearchModeRequirement {    fn from(mode: WebSearchMode) -> Self {        match mode {            WebSearchMode::Disabled => WebSearchModeRequirement::Disabled,            WebSearchMode::Cached => WebSearchModeRequirement::Cached,            WebSearchMode::Live => WebSearchModeRequirement::Live,        }    }}impl From<WebSearchModeRequirement> for WebSearchMode {    fn from(mode: WebSearchModeRequirement) -> Self {        match mode {            WebSearchModeRequirement::Disabled => WebSearchMode::Disabled,            WebSearchModeRequirement::Cached => WebSearchMode::Cached,            WebSearchModeRequirement::Live => WebSearchMode::Live,        }    }}impl fmt::Display for WebSearchModeRequirement {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        match self {            WebSearchModeRequirement::Disabled => write!(f, "disabled"),            WebSearchModeRequirement::Cached => write!(f, "cached"),            WebSearchModeRequirement::Live => write!(f, "live"),        }    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct ComputerUseRequirementsToml {    pub allow_locked_computer_use: Option<bool>,}impl ComputerUseRequirementsToml {    pub fn is_empty(&self) -> bool {        self.allow_locked_computer_use.is_none()    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct WindowsRequirementsToml {    pub allowed_sandbox_implementations: Option<Vec<WindowsSandboxModeToml>>,}impl WindowsRequirementsToml {    pub fn is_empty(&self) -> bool {        self.allowed_sandbox_implementations.is_none()    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct FeatureRequirementsToml {    #[serde(flatten)]    pub entries: BTreeMap<String, bool>,}impl FeatureRequirementsToml {    pub fn is_empty(&self) -> bool {        self.entries.is_empty()    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct AppToolRequirementToml {    pub approval_mode: Option<AppToolApproval>,}impl AppToolRequirementToml {    pub fn is_empty(&self) -> bool {        self.approval_mode.is_none()    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct AppToolsRequirementsToml {    #[serde(default, flatten)]    pub tools: BTreeMap<String, AppToolRequirementToml>,}impl AppToolsRequirementsToml {    pub fn is_empty(&self) -> bool {        self.tools.values().all(AppToolRequirementToml::is_empty)    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct AppRequirementToml {    pub enabled: Option<bool>,    pub tools: Option<AppToolsRequirementsToml>,}impl AppRequirementToml {    pub fn is_empty(&self) -> bool {        self.enabled.is_none()            && self                .tools                .as_ref()                .is_none_or(AppToolsRequirementsToml::is_empty)    }}#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]pub struct AppsRequirementsToml {    #[serde(default, flatten)]    pub apps: BTreeMap<String, AppRequirementToml>,}impl AppsRequirementsToml {    pub fn is_empty(&self) -> bool {        self.apps.values().all(AppRequirementToml::is_empty)    }}/// Merge app requirements from a lower-precedence source into an existing higher-precedence set./// This lets managed sources (for example Cloud/MDM) enforce setting disablement across layers,/// while exact tool approval settings keep the higher-precedence value when present.pub(crate) fn merge_app_requirements_descending(    base: &mut AppsRequirementsToml,    incoming: AppsRequirementsToml,) {    for (app_id, incoming_requirement) in incoming.apps {        let base_requirement = base.apps.entry(app_id).or_default();        let higher_precedence = base_requirement.enabled;        let lower_precedence = incoming_requirement.enabled;        base_requirement.enabled =            if higher_precedence == Some(false) || lower_precedence == Some(false) {                Some(false)            } else {                higher_precedence.or(lower_precedence)            };        let Some(incoming_tools) = incoming_requirement.tools else {            continue;        };        let base_tools = base_requirement.tools.get_or_insert_with(Default::default);        for (tool_name, incoming_tool) in incoming_tools.tools {            let base_tool = base_tools.tools.entry(tool_name).or_default();            if base_tool.approval_mode.is_none() {                base_tool.approval_mode = incoming_tool.approval_mode;            }        }    }}/// Base config deserialized from system `requirements.toml` or MDM.#[derive(Deserialize, Debug, Clone, Default, PartialEq)]pub struct ConfigRequirementsToml {    pub allowed_approval_policies: Option<Vec<AskForApproval>>,    pub allowed_approvals_reviewers: Option<Vec<ApprovalsReviewer>>,    pub allowed_sandbox_modes: Option<Vec<SandboxModeRequirement>>,    pub allowed_permission_profiles: Option<BTreeMap<String, bool>>,    pub default_permissions: Option<String>,    pub remote_sandbox_config: Option<Vec<RemoteSandboxConfigToml>>,    pub allowed_web_search_modes: Option<Vec<WebSearchModeRequirement>>,    pub allow_managed_hooks_only: Option<bool>,    pub allow_appshots: Option<bool>,    pub allow_remote_control: Option<bool>,    pub computer_use: Option<ComputerUseRequirementsToml>,    pub windows: Option<WindowsRequirementsToml>,    #[serde(rename = "features", alias = "feature_requirements")]    pub feature_requirements: Option<FeatureRequirementsToml>,    pub hooks: Option<ManagedHooksRequirementsToml>,    pub mcp_servers: Option<BTreeMap<String, McpServerRequirement>>,    pub plugins: Option<BTreeMap<String, PluginRequirementsToml>>,    pub apps: Option<AppsRequirementsToml>,    pub rules: Option<RequirementsExecPolicyToml>,    pub enforce_residency: Option<ResidencyRequirement>,    #[serde(rename = "experimental_network")]    pub network: Option<NetworkRequirementsToml>,    pub permissions: Option<PermissionsRequirementsToml>,    pub guardian_policy_config: Option<String>,}#[derive(Deserialize, Debug, Clone, PartialEq)]pub struct RemoteSandboxConfigToml {    pub hostname_patterns: Vec<String>,    pub allowed_sandbox_modes: Vec<SandboxModeRequirement>,}/// Value paired with the requirement source it came from, for better error/// messages.#[derive(Debug, Clone, PartialEq)]pub struct Sourced<T> {    pub value: T,    pub source: RequirementSource,}impl<T> Sourced<T> {    pub fn new(value: T, source: RequirementSource) -> Self {        Self { value, source }    }}impl<T> std::ops::Deref for Sourced<T> {    type Target = T;    fn deref(&self) -> &Self::Target {        &self.value    }}#[derive(Debug, Clone, Default, PartialEq)]pub struct ConfigRequirementsWithSources {    pub allowed_approval_policies: Option<Sourced<Vec<AskForApproval>>>,    pub allowed_approvals_reviewers: Option<Sourced<Vec<ApprovalsReviewer>>>,    pub allowed_sandbox_modes: Option<Sourced<Vec<SandboxModeRequirement>>>,    pub allowed_permission_profiles: Option<Sourced<BTreeMap<String, bool>>>,    pub default_permissions: Option<Sourced<String>>,    pub allowed_web_search_modes: Option<Sourced<Vec<WebSearchModeRequirement>>>,    pub allow_managed_hooks_only: Option<Sourced<bool>>,    pub allow_appshots: Option<Sourced<bool>>,    pub allow_remote_control: Option<Sourced<bool>>,    pub computer_use: Option<Sourced<ComputerUseRequirementsToml>>,    pub windows: Option<Sourced<WindowsRequirementsToml>>,    pub feature_requirements: Option<Sourced<FeatureRequirementsToml>>,    pub hooks: Option<Sourced<ManagedHooksRequirementsToml>>,    pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,    pub plugins: Option<Sourced<BTreeMap<String, PluginRequirementsToml>>>,    pub apps: Option<Sourced<AppsRequirementsToml>>,    pub rules: Option<Sourced<RequirementsExecPolicyToml>>,    pub enforce_residency: Option<Sourced<ResidencyRequirement>>,    pub network: Option<Sourced<NetworkRequirementsToml>>,    pub permissions: Option<Sourced<PermissionsRequirementsToml>>,    pub guardian_policy_config: Option<Sourced<String>>,}impl ConfigRequirementsWithSources {    pub fn merge_unset_fields(&mut self, source: RequirementSource, other: ConfigRequirementsToml) {        // For every field in `other` that is `Some`, if the corresponding field        // in `self` is `None`, copy the value from `other` into `self`.        macro_rules! fill_missing_take {            ($base:expr, $other:expr, $source:expr, { $($field:ident),+ $(,)? }) => {                $(                    if $base.$field.is_none()                        && let Some(value) = $other.$field.take()                    {                        $base.$field = Some(Sourced::new(value, $source.clone()));                    }                )+            };        }        // Destructure without `..` so adding fields to `ConfigRequirementsToml`        // forces this merge logic to be updated.        let ConfigRequirementsToml {            allowed_approval_policies: _,            allowed_approvals_reviewers: _,            allowed_sandbox_modes: _,            allowed_permission_profiles: _,            default_permissions: _,            remote_sandbox_config: _,            allowed_web_search_modes: _,            allow_managed_hooks_only: _,            allow_appshots: _,            allow_remote_control: _,            computer_use: _,            windows: _,            feature_requirements: _,            hooks: _,            mcp_servers: _,            plugins: _,            apps: _,            rules: _,            enforce_residency: _,            network: _,            permissions: _,            guardian_policy_config: _,        } = &other;        let mut other = other;        if other            .guardian_policy_config            .as_deref()            .is_some_and(|value| value.trim().is_empty())        {            other.guardian_policy_config = None;        }        fill_missing_take!(            self,            other,            source,            {                allowed_approval_policies,                allowed_approvals_reviewers,                allowed_sandbox_modes,                allowed_permission_profiles,                default_permissions,                allowed_web_search_modes,                allow_managed_hooks_only,                allow_appshots,                allow_remote_control,                computer_use,                windows,                feature_requirements,                hooks,                mcp_servers,                plugins,                rules,                enforce_residency,                network,                permissions,                guardian_policy_config,            }        );        if let Some(incoming_apps) = other.apps.take() {            if let Some(existing_apps) = self.apps.as_mut() {                merge_app_requirements_descending(&mut existing_apps.value, incoming_apps);            } else {                self.apps = Some(Sourced::new(incoming_apps, source));            }        }    }    pub fn into_toml(self) -> ConfigRequirementsToml {        let ConfigRequirementsWithSources {            allowed_approval_policies,            allowed_approvals_reviewers,            allowed_sandbox_modes,            allowed_permission_profiles,            default_permissions,            allowed_web_search_modes,            allow_managed_hooks_only,            allow_appshots,            allow_remote_control,            computer_use,            windows,            feature_requirements,            hooks,            mcp_servers,            plugins,            apps,            rules,            enforce_residency,            network,            permissions,            guardian_policy_config,        } = self;        ConfigRequirementsToml {            allowed_approval_policies: allowed_approval_policies.map(|sourced| sourced.value),            allowed_approvals_reviewers: allowed_approvals_reviewers.map(|sourced| sourced.value),            allowed_sandbox_modes: allowed_sandbox_modes.map(|sourced| sourced.value),            allowed_permission_profiles: allowed_permission_profiles.map(|sourced| sourced.value),            default_permissions: default_permissions.map(|sourced| sourced.value),            remote_sandbox_config: None,            allowed_web_search_modes: allowed_web_search_modes.map(|sourced| sourced.value),            allow_managed_hooks_only: allow_managed_hooks_only.map(|sourced| sourced.value),            allow_appshots: allow_appshots.map(|sourced| sourced.value),            allow_remote_control: allow_remote_control.map(|sourced| sourced.value),            computer_use: computer_use.map(|sourced| sourced.value),            windows: windows.map(|sourced| sourced.value),            feature_requirements: feature_requirements.map(|sourced| sourced.value),            hooks: hooks.map(|sourced| sourced.value),            mcp_servers: mcp_servers.map(|sourced| sourced.value),            plugins: plugins.map(|sourced| sourced.value),            apps: apps.map(|sourced| sourced.value),            rules: rules.map(|sourced| sourced.value),            enforce_residency: enforce_residency.map(|sourced| sourced.value),            network: network.map(|sourced| sourced.value),            permissions: permissions.map(|sourced| sourced.value),            guardian_policy_config: guardian_policy_config.map(|sourced| sourced.value),        }    }}fn normalize_hostname(hostname: &str) -> Option<String> {    let hostname = hostname.trim().trim_end_matches('.');    (!hostname.is_empty()).then(|| hostname.to_ascii_lowercase())}fn hostname_matches_any_pattern(hostname: &str, patterns: &[String]) -> bool {    patterns.iter().any(|pattern| {        normalize_hostname(pattern)            .map(|pattern| WildMatchPattern::<'*', '?'>::new_case_insensitive(&pattern))            .is_some_and(|pattern| pattern.matches(hostname))    })}/// Currently, `external-sandbox` is not supported in config.toml, but it is/// supported through programmatic use.#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]pub enum SandboxModeRequirement {    #[serde(rename = "read-only")]    ReadOnly,    #[serde(rename = "workspace-write")]    WorkspaceWrite,    #[serde(rename = "danger-full-access")]    DangerFullAccess,    #[serde(rename = "external-sandbox")]    ExternalSandbox,}impl From<SandboxMode> for SandboxModeRequirement {    fn from(mode: SandboxMode) -> Self {        match mode {            SandboxMode::ReadOnly => SandboxModeRequirement::ReadOnly,            SandboxMode::WorkspaceWrite => SandboxModeRequirement::WorkspaceWrite,            SandboxMode::DangerFullAccess => SandboxModeRequirement::DangerFullAccess,        }    }}#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]#[serde(rename_all = "lowercase")]pub enum ResidencyRequirement {    Us,}impl ConfigRequirementsToml {    pub fn apply_remote_sandbox_config(&mut self, hostname: Option<&str>) {        let Some(remote_sandbox_config) = self.remote_sandbox_config.as_ref() else {            return;        };        let Some(hostname) = hostname.and_then(normalize_hostname) else {            return;        };        let Some(matched_config) = remote_sandbox_config            .iter()            .find(|config| hostname_matches_any_pattern(&hostname, &config.hostname_patterns))        else {            return;        };        self.allowed_sandbox_modes = Some(matched_config.allowed_sandbox_modes.clone());    }    pub fn is_empty(&self) -> bool {        self.allowed_approval_policies.is_none()            && self.allowed_approvals_reviewers.is_none()            && self.allowed_sandbox_modes.is_none()            && self.allowed_permission_profiles.is_none()            && self.default_permissions.is_none()            && self.remote_sandbox_config.is_none()            && self.allowed_web_search_modes.is_none()            && self.allow_managed_hooks_only.is_none()            && self.allow_appshots.is_none()            && self.allow_remote_control.is_none()            && self                .computer_use                .as_ref()                .is_none_or(ComputerUseRequirementsToml::is_empty)            && self                .windows                .as_ref()                .is_none_or(WindowsRequirementsToml::is_empty)            && self                .feature_requirements                .as_ref()                .is_none_or(FeatureRequirementsToml::is_empty)            && self                .hooks                .as_ref()                .is_none_or(ManagedHooksRequirementsToml::is_empty)            && self.mcp_servers.is_none()            && self                .plugins                .as_ref()                .is_none_or(|plugins| plugins.values().all(PluginRequirementsToml::is_empty))            && self                .apps                .as_ref()                .is_none_or(AppsRequirementsToml::is_empty)            && self.rules.is_none()            && self.enforce_residency.is_none()            && self.network.is_none()            && self.permissions.is_none()            && self                .guardian_policy_config                .as_deref()                .is_none_or(|value| value.trim().is_empty())    }}impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {    type Error = ConstraintError;    fn try_from(toml: ConfigRequirementsWithSources) -> Result<Self, Self::Error> {        // Profile catalog selection remains on ConfigRequirementsToml for        // config loading and requirements API projection. The normalized        // constraints below only need the compiled PermissionProfile envelope.        let ConfigRequirementsWithSources {            allowed_approval_policies,            allowed_approvals_reviewers,            allowed_sandbox_modes,            allowed_permission_profiles: _,            default_permissions: _,            allowed_web_search_modes,            allow_managed_hooks_only,            allow_appshots,            allow_remote_control,            computer_use,            windows,            feature_requirements,            hooks,            mcp_servers,            plugins,            apps: _apps,            rules,            enforce_residency,            network,            permissions,            guardian_policy_config,        } = toml;        let approval_policy = match allowed_approval_policies {            Some(Sourced {                value: policies,                source: requirement_source,            }) => {                let Some(initial_value) = policies.first().copied() else {                    return Err(ConstraintError::empty_field("allowed_approval_policies"));                };                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(initial_value, move |candidate| {                    if policies.contains(candidate) {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "approval_policy",                            candidate: format!("{candidate:?}"),                            allowed: format!("{policies:?}"),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            None => ConstrainedWithSource::new(                Constrained::allow_any_from_default(),                /*source*/ None,            ),        };        let approvals_reviewer = match allowed_approvals_reviewers {            Some(Sourced {                value: reviewers,                source: requirement_source,            }) => {                let Some(initial_value) = reviewers.first().copied() else {                    return Err(ConstraintError::empty_field("allowed_approvals_reviewers"));                };                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(initial_value, move |candidate| {                    if reviewers.contains(candidate) {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "approvals_reviewer",                            candidate: format!("{candidate:?}"),                            allowed: format!("{reviewers:?}"),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            None => ConstrainedWithSource::new(                Constrained::allow_any_from_default(),                /*source*/ None,            ),        };        let default_permission_profile = PermissionProfile::read_only();        let permission_profile = match allowed_sandbox_modes {            Some(Sourced {                value: modes,                source: requirement_source,            }) => {                if !modes.contains(&SandboxModeRequirement::ReadOnly) {                    return Err(ConstraintError::InvalidValue {                        field_name: "allowed_sandbox_modes",                        candidate: format!("{modes:?}"),                        allowed: "must include 'read-only' to allow any PermissionProfile"                            .to_string(),                        requirement_source,                    });                };                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(default_permission_profile, move |candidate| {                    let mode = sandbox_mode_requirement_for_permission_profile(candidate);                    if modes.contains(&mode) {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "sandbox_mode",                            candidate: format!("{mode:?}"),                            allowed: format!("{modes:?}"),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            None => ConstrainedWithSource::new(                Constrained::allow_any(default_permission_profile),                /*source*/ None,            ),        };        let windows_sandbox_mode = match windows {            Some(Sourced {                value:                    WindowsRequirementsToml {                        allowed_sandbox_implementations: Some(implementations),                    },                source: requirement_source,            }) => {                if implementations.is_empty() {                    return Err(ConstraintError::empty_field(                        "windows.allowed_sandbox_implementations",                    ));                }                // Prefer elevated when both Windows sandbox implementations are allowed.                let initial_value = if implementations.contains(&WindowsSandboxModeToml::Elevated) {                    WindowsSandboxModeToml::Elevated                } else {                    WindowsSandboxModeToml::Unelevated                };                let requirement_source_for_error = requirement_source.clone();                let constrained =                    Constrained::new(Some(initial_value), move |candidate| match candidate {                        Some(candidate) if implementations.contains(candidate) => Ok(()),                        _ => Err(ConstraintError::InvalidValue {                            field_name: "windows.sandbox",                            candidate: format!("{candidate:?}"),                            allowed: format!("{implementations:?}"),                            requirement_source: requirement_source_for_error.clone(),                        }),                    })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            Some(_) | None => ConstrainedWithSource::new(                Constrained::allow_any(/*initial_value*/ None),                /*source*/ None,            ),        };        let exec_policy = match rules {            Some(Sourced { value, source }) => {                let policy = value.to_requirements_policy().map_err(|err| {                    ConstraintError::ExecPolicyParse {                        requirement_source: source.clone(),                        reason: err.to_string(),                    }                })?;                Some(Sourced::new(policy, source))            }            None => None,        };        let web_search_mode = match allowed_web_search_modes {            Some(Sourced {                value: modes,                source: requirement_source,            }) => {                let mut accepted = modes.into_iter().collect::<std::collections::BTreeSet<_>>();                accepted.insert(WebSearchModeRequirement::Disabled);                let allowed_for_error = format!(                    "{:?}",                    accepted                        .iter()                        .copied()                        .map(WebSearchMode::from)                        .collect::<Vec<_>>()                );                let initial_value = if accepted.contains(&WebSearchModeRequirement::Cached) {                    WebSearchMode::Cached                } else if accepted.contains(&WebSearchModeRequirement::Live) {                    WebSearchMode::Live                } else {                    WebSearchMode::Disabled                };                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(initial_value, move |candidate| {                    if accepted.contains(&(*candidate).into()) {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "web_search_mode",                            candidate: format!("{candidate:?}"),                            allowed: allowed_for_error.clone(),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            None => ConstrainedWithSource::new(                Constrained::allow_any(WebSearchMode::Cached),                /*source*/ None,            ),        };        let feature_requirements =            feature_requirements.filter(|requirements| !requirements.value.is_empty());        let managed_hooks = hooks            .filter(|managed_hooks| managed_hooks.value.handler_count() > 0)            .map(|sourced_hooks| {                let Sourced {                    value,                    source: requirement_source,                } = sourced_hooks;                let allowed = value;                let allowed_for_error = format!("{allowed:?}");                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(allowed.clone(), move |candidate| {                    if candidate == &allowed {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "hooks",                            candidate: format!("{candidate:?}"),                            allowed: allowed_for_error.clone(),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                Ok(ConstrainedWithSource::new(                    constrained,                    Some(requirement_source),                ))            })            .transpose()?;        let enforce_residency = match enforce_residency {            Some(Sourced {                value: residency,                source: requirement_source,            }) => {                let required = Some(residency);                let requirement_source_for_error = requirement_source.clone();                let constrained = Constrained::new(required, move |candidate| {                    if candidate == &required {                        Ok(())                    } else {                        Err(ConstraintError::InvalidValue {                            field_name: "enforce_residency",                            candidate: format!("{candidate:?}"),                            allowed: format!("{required:?}"),                            requirement_source: requirement_source_for_error.clone(),                        })                    }                })?;                ConstrainedWithSource::new(constrained, Some(requirement_source))            }            None => ConstrainedWithSource::new(                Constrained::allow_any(/*initial_value*/ None),                /*source*/ None,            ),        };        let network = network.map(|sourced_network| {            let Sourced { value, source } = sourced_network;            Sourced::new(NetworkConstraints::from(value), source)        });        let filesystem = permissions.map(|sourced_permissions| {            let Sourced { value, source } = sourced_permissions;            Sourced::new(FilesystemConstraints::from(value), source)        });        let guardian_policy_config_source = guardian_policy_config.map(|sourced| sourced.source);        Ok(ConfigRequirements {            approval_policy,            approvals_reviewer,            permission_profile,            windows_sandbox_mode,            web_search_mode,            allow_managed_hooks_only,            allow_appshots,            allow_remote_control,            computer_use,            feature_requirements,            managed_hooks,            mcp_servers,            plugins,            exec_policy,            enforce_residency,            network,            filesystem,            guardian_policy_config_source,        })    }}pub fn sandbox_mode_requirement_for_permission_profile(    permission_profile: &PermissionProfile,) -> SandboxModeRequirement {    match permission_profile {        PermissionProfile::Disabled => SandboxModeRequirement::DangerFullAccess,        PermissionProfile::External { .. } => SandboxModeRequirement::ExternalSandbox,        PermissionProfile::Managed { .. } => {            let file_system_policy = permission_profile.file_system_sandbox_policy();            if file_system_policy.has_full_disk_write_access() {                SandboxModeRequirement::DangerFullAccess            } else if file_system_policy                .entries                .iter()                .any(|entry| entry.access.can_write())            {                SandboxModeRequirement::WorkspaceWrite            } else {                SandboxModeRequirement::ReadOnly            }        }    }}#[cfg(test)]mod tests {    use super::*;    use crate::HookEventsToml;    use anyhow::Result;    use codex_execpolicy::Decision;    use codex_execpolicy::Evaluation;    use codex_execpolicy::RuleMatch;    use codex_protocol::permissions::NetworkSandboxPolicy;    use codex_utils_absolute_path::AbsolutePathBuf;    use codex_utils_absolute_path::AbsolutePathBufGuard;    use pretty_assertions::assert_eq;    use toml::from_str;    fn tokens(cmd: &[&str]) -> Vec<String> {        cmd.iter().map(std::string::ToString::to_string).collect()    }    fn system_requirements_toml_file_for_test() -> Result<AbsolutePathBuf> {        Ok(AbsolutePathBuf::try_from(            std::env::temp_dir().join("requirements.toml"),        )?)    }    #[test]    fn composite_requirement_source_flattens_and_deduplicates_sources() {        let mdm_source = RequirementSource::MdmManagedPreferences {            domain: "com.openai.codex".to_string(),            key: "requirements_toml_base64".to_string(),        };        let legacy_source = RequirementSource::LegacyManagedConfigTomlFromMdm;        assert_eq!(            RequirementSource::composite([                mdm_source.clone(),                RequirementSource::composite([legacy_source.clone(), mdm_source.clone()]),            ]),            RequirementSource::Composite {                sources: vec![mdm_source, legacy_source],            }        );    }    fn with_unknown_source(toml: ConfigRequirementsToml) -> ConfigRequirementsWithSources {        let ConfigRequirementsToml {            allowed_approval_policies,            allowed_approvals_reviewers,            allowed_sandbox_modes,            allowed_permission_profiles,            default_permissions,            remote_sandbox_config: _,            allowed_web_search_modes,            allow_managed_hooks_only,            allow_appshots,            allow_remote_control,            computer_use,            windows,            feature_requirements,            hooks,            mcp_servers,            plugins,            apps,            rules,            enforce_residency,            network,            permissions,            guardian_policy_config,        } = toml;        ConfigRequirementsWithSources {            allowed_approval_policies: allowed_approval_policies                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allowed_approvals_reviewers: allowed_approvals_reviewers                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allowed_sandbox_modes: allowed_sandbox_modes                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allowed_permission_profiles: allowed_permission_profiles                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            default_permissions: default_permissions                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allowed_web_search_modes: allowed_web_search_modes                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allow_managed_hooks_only: allow_managed_hooks_only                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allow_appshots: allow_appshots                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            allow_remote_control: allow_remote_control                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            computer_use: computer_use.map(|value| Sourced::new(value, RequirementSource::Unknown)),            windows: windows.map(|value| Sourced::new(value, RequirementSource::Unknown)),            feature_requirements: feature_requirements                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            hooks: hooks.map(|value| Sourced::new(value, RequirementSource::Unknown)),            mcp_servers: mcp_servers.map(|value| Sourced::new(value, RequirementSource::Unknown)),            plugins: plugins.map(|value| Sourced::new(value, RequirementSource::Unknown)),            apps: apps.map(|value| Sourced::new(value, RequirementSource::Unknown)),            rules: rules.map(|value| Sourced::new(value, RequirementSource::Unknown)),            enforce_residency: enforce_residency                .map(|value| Sourced::new(value, RequirementSource::Unknown)),            network: network.map(|value| Sourced::new(value, RequirementSource::Unknown)),            permissions: permissions.map(|value| Sourced::new(value, RequirementSource::Unknown)),            guardian_policy_config: guardian_policy_config                .map(|value| Sourced::new(value, RequirementSource::Unknown)),        }    }    #[test]    fn deserialize_allow_managed_hooks_only() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                allow_managed_hooks_only = true            "#,        )?;        assert_eq!(requirements.allow_managed_hooks_only, Some(true));        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn allow_managed_hooks_only_false_is_still_configured() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                allow_managed_hooks_only = false            "#,        )?;        assert_eq!(requirements.allow_managed_hooks_only, Some(false));        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn deserialize_managed_permission_profiles() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                default_permissions = "managed-standard"                [allowed_permission_profiles]                managed-standard = true                managed-build = true                [permissions.managed-standard]                extends = ":workspace"                [permissions.managed-build]                extends = "managed-standard"            "#,        )?;        assert_eq!(            requirements.allowed_permission_profiles,            Some(BTreeMap::from([                ("managed-build".to_string(), true),                ("managed-standard".to_string(), true),            ]))        );        assert_eq!(            requirements.default_permissions,            Some("managed-standard".to_string())        );        let permissions = requirements            .permissions            .as_ref()            .expect("managed permission profiles");        assert!(permissions.profiles.contains_key("managed-standard"));        assert!(            permissions                .profiles                .get("managed-build")                .and_then(|profile| profile.extends.as_deref())                .is_some()        );        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn deserialize_allow_appshots() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                allow_appshots = true            "#,        )?;        assert_eq!(requirements.allow_appshots, Some(true));        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn filesystem_requirements_table_cannot_define_a_permission_profile() {        let err = from_str::<ConfigRequirementsToml>(            r#"                [permissions.filesystem]                extends = ":workspace"            "#,        )        .expect_err("filesystem requirements cannot define a permission profile");        assert!(            err.to_string().contains(                "`permissions.filesystem` is reserved for requirements-level filesystem constraints and cannot define a profile"            ),            "unexpected error: {err:#}"        );    }    #[test]    fn allow_appshots_false_is_still_configured() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                allow_appshots = false            "#,        )?;        assert_eq!(requirements.allow_appshots, Some(false));        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn allow_remote_control_false_is_still_configured() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                allow_remote_control = false            "#,        )?;        assert_eq!(requirements.allow_remote_control, Some(false));        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn deserialize_computer_use_requirements() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"                [computer_use]                allow_locked_computer_use = false            "#,        )?;        assert_eq!(            requirements.computer_use,            Some(ComputerUseRequirementsToml {                allow_locked_computer_use: Some(false),            })        );        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn merge_unset_fields_copies_every_field_and_sets_sources() {        let mut target = ConfigRequirementsWithSources::default();        let source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let allowed_approval_policies = vec![AskForApproval::UnlessTrusted, AskForApproval::Never];        let allowed_approvals_reviewers =            vec![ApprovalsReviewer::AutoReview, ApprovalsReviewer::User];        let allowed_sandbox_modes = vec![            SandboxModeRequirement::WorkspaceWrite,            SandboxModeRequirement::DangerFullAccess,        ];        let allowed_web_search_modes = vec![            WebSearchModeRequirement::Cached,            WebSearchModeRequirement::Live,        ];        let feature_requirements = FeatureRequirementsToml {            entries: BTreeMap::from([("personality".to_string(), true)]),        };        let computer_use = ComputerUseRequirementsToml {            allow_locked_computer_use: Some(false),        };        let enforce_residency = ResidencyRequirement::Us;        let enforce_source = source.clone();        let guardian_policy_config = "Use the company-managed guardian policy.".to_string();        // Intentionally constructed without `..Default::default()` so adding a new field to        // `ConfigRequirementsToml` forces this test to be updated.        let other = ConfigRequirementsToml {            allowed_approval_policies: Some(allowed_approval_policies.clone()),            allowed_approvals_reviewers: Some(allowed_approvals_reviewers.clone()),            allowed_sandbox_modes: Some(allowed_sandbox_modes.clone()),            allowed_permission_profiles: Some(BTreeMap::from([("managed".to_string(), true)])),            default_permissions: Some("managed".to_string()),            remote_sandbox_config: None,            allowed_web_search_modes: Some(allowed_web_search_modes.clone()),            allow_managed_hooks_only: Some(true),            allow_appshots: Some(false),            allow_remote_control: Some(false),            computer_use: Some(computer_use.clone()),            windows: None,            feature_requirements: Some(feature_requirements.clone()),            hooks: None,            mcp_servers: None,            plugins: None,            apps: None,            rules: None,            enforce_residency: Some(enforce_residency),            network: None,            permissions: None,            guardian_policy_config: Some(guardian_policy_config.clone()),        };        target.merge_unset_fields(source.clone(), other);        assert_eq!(            target,            ConfigRequirementsWithSources {                allowed_approval_policies: Some(Sourced::new(                    allowed_approval_policies,                    source.clone()                )),                allowed_approvals_reviewers: Some(Sourced::new(                    allowed_approvals_reviewers,                    source.clone(),                )),                allowed_sandbox_modes: Some(Sourced::new(allowed_sandbox_modes, source.clone(),)),                allowed_permission_profiles: Some(Sourced::new(                    BTreeMap::from([("managed".to_string(), true)]),                    source.clone(),                )),                default_permissions: Some(Sourced::new("managed".to_string(), source.clone(),)),                allowed_web_search_modes: Some(Sourced::new(                    allowed_web_search_modes,                    enforce_source.clone(),                )),                allow_managed_hooks_only: Some(Sourced::new(                    /*value*/ true,                    enforce_source.clone(),                )),                allow_appshots: Some(Sourced::new(/*value*/ false, enforce_source.clone(),)),                allow_remote_control: Some(Sourced::new(                    /*value*/ false,                    enforce_source.clone(),                )),                computer_use: Some(Sourced::new(computer_use, enforce_source.clone())),                windows: None,                feature_requirements: Some(Sourced::new(                    feature_requirements,                    enforce_source.clone(),                )),                hooks: None,                mcp_servers: None,                plugins: None,                apps: None,                rules: None,                enforce_residency: Some(Sourced::new(enforce_residency, enforce_source)),                network: None,                permissions: None,                guardian_policy_config: Some(Sourced::new(guardian_policy_config, source)),            }        );    }    #[test]    fn merge_unset_fields_fills_missing_values() -> Result<()> {        let source: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["on-request"]            "#,        )?;        let source_location = RequirementSource::MdmManagedPreferences {            domain: "com.codex".to_string(),            key: "allowed_approval_policies".to_string(),        };        let mut empty_target = ConfigRequirementsWithSources::default();        empty_target.merge_unset_fields(source_location.clone(), source);        assert_eq!(            empty_target,            ConfigRequirementsWithSources {                allowed_approval_policies: Some(Sourced::new(                    vec![AskForApproval::OnRequest],                    source_location,                )),                allowed_approvals_reviewers: None,                allowed_sandbox_modes: None,                allowed_permission_profiles: None,                default_permissions: None,                allowed_web_search_modes: None,                allow_managed_hooks_only: None,                allow_appshots: None,                allow_remote_control: None,                computer_use: None,                windows: None,                feature_requirements: None,                hooks: None,                mcp_servers: None,                plugins: None,                apps: None,                rules: None,                enforce_residency: None,                network: None,                permissions: None,                guardian_policy_config: None,            }        );        Ok(())    }    #[test]    fn merge_unset_fields_does_not_overwrite_existing_values() -> Result<()> {        let existing_source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut populated_target = ConfigRequirementsWithSources::default();        let populated_requirements: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["never"]            "#,        )?;        populated_target.merge_unset_fields(existing_source.clone(), populated_requirements);        let source: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["on-request"]            "#,        )?;        let source_location = RequirementSource::MdmManagedPreferences {            domain: "com.codex".to_string(),            key: "allowed_approval_policies".to_string(),        };        populated_target.merge_unset_fields(source_location, source);        assert_eq!(            populated_target,            ConfigRequirementsWithSources {                allowed_approval_policies: Some(Sourced::new(                    vec![AskForApproval::Never],                    existing_source,                )),                allowed_approvals_reviewers: None,                allowed_sandbox_modes: None,                allowed_permission_profiles: None,                default_permissions: None,                allowed_web_search_modes: None,                allow_managed_hooks_only: None,                allow_appshots: None,                allow_remote_control: None,                computer_use: None,                windows: None,                feature_requirements: None,                hooks: None,                mcp_servers: None,                plugins: None,                apps: None,                rules: None,                enforce_residency: None,                network: None,                permissions: None,                guardian_policy_config: None,            }        );        Ok(())    }    #[test]    fn merge_unset_fields_ignores_blank_guardian_override() {        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(            RequirementSource::LegacyManagedConfigTomlFromMdm,            ConfigRequirementsToml {                guardian_policy_config: Some("   \n\t".to_string()),                ..Default::default()            },        );        target.merge_unset_fields(            RequirementSource::SystemRequirementsToml {                file: system_requirements_toml_file_for_test()                    .expect("system requirements.toml path"),            },            ConfigRequirementsToml {                guardian_policy_config: Some("Use the system guardian policy.".to_string()),                ..Default::default()            },        );        assert_eq!(            target.guardian_policy_config,            Some(Sourced::new(                "Use the system guardian policy.".to_string(),                RequirementSource::SystemRequirementsToml {                    file: system_requirements_toml_file_for_test()                        .expect("system requirements.toml path"),                },            )),        );    }    #[test]    fn deserialize_guardian_policy_config() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"guardian_policy_config = """Use the cloud-managed guardian policy.""""#,        )?;        assert_eq!(            requirements.guardian_policy_config.as_deref(),            Some("Use the cloud-managed guardian policy.\n")        );        Ok(())    }    #[test]    fn blank_guardian_policy_config_is_empty() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"guardian_policy_config = """""""#,        )?;        assert!(requirements.is_empty());        Ok(())    }    #[test]    fn allowed_approvals_reviewers_is_not_empty() -> Result<()> {        let requirements: ConfigRequirementsToml = from_str(            r#"allowed_approvals_reviewers = ["user"]"#,        )?;        assert!(!requirements.is_empty());        Ok(())    }    #[test]    fn deserialize_filesystem_deny_read_requirements() -> Result<()> {        let deny_read_0 = if cfg!(windows) {            r"C:\Users\alice\.gitconfig"        } else {            "/home/alice/.gitconfig"        };        let deny_read_1 = if cfg!(windows) {            r"C:\Users\alice\.ssh"        } else {            "/home/alice/.ssh"        };        let toml_str = format!(            r#"            [permissions.filesystem]            deny_read = [{deny_read_0:?}, {deny_read_1:?}]        "#        );        let config: ConfigRequirementsToml = from_str(&toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.filesystem,            Some(Sourced::new(                FilesystemConstraints {                    deny_read: vec![                        AbsolutePathBuf::from_absolute_path(deny_read_0)?.into(),                        AbsolutePathBuf::from_absolute_path(deny_read_1)?.into(),                    ],                },                RequirementSource::Unknown,            ))        );        Ok(())    }    #[test]    fn deserialize_filesystem_deny_read_glob_requirements() -> Result<()> {        let temp_dir = std::env::temp_dir();        let _guard = AbsolutePathBufGuard::new(&temp_dir);        let config: ConfigRequirementsToml = from_str(            r#"            [permissions.filesystem]            deny_read = ["./private/**/*.txt"]        "#,        )?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.filesystem,            Some(Sourced::new(                FilesystemConstraints {                    deny_read: vec![                        FilesystemDenyReadPattern::from_input("./private/**/*.txt")                            .expect("normalize glob pattern"),                    ],                },                RequirementSource::Unknown,            ))        );        Ok(())    }    #[test]    fn deserialize_apps_requirements() -> Result<()> {        let toml_str = r#"            [apps.connector_123123]            enabled = false        "#;        let requirements: ConfigRequirementsToml = from_str(toml_str)?;        assert_eq!(            requirements.apps,            Some(AppsRequirementsToml {                apps: BTreeMap::from([(                    "connector_123123".to_string(),                    AppRequirementToml {                        enabled: Some(false),                        tools: None,                    },                )]),            })        );        Ok(())    }    #[test]    fn deserialize_apps_tool_requirements() -> Result<()> {        let toml_str = r#"            [apps.connector_123123.tools."calendar/list_events"]            approval_mode = "approve"        "#;        let requirements: ConfigRequirementsToml = from_str(toml_str)?;        assert_eq!(            requirements.apps,            Some(AppsRequirementsToml {                apps: BTreeMap::from([(                    "connector_123123".to_string(),                    AppRequirementToml {                        enabled: None,                        tools: Some(AppToolsRequirementsToml {                            tools: BTreeMap::from([(                                "calendar/list_events".to_string(),                                AppToolRequirementToml {                                    approval_mode: Some(AppToolApproval::Approve),                                },                            )]),                        }),                    },                )]),            })        );        Ok(())    }    fn apps_requirements(entries: &[(&str, Option<bool>)]) -> AppsRequirementsToml {        AppsRequirementsToml {            apps: entries                .iter()                .map(|(app_id, enabled)| {                    (                        (*app_id).to_string(),                        AppRequirementToml {                            enabled: *enabled,                            tools: None,                        },                    )                })                .collect(),        }    }    fn app_tool_requirements(        app_id: &str,        tool_name: &str,        approval_mode: AppToolApproval,    ) -> AppsRequirementsToml {        AppsRequirementsToml {            apps: BTreeMap::from([(                app_id.to_string(),                AppRequirementToml {                    enabled: None,                    tools: Some(AppToolsRequirementsToml {                        tools: BTreeMap::from([(                            tool_name.to_string(),                            AppToolRequirementToml {                                approval_mode: Some(approval_mode),                            },                        )]),                    }),                },            )]),        }    }    #[test]    fn merge_app_requirements_descending_unions_distinct_apps() {        let mut merged = apps_requirements(&[("connector_high", Some(false))]);        let lower = apps_requirements(&[("connector_low", Some(true))]);        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            apps_requirements(&[                ("connector_high", Some(false)),                ("connector_low", Some(true))            ]),        );    }    #[test]    fn merge_app_requirements_descending_prefers_false_from_lower_precedence() {        let mut merged = apps_requirements(&[("connector_123123", Some(true))]);        let lower = apps_requirements(&[("connector_123123", Some(false))]);        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            apps_requirements(&[("connector_123123", Some(false))]),        );    }    #[test]    fn merge_app_requirements_descending_keeps_higher_true_when_lower_is_unset() {        let mut merged = apps_requirements(&[("connector_123123", Some(true))]);        let lower = apps_requirements(&[("connector_123123", None)]);        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            apps_requirements(&[("connector_123123", Some(true))]),        );    }    #[test]    fn merge_app_requirements_descending_uses_lower_value_when_higher_missing() {        let mut merged = apps_requirements(&[]);        let lower = apps_requirements(&[("connector_123123", Some(true))]);        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            apps_requirements(&[("connector_123123", Some(true))]),        );    }    #[test]    fn merge_app_requirements_descending_preserves_higher_false_when_lower_missing_app() {        let mut merged = apps_requirements(&[("connector_123123", Some(false))]);        let lower = apps_requirements(&[]);        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            apps_requirements(&[("connector_123123", Some(false))]),        );    }    #[test]    fn merge_app_requirements_descending_preserves_higher_tool_approval_mode() {        let mut merged = app_tool_requirements(            "connector_123123",            "calendar/list_events",            AppToolApproval::Approve,        );        let lower = app_tool_requirements(            "connector_123123",            "calendar/list_events",            AppToolApproval::Prompt,        );        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            app_tool_requirements(                "connector_123123",                "calendar/list_events",                AppToolApproval::Approve,            )        );    }    #[test]    fn merge_app_requirements_descending_uses_lower_tool_approval_when_higher_missing() {        let mut merged = apps_requirements(&[("connector_123123", None)]);        let lower = app_tool_requirements(            "connector_123123",            "calendar/list_events",            AppToolApproval::Approve,        );        merge_app_requirements_descending(&mut merged, lower);        assert_eq!(            merged,            app_tool_requirements(                "connector_123123",                "calendar/list_events",                AppToolApproval::Approve,            )        );    }    #[test]    fn merge_unset_fields_merges_apps_across_sources_with_enabled_evaluation() {        let higher_source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let lower_source = RequirementSource::MdmManagedPreferences {            domain: "com.openai.codex".to_string(),            key: "requirements_toml_base64".to_string(),        };        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(            higher_source.clone(),            ConfigRequirementsToml {                apps: Some(apps_requirements(&[                    ("connector_high", Some(true)),                    ("connector_shared", Some(true)),                ])),                ..Default::default()            },        );        target.merge_unset_fields(            lower_source,            ConfigRequirementsToml {                apps: Some(apps_requirements(&[                    ("connector_low", Some(false)),                    ("connector_shared", Some(false)),                ])),                ..Default::default()            },        );        let apps = target.apps.expect("apps should be present");        assert_eq!(            apps.value,            apps_requirements(&[                ("connector_high", Some(true)),                ("connector_low", Some(false)),                ("connector_shared", Some(false)),            ])        );        assert_eq!(apps.source, higher_source);    }    #[test]    fn merge_unset_fields_apps_empty_higher_source_does_not_block_lower_disables() {        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(            RequirementSource::LegacyManagedConfigTomlFromMdm,            ConfigRequirementsToml {                apps: Some(apps_requirements(&[])),                ..Default::default()            },        );        target.merge_unset_fields(            RequirementSource::LegacyManagedConfigTomlFromMdm,            ConfigRequirementsToml {                apps: Some(apps_requirements(&[("connector_123123", Some(false))])),                ..Default::default()            },        );        assert_eq!(            target.apps.map(|apps| apps.value),            Some(apps_requirements(&[("connector_123123", Some(false))])),        );    }    #[test]    fn constraint_error_includes_requirement_source() -> Result<()> {        let source: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["on-request"]                allowed_approvals_reviewers = ["auto_review"]                allowed_sandbox_modes = ["read-only"]            "#,        )?;        let requirements_toml_file = system_requirements_toml_file_for_test()?;        let source_location = RequirementSource::SystemRequirementsToml {            file: requirements_toml_file,        };        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(source_location.clone(), source);        let requirements = ConfigRequirements::try_from(target)?;        assert_eq!(            requirements.approval_policy.can_set(&AskForApproval::Never),            Err(ConstraintError::InvalidValue {                field_name: "approval_policy",                candidate: "Never".into(),                allowed: "[OnRequest]".into(),                requirement_source: source_location.clone(),            })        );        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::Disabled),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "DangerFullAccess".into(),                allowed: "[ReadOnly]".into(),                requirement_source: source_location.clone(),            })        );        assert_eq!(            requirements                .approvals_reviewer                .can_set(&ApprovalsReviewer::User),            Err(ConstraintError::InvalidValue {                field_name: "approvals_reviewer",                candidate: "User".into(),                allowed: "[AutoReview]".into(),                requirement_source: source_location,            })        );        Ok(())    }    #[test]    fn constraint_error_includes_composite_requirement_source() -> Result<()> {        let source: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["on-request"]            "#,        )?;        let source_location = RequirementSource::composite([            RequirementSource::MdmManagedPreferences {                domain: "com.openai.codex".to_string(),                key: "requirements_toml_base64".to_string(),            },            RequirementSource::LegacyManagedConfigTomlFromMdm,        ]);        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(source_location.clone(), source);        let requirements = ConfigRequirements::try_from(target)?;        assert_eq!(            requirements.approval_policy.can_set(&AskForApproval::Never),            Err(ConstraintError::InvalidValue {                field_name: "approval_policy",                candidate: "Never".into(),                allowed: "[OnRequest]".into(),                requirement_source: source_location,            })        );        Ok(())    }    #[test]    fn constrained_fields_store_requirement_source() -> Result<()> {        let source: ConfigRequirementsToml = from_str(            r#"                allowed_approval_policies = ["on-request"]                allowed_approvals_reviewers = ["auto_review"]                allowed_sandbox_modes = ["read-only"]                allowed_web_search_modes = ["cached"]                enforce_residency = "us"                [features]                personality = true            "#,        )?;        let source_location = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(source_location.clone(), source);        let requirements = ConfigRequirements::try_from(target)?;        assert_eq!(            requirements.approval_policy.source,            Some(source_location.clone())        );        assert_eq!(            requirements.approvals_reviewer.source,            Some(source_location.clone())        );        assert_eq!(            requirements.permission_profile.source,            Some(source_location.clone())        );        assert_eq!(            requirements.web_search_mode.source,            Some(source_location.clone())        );        assert_eq!(            requirements                .feature_requirements                .as_ref()                .map(|requirements| requirements.source.clone()),            Some(source_location.clone())        );        assert_eq!(requirements.enforce_residency.source, Some(source_location));        Ok(())    }    #[test]    fn deserialize_allowed_approval_policies() -> Result<()> {        let toml_str = r#"            allowed_approval_policies = ["untrusted", "on-request"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.approval_policy.value(),            AskForApproval::UnlessTrusted,            "currently, there is no way to specify the default value for approval policy in the toml, so it picks the first allowed value"        );        assert!(            requirements                .approval_policy                .can_set(&AskForApproval::UnlessTrusted)                .is_ok()        );        assert_eq!(            requirements                .approval_policy                .can_set(&AskForApproval::OnFailure),            Err(ConstraintError::InvalidValue {                field_name: "approval_policy",                candidate: "OnFailure".into(),                allowed: "[UnlessTrusted, OnRequest]".into(),                requirement_source: RequirementSource::Unknown,            })        );        assert!(            requirements                .approval_policy                .can_set(&AskForApproval::OnRequest)                .is_ok()        );        assert_eq!(            requirements.approval_policy.can_set(&AskForApproval::Never),            Err(ConstraintError::InvalidValue {                field_name: "approval_policy",                candidate: "Never".into(),                allowed: "[UnlessTrusted, OnRequest]".into(),                requirement_source: RequirementSource::Unknown,            })        );        assert!(            requirements                .permission_profile                .can_set(&PermissionProfile::read_only())                .is_ok()        );        Ok(())    }    #[test]    fn deserialize_allowed_approvals_reviewers() -> Result<()> {        let toml_str = r#"            allowed_approvals_reviewers = ["auto_review", "user"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.approvals_reviewer.value(),            ApprovalsReviewer::AutoReview,            "currently, there is no way to specify the default value for approvals reviewer in the toml, so it picks the first allowed value"        );        assert!(            requirements                .approvals_reviewer                .can_set(&ApprovalsReviewer::AutoReview)                .is_ok()        );        assert!(            requirements                .approvals_reviewer                .can_set(&ApprovalsReviewer::User)                .is_ok()        );        Ok(())    }    #[test]    fn deserialize_allowed_windows_sandbox_implementations() -> Result<()> {        let toml_str = r#"            [windows]            allowed_sandbox_implementations = ["elevated"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.windows_sandbox_mode.value(),            Some(WindowsSandboxModeToml::Elevated)        );        assert!(            requirements                .windows_sandbox_mode                .can_set(&Some(WindowsSandboxModeToml::Elevated))                .is_ok()        );        assert!(            requirements                .windows_sandbox_mode                .can_set(&Some(WindowsSandboxModeToml::Unelevated))                .is_err()        );        assert!(requirements.windows_sandbox_mode.can_set(&None).is_err());        Ok(())    }    #[test]    fn empty_allowed_windows_sandbox_implementations_is_rejected() -> Result<()> {        let toml_str = r#"            [windows]            allowed_sandbox_implementations = []        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        assert_eq!(            ConfigRequirements::try_from(with_unknown_source(config)),            Err(ConstraintError::EmptyField {                field_name: "windows.allowed_sandbox_implementations".to_string(),            })        );        Ok(())    }    #[test]    fn allowed_windows_sandbox_implementations_prefer_elevated_fallback() -> Result<()> {        let toml_str = r#"            [windows]            allowed_sandbox_implementations = ["unelevated", "elevated"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.windows_sandbox_mode.value(),            Some(WindowsSandboxModeToml::Elevated)        );        Ok(())    }    #[test]    fn deserialize_legacy_allowed_approvals_reviewer() -> Result<()> {        let toml_str = r#"            allowed_approvals_reviewers = ["guardian_subagent", "user"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.approvals_reviewer.value(),            ApprovalsReviewer::AutoReview        );        Ok(())    }    #[test]    fn empty_allowed_approvals_reviewers_is_rejected() -> Result<()> {        let toml_str = r#"            allowed_approvals_reviewers = []        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let err = ConfigRequirements::try_from(with_unknown_source(config))            .expect_err("empty approvals reviewer allow-list should be rejected");        assert_eq!(            err,            ConstraintError::EmptyField {                field_name: "allowed_approvals_reviewers".to_string(),            }        );        Ok(())    }    #[test]    fn deserialize_allowed_sandbox_modes() -> Result<()> {        let toml_str = r#"            allowed_sandbox_modes = ["read-only", "workspace-write"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        let root = if cfg!(windows) { "C:\\repo" } else { "/repo" };        assert!(            requirements                .permission_profile                .can_set(&PermissionProfile::read_only())                .is_ok()        );        let workspace_write_profile = PermissionProfile::workspace_write_with(            &[AbsolutePathBuf::from_absolute_path(root)?],            NetworkSandboxPolicy::Restricted,            /*exclude_tmpdir_env_var*/ false,            /*exclude_slash_tmp*/ false,        );        assert!(            requirements                .permission_profile                .can_set(&workspace_write_profile)                .is_ok()        );        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::Disabled),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "DangerFullAccess".into(),                allowed: "[ReadOnly, WorkspaceWrite]".into(),                requirement_source: RequirementSource::Unknown,            })        );        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::External {                    network: NetworkSandboxPolicy::Restricted,                }),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "ExternalSandbox".into(),                allowed: "[ReadOnly, WorkspaceWrite]".into(),                requirement_source: RequirementSource::Unknown,            })        );        Ok(())    }    #[test]    fn deserialize_remote_sandbox_config_requires_hostname_patterns_list() -> Result<()> {        let toml_str = r#"            [[remote_sandbox_config]]            hostname_patterns = ["*.org", "runner-??.ci"]            allowed_sandbox_modes = ["read-only", "workspace-write"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        assert_eq!(            config.remote_sandbox_config,            Some(vec![RemoteSandboxConfigToml {                hostname_patterns: vec!["*.org".to_string(), "runner-??.ci".to_string()],                allowed_sandbox_modes: vec![                    SandboxModeRequirement::ReadOnly,                    SandboxModeRequirement::WorkspaceWrite,                ],            }])        );        let err = from_str::<ConfigRequirementsToml>(            r#"                [[remote_sandbox_config]]                hostname_patterns = "*.org"                allowed_sandbox_modes = ["read-only"]            "#,        )        .expect_err("hostname_patterns should be list-only");        assert!(            err.to_string().contains("invalid type: string"),            "unexpected error: {err}"        );        Ok(())    }    #[test]    fn remote_sandbox_config_first_match_overrides_top_level() -> Result<()> {        let source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut requirements_toml: ConfigRequirementsToml = from_str(            r#"                allowed_sandbox_modes = ["read-only"]                [[remote_sandbox_config]]                hostname_patterns = ["build-*.example.com"]                allowed_sandbox_modes = ["read-only", "workspace-write"]                [[remote_sandbox_config]]                hostname_patterns = ["build-01.example.com"]                allowed_sandbox_modes = ["read-only", "danger-full-access"]            "#,        )?;        requirements_toml.apply_remote_sandbox_config(Some("BUILD-01.EXAMPLE.COM."));        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(source.clone(), requirements_toml);        assert_eq!(            requirements_with_sources                .allowed_sandbox_modes                .as_ref()                .map(|sourced| sourced.value.clone()),            Some(vec![                SandboxModeRequirement::ReadOnly,                SandboxModeRequirement::WorkspaceWrite,            ])        );        let requirements = ConfigRequirements::try_from(requirements_with_sources)?;        let root = if cfg!(windows) { "C:\\repo" } else { "/repo" };        let workspace_write_profile = PermissionProfile::workspace_write_with(            &[AbsolutePathBuf::from_absolute_path(root)?],            NetworkSandboxPolicy::Restricted,            /*exclude_tmpdir_env_var*/ false,            /*exclude_slash_tmp*/ false,        );        assert!(            requirements                .permission_profile                .can_set(&workspace_write_profile)                .is_ok()        );        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::Disabled),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "DangerFullAccess".into(),                allowed: "[ReadOnly, WorkspaceWrite]".into(),                requirement_source: source,            })        );        Ok(())    }    #[test]    fn remote_sandbox_config_non_match_preserves_top_level() -> Result<()> {        let mut requirements_toml: ConfigRequirementsToml = from_str(            r#"                allowed_sandbox_modes = ["read-only"]                [[remote_sandbox_config]]                hostname_patterns = ["build-*.example.com"]                allowed_sandbox_modes = ["read-only", "workspace-write"]            "#,        )?;        requirements_toml.apply_remote_sandbox_config(Some("laptop.example.com"));        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(RequirementSource::Unknown, requirements_toml);        let requirements = ConfigRequirements::try_from(requirements_with_sources)?;        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::Disabled),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "DangerFullAccess".into(),                allowed: "[ReadOnly]".into(),                requirement_source: RequirementSource::Unknown,            })        );        Ok(())    }    #[test]    fn remote_sandbox_config_does_not_override_higher_precedence_sandbox_modes() -> Result<()> {        let high_source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut high_precedence: ConfigRequirementsToml = from_str(            r#"                allowed_sandbox_modes = ["read-only"]            "#,        )?;        high_precedence.apply_remote_sandbox_config(Some("runner-01.ci.example.com"));        let mut low_precedence: ConfigRequirementsToml = from_str(            r#"                [[remote_sandbox_config]]                hostname_patterns = ["runner-*.ci.example.com"]                allowed_sandbox_modes = ["read-only", "workspace-write"]            "#,        )?;        low_precedence.apply_remote_sandbox_config(Some("runner-01.ci.example.com"));        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(high_source.clone(), high_precedence);        requirements_with_sources.merge_unset_fields(RequirementSource::Unknown, low_precedence);        let requirements = ConfigRequirements::try_from(requirements_with_sources)?;        assert_eq!(            requirements                .permission_profile                .can_set(&PermissionProfile::workspace_write()),            Err(ConstraintError::InvalidValue {                field_name: "sandbox_mode",                candidate: "WorkspaceWrite".into(),                allowed: "[ReadOnly]".into(),                requirement_source: high_source,            })        );        Ok(())    }    #[test]    fn deserialize_allowed_web_search_modes() -> Result<()> {        let toml_str = r#"            allowed_web_search_modes = ["cached"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(requirements.web_search_mode.value(), WebSearchMode::Cached);        assert!(            requirements                .web_search_mode                .can_set(&WebSearchMode::Disabled)                .is_ok()        );        assert_eq!(            requirements.web_search_mode.can_set(&WebSearchMode::Live),            Err(ConstraintError::InvalidValue {                field_name: "web_search_mode",                candidate: "Live".into(),                allowed: "[Disabled, Cached]".into(),                requirement_source: RequirementSource::Unknown,            })        );        assert!(            requirements                .web_search_mode                .can_set(&WebSearchMode::Cached)                .is_ok()        );        Ok(())    }    #[test]    fn allowed_web_search_modes_allows_disabled() -> Result<()> {        let toml_str = r#"            allowed_web_search_modes = ["disabled"]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.web_search_mode.value(),            WebSearchMode::Disabled        );        assert!(            requirements                .web_search_mode                .can_set(&WebSearchMode::Disabled)                .is_ok()        );        assert_eq!(            requirements.web_search_mode.can_set(&WebSearchMode::Cached),            Err(ConstraintError::InvalidValue {                field_name: "web_search_mode",                candidate: "Cached".into(),                allowed: "[Disabled]".into(),                requirement_source: RequirementSource::Unknown,            })        );        Ok(())    }    #[test]    fn allowed_web_search_modes_empty_restricts_to_disabled() -> Result<()> {        let toml_str = r#"            allowed_web_search_modes = []        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.web_search_mode.value(),            WebSearchMode::Disabled        );        assert!(            requirements                .web_search_mode                .can_set(&WebSearchMode::Disabled)                .is_ok()        );        assert_eq!(            requirements.web_search_mode.can_set(&WebSearchMode::Cached),            Err(ConstraintError::InvalidValue {                field_name: "web_search_mode",                candidate: "Cached".into(),                allowed: "[Disabled]".into(),                requirement_source: RequirementSource::Unknown,            })        );        Ok(())    }    #[test]    fn deserialize_feature_requirements() -> Result<()> {        let toml_str = r#"            [features]            apps = false            personality = true        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        assert_eq!(            requirements.feature_requirements,            Some(Sourced::new(                FeatureRequirementsToml {                    entries: BTreeMap::from([                        ("apps".to_string(), false),                        ("personality".to_string(), true),                    ]),                },                RequirementSource::Unknown,            ))        );        Ok(())    }    #[test]    fn deserialize_managed_hooks_requirements() -> Result<()> {        let toml_str = r#"managed_dir = "/enterprise/hooks"windows_managed_dir = 'C:\enterprise\hooks'[[PreToolUse]]matcher = "^Bash$"[[PreToolUse.hooks]]type = "command"command = "python3 /enterprise/hooks/pre.py"timeout = 10statusMessage = "checking"        "#;        let hooks: ManagedHooksRequirementsToml = from_str(toml_str)?;        assert_eq!(            hooks.managed_dir.as_deref(),            Some(std::path::Path::new("/enterprise/hooks"))        );        assert_eq!(hooks.handler_count(), 1);        assert_eq!(hooks.hooks.pre_tool_use.len(), 1);        Ok(())    }    #[test]    fn merge_unset_fields_does_not_overwrite_existing_hooks() -> Result<()> {        let mut target = ConfigRequirementsWithSources::default();        target.merge_unset_fields(            RequirementSource::LegacyManagedConfigTomlFromMdm,            from_str::<ConfigRequirementsToml>(                r#"[hooks]managed_dir = "/cloud/hooks"[[hooks.PreToolUse]]matcher = "^Bash$"[[hooks.PreToolUse.hooks]]type = "command"command = "python3 /cloud/hooks/pre.py"                "#,            )?,        );        target.merge_unset_fields(            RequirementSource::SystemRequirementsToml {                file: system_requirements_toml_file_for_test()?,            },            from_str::<ConfigRequirementsToml>(                r#"[hooks]managed_dir = "/system/hooks"[[hooks.PreToolUse]]matcher = "^Bash$"[[hooks.PreToolUse.hooks]]type = "command"command = "python3 /system/hooks/pre.py"                "#,            )?,        );        assert_eq!(            target                .hooks                .as_ref()                .and_then(|hooks| hooks.value.managed_dir.as_ref())                .map(std::path::PathBuf::as_path),            Some(std::path::Path::new("/cloud/hooks"))        );        assert_eq!(            target.hooks.as_ref().map(|hooks| hooks.source.clone()),            Some(RequirementSource::LegacyManagedConfigTomlFromMdm)        );        Ok(())    }    #[test]    fn managed_hooks_constraint_rejects_drift() -> Result<()> {        let config: ConfigRequirementsToml = from_str(            r#"[hooks]managed_dir = "/enterprise/hooks"[[hooks.PreToolUse]]matcher = "^Bash$"[[hooks.PreToolUse.hooks]]type = "command"command = "python3 /enterprise/hooks/pre.py"            "#,        )?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        let mut managed_hooks = requirements            .managed_hooks            .expect("expected managed hooks requirements");        let err = managed_hooks            .set(ManagedHooksRequirementsToml {                managed_dir: Some(std::path::PathBuf::from("/other/hooks")),                windows_managed_dir: None,                hooks: HookEventsToml::default(),            })            .expect_err("managed hooks should reject drift");        assert!(matches!(            err,            ConstraintError::InvalidValue {                field_name: "hooks",                requirement_source: RequirementSource::Unknown,                ..            }        ));        Ok(())    }    #[test]    fn network_requirements_are_preserved_as_constraints_with_source() -> Result<()> {        let toml_str = r#"            [experimental_network]            enabled = true            allow_upstream_proxy = false            dangerously_allow_all_unix_sockets = true            managed_allowed_domains_only = true            allow_local_binding = false            [experimental_network.domains]            "api.example.com" = "allow"            "*.openai.com" = "allow"            "blocked.example.com" = "deny"            [experimental_network.unix_sockets]            "/tmp/example.sock" = "allow"            "/tmp/blocked.sock" = "deny"        "#;        let source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(source.clone(), from_str(toml_str)?);        let requirements = ConfigRequirements::try_from(requirements_with_sources)?;        let sourced_network = requirements            .network            .expect("network requirements should be preserved as constraints");        assert_eq!(sourced_network.source, source);        assert_eq!(sourced_network.value.enabled, Some(true));        assert_eq!(sourced_network.value.allow_upstream_proxy, Some(false));        assert_eq!(            sourced_network.value.dangerously_allow_all_unix_sockets,            Some(true)        );        assert_eq!(            sourced_network.value.domains.as_ref(),            Some(&NetworkDomainPermissionsToml {                entries: BTreeMap::from([                    (                        "*.openai.com".to_string(),                        NetworkDomainPermissionToml::Allow,                    ),                    (                        "api.example.com".to_string(),                        NetworkDomainPermissionToml::Allow,                    ),                    (                        "blocked.example.com".to_string(),                        NetworkDomainPermissionToml::Deny,                    ),                ]),            })        );        assert_eq!(            sourced_network.value.managed_allowed_domains_only,            Some(true)        );        assert_eq!(            sourced_network.value.unix_sockets.as_ref(),            Some(&NetworkUnixSocketPermissionsToml {                entries: BTreeMap::from([                    (                        "/tmp/blocked.sock".to_string(),                        NetworkUnixSocketPermissionToml::Deny,                    ),                    (                        "/tmp/example.sock".to_string(),                        NetworkUnixSocketPermissionToml::Allow,                    ),                ]),            })        );        assert_eq!(sourced_network.value.allow_local_binding, Some(false));        Ok(())    }    #[test]    fn legacy_network_requirements_are_preserved_as_constraints_with_source() -> Result<()> {        let toml_str = r#"            [experimental_network]            enabled = true            allow_upstream_proxy = false            dangerously_allow_all_unix_sockets = true            allowed_domains = ["api.example.com", "*.openai.com"]            managed_allowed_domains_only = true            denied_domains = ["blocked.example.com"]            allow_unix_sockets = ["/tmp/example.sock"]            allow_local_binding = false        "#;        let source = RequirementSource::LegacyManagedConfigTomlFromMdm;        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(source.clone(), from_str(toml_str)?);        let requirements = ConfigRequirements::try_from(requirements_with_sources)?;        let sourced_network = requirements            .network            .expect("network requirements should be preserved as constraints");        assert_eq!(sourced_network.source, source);        assert_eq!(sourced_network.value.enabled, Some(true));        assert_eq!(sourced_network.value.allow_upstream_proxy, Some(false));        assert_eq!(            sourced_network.value.dangerously_allow_all_unix_sockets,            Some(true)        );        assert_eq!(            sourced_network.value.domains.as_ref(),            Some(&NetworkDomainPermissionsToml {                entries: BTreeMap::from([                    (                        "*.openai.com".to_string(),                        NetworkDomainPermissionToml::Allow,                    ),                    (                        "api.example.com".to_string(),                        NetworkDomainPermissionToml::Allow,                    ),                    (                        "blocked.example.com".to_string(),                        NetworkDomainPermissionToml::Deny,                    ),                ]),            })        );        assert_eq!(            sourced_network.value.managed_allowed_domains_only,            Some(true)        );        assert_eq!(            sourced_network.value.unix_sockets.as_ref(),            Some(&NetworkUnixSocketPermissionsToml {                entries: BTreeMap::from([(                    "/tmp/example.sock".to_string(),                    NetworkUnixSocketPermissionToml::Allow,                )]),            })        );        assert_eq!(sourced_network.value.allow_local_binding, Some(false));        Ok(())    }    #[test]    fn mixed_legacy_and_canonical_network_requirements_are_rejected() {        let err = from_str::<ConfigRequirementsToml>(            r#"                [experimental_network]                allowed_domains = ["api.example.com"]                [experimental_network.domains]                "*.openai.com" = "allow"            "#,        )        .expect_err("mixed network domain shapes should fail");        assert!(            err.to_string()                .contains("`experimental_network.domains` cannot be combined"),            "unexpected error: {err:#}"        );        let err = from_str::<ConfigRequirementsToml>(            r#"                [experimental_network]                allow_unix_sockets = ["/tmp/example.sock"]                [experimental_network.unix_sockets]                "/tmp/another.sock" = "allow"            "#,        )        .expect_err("mixed network unix socket shapes should fail");        assert!(            err.to_string()                .contains("`experimental_network.unix_sockets` cannot be combined"),            "unexpected error: {err:#}"        );    }    #[test]    fn network_permission_containers_project_allowed_and_denied_entries() {        let domains = NetworkDomainPermissionsToml {            entries: BTreeMap::from([                (                    "*.openai.com".to_string(),                    NetworkDomainPermissionToml::Allow,                ),                (                    "api.example.com".to_string(),                    NetworkDomainPermissionToml::Allow,                ),                (                    "blocked.example.com".to_string(),                    NetworkDomainPermissionToml::Deny,                ),            ]),        };        let unix_sockets = NetworkUnixSocketPermissionsToml {            entries: BTreeMap::from([                (                    "/tmp/example.sock".to_string(),                    NetworkUnixSocketPermissionToml::Allow,                ),                (                    "/tmp/ignored.sock".to_string(),                    NetworkUnixSocketPermissionToml::Deny,                ),            ]),        };        assert_eq!(            domains.allowed_domains(),            Some(vec![                "*.openai.com".to_string(),                "api.example.com".to_string()            ])        );        assert_eq!(            domains.denied_domains(),            Some(vec!["blocked.example.com".to_string()])        );        assert_eq!(            NetworkDomainPermissionsToml {                entries: BTreeMap::from([(                    "api.example.com".to_string(),                    NetworkDomainPermissionToml::Allow,                )]),            }            .denied_domains(),            None        );        assert_eq!(            unix_sockets.allow_unix_sockets(),            vec!["/tmp/example.sock".to_string()]        );    }    #[test]    fn deserialize_mcp_server_requirements() -> Result<()> {        let toml_str = r#"            [mcp_servers.docs.identity]            command = "codex-mcp"            [mcp_servers.remote.identity]            url = "https://example.com/mcp"        "#;        let requirements: ConfigRequirements =            with_unknown_source(from_str(toml_str)?).try_into()?;        assert_eq!(            requirements.mcp_servers,            Some(Sourced::new(                BTreeMap::from([                    (                        "docs".to_string(),                        McpServerRequirement {                            identity: McpServerIdentity::Command {                                command: "codex-mcp".to_string(),                            },                        },                    ),                    (                        "remote".to_string(),                        McpServerRequirement {                            identity: McpServerIdentity::Url {                                url: "https://example.com/mcp".to_string(),                            },                        },                    ),                ]),                RequirementSource::Unknown,            ))        );        Ok(())    }    #[test]    fn deserialize_plugin_mcp_server_requirements() -> Result<()> {        let toml_str = r#"            [plugins."sample@test".mcp_servers.sample.identity]            command = "sample-mcp"            [plugins."remote@test".mcp_servers.remote.identity]            url = "https://example.com/mcp"        "#;        let requirements: ConfigRequirements =            with_unknown_source(from_str(toml_str)?).try_into()?;        assert_eq!(            requirements.plugins,            Some(Sourced::new(                BTreeMap::from([                    (                        "remote@test".to_string(),                        PluginRequirementsToml {                            mcp_servers: Some(BTreeMap::from([(                                "remote".to_string(),                                McpServerRequirement {                                    identity: McpServerIdentity::Url {                                        url: "https://example.com/mcp".to_string(),                                    },                                },                            )])),                        },                    ),                    (                        "sample@test".to_string(),                        PluginRequirementsToml {                            mcp_servers: Some(BTreeMap::from([(                                "sample".to_string(),                                McpServerRequirement {                                    identity: McpServerIdentity::Command {                                        command: "sample-mcp".to_string(),                                    },                                },                            )])),                        },                    ),                ]),                RequirementSource::Unknown,            ))        );        Ok(())    }    #[test]    fn deserialize_exec_policy_requirements() -> Result<()> {        let toml_str = r#"            [rules]            prefix_rules = [                { pattern = [{ token = "rm" }], decision = "forbidden" },            ]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements: ConfigRequirements = with_unknown_source(config).try_into()?;        let policy = requirements.exec_policy.expect("exec policy").value;        assert_eq!(            policy.as_ref().check(&tokens(&["rm", "-rf"]), &|_| {                panic!("rule should match so heuristic should not be called");            }),            Evaluation {                decision: Decision::Forbidden,                matched_rules: vec![RuleMatch::PrefixRuleMatch {                    matched_prefix: tokens(&["rm"]),                    decision: Decision::Forbidden,                    resolved_program: None,                    justification: None,                }],            }        );        Ok(())    }    #[test]    fn exec_policy_error_includes_requirement_source() -> Result<()> {        let toml_str = r#"            [rules]            prefix_rules = [                { pattern = [{ token = "rm" }] },            ]        "#;        let config: ConfigRequirementsToml = from_str(toml_str)?;        let requirements_toml_file = system_requirements_toml_file_for_test()?;        let source_location = RequirementSource::SystemRequirementsToml {            file: requirements_toml_file,        };        let mut requirements_with_sources = ConfigRequirementsWithSources::default();        requirements_with_sources.merge_unset_fields(source_location.clone(), config);        let err = ConfigRequirements::try_from(requirements_with_sources)            .expect_err("invalid exec policy");        assert_eq!(            err,            ConstraintError::ExecPolicyParse {                requirement_source: source_location,                reason: "rules prefix_rule at index 0 is missing a decision".to_string(),            }        );        Ok(())    }}