Compare commits

...

2 Commits

Author SHA1 Message Date
viyatb-oai
4825e48fcd fix: keep managed artifact sources in config plumbing
Co-authored-by: Codex noreply@openai.com
2026-05-06 19:35:13 -07:00
viyatb-oai
45c47d2b33 feat: add managed artifact requirement plumbing
Co-authored-by: Codex noreply@openai.com
2026-05-06 19:19:09 -07:00
3 changed files with 76 additions and 0 deletions

View File

@@ -90,6 +90,8 @@ pub struct ConfigRequirements {
pub managed_hooks: Option<ConstrainedWithSource<ManagedHooksRequirementsToml>>,
pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,
pub plugins: Option<Sourced<BTreeMap<String, PluginRequirementsToml>>>,
pub skills: Option<Sourced<SkillsRequirementsToml>>,
pub plugin_marketplaces: Option<Sourced<PluginMarketplaceRequirementsToml>>,
pub exec_policy: Option<Sourced<RequirementsExecPolicy>>,
pub enforce_residency: ConstrainedWithSource<Option<ResidencyRequirement>>,
/// Managed network constraints derived from requirements.
@@ -123,6 +125,8 @@ impl Default for ConfigRequirements {
managed_hooks: None,
mcp_servers: None,
plugins: None,
skills: None,
plugin_marketplaces: None,
exec_policy: None,
enforce_residency: ConstrainedWithSource::new(
Constrained::allow_any(/*initial_value*/ None),
@@ -164,6 +168,57 @@ impl PluginRequirementsToml {
}
}
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum SkillSourceRequirement {
User,
Repo,
System,
Admin,
Plugin,
}
#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]
pub struct SkillsRequirementsToml {
pub allowed_sources: Option<Vec<SkillSourceRequirement>>,
}
impl SkillsRequirementsToml {
pub fn is_empty(&self) -> bool {
self.allowed_sources.is_none()
}
pub fn allows_source(&self, source: SkillSourceRequirement) -> bool {
self.allowed_sources
.as_ref()
.is_none_or(|sources| sources.contains(&source))
}
}
#[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)]
pub struct PluginMarketplaceRequirementsToml {
pub allowed_names: Option<Vec<String>>,
pub allow_user_additions: Option<bool>,
}
impl PluginMarketplaceRequirementsToml {
pub fn is_empty(&self) -> bool {
self.allowed_names.is_none() && self.allow_user_additions.is_none()
}
pub fn allows_marketplace(&self, marketplace_name: &str) -> bool {
self.allowed_names.as_ref().is_none_or(|allowed_names| {
allowed_names
.iter()
.any(|allowed_name| allowed_name == marketplace_name)
})
}
pub fn allows_user_additions(&self) -> bool {
self.allow_user_additions.unwrap_or(true)
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
pub struct NetworkDomainPermissionsToml {
#[serde(flatten)]
@@ -694,6 +749,8 @@ pub struct ConfigRequirementsWithSources {
pub hooks: Option<Sourced<ManagedHooksRequirementsToml>>,
pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,
pub plugins: Option<Sourced<BTreeMap<String, PluginRequirementsToml>>>,
pub skills: Option<Sourced<SkillsRequirementsToml>>,
pub plugin_marketplaces: Option<Sourced<PluginMarketplaceRequirementsToml>>,
pub apps: Option<Sourced<AppsRequirementsToml>>,
pub rules: Option<Sourced<RequirementsExecPolicyToml>>,
pub enforce_residency: Option<Sourced<ResidencyRequirement>>,
@@ -786,6 +843,8 @@ impl ConfigRequirementsWithSources {
hooks,
mcp_servers,
plugins,
skills: _,
plugin_marketplaces: _,
apps,
rules,
enforce_residency,
@@ -923,6 +982,8 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
hooks,
mcp_servers,
plugins,
skills,
plugin_marketplaces,
apps: _apps,
rules,
enforce_residency,
@@ -1158,6 +1219,8 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
managed_hooks,
mcp_servers,
plugins,
skills,
plugin_marketplaces,
exec_policy,
enforce_residency,
network,
@@ -1251,6 +1314,8 @@ mod tests {
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)),
skills: None,
plugin_marketplaces: None,
apps: apps.map(|value| Sourced::new(value, RequirementSource::Unknown)),
rules: rules.map(|value| Sourced::new(value, RequirementSource::Unknown)),
enforce_residency: enforce_residency
@@ -1330,6 +1395,8 @@ mod tests {
hooks: None,
mcp_servers: None,
plugins: None,
skills: None,
plugin_marketplaces: None,
apps: None,
rules: None,
enforce_residency: Some(Sourced::new(enforce_residency, enforce_source)),
@@ -1369,6 +1436,8 @@ mod tests {
hooks: None,
mcp_servers: None,
plugins: None,
skills: None,
plugin_marketplaces: None,
apps: None,
rules: None,
enforce_residency: None,
@@ -1416,6 +1485,8 @@ mod tests {
hooks: None,
mcp_servers: None,
plugins: None,
skills: None,
plugin_marketplaces: None,
apps: None,
rules: None,
enforce_residency: None,

View File

@@ -49,11 +49,14 @@ pub use config_requirements::NetworkDomainPermissionsToml;
pub use config_requirements::NetworkRequirementsToml;
pub use config_requirements::NetworkUnixSocketPermissionToml;
pub use config_requirements::NetworkUnixSocketPermissionsToml;
pub use config_requirements::PluginMarketplaceRequirementsToml;
pub use config_requirements::PluginRequirementsToml;
pub use config_requirements::RemoteSandboxConfigToml;
pub use config_requirements::RequirementSource;
pub use config_requirements::ResidencyRequirement;
pub use config_requirements::SandboxModeRequirement;
pub use config_requirements::SkillSourceRequirement;
pub use config_requirements::SkillsRequirementsToml;
pub use config_requirements::Sourced;
pub use config_requirements::WebSearchModeRequirement;
pub use config_requirements::sandbox_mode_requirement_for_permission_profile;

View File

@@ -2117,6 +2117,8 @@ impl Config {
network: network_requirements,
filesystem: filesystem_requirements,
guardian_policy_config_source: _,
skills: _,
plugin_marketplaces: _,
} = config_layer_stack.requirements().clone();
let user_instructions = AgentsMdManager::load_global_instructions(Some(&codex_home))