feat: add managed artifact requirement plumbing

Co-authored-by: Codex noreply@openai.com
This commit is contained in:
viyatb-oai
2026-05-06 19:19:09 -07:00
parent 11106016ff
commit 45c47d2b33
3 changed files with 66 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)]
@@ -1158,6 +1213,8 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
managed_hooks,
mcp_servers,
plugins,
skills: None,
plugin_marketplaces: None,
exec_policy,
enforce_residency,
network,
@@ -1369,6 +1426,8 @@ mod tests {
hooks: None,
mcp_servers: None,
plugins: None,
skills: None,
plugin_marketplaces: None,
apps: None,
rules: None,
enforce_residency: None,
@@ -1416,6 +1475,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))