Ignore reusable command approvals for cyber models (#37516)

## What changed

- Filter saved `allow` prefix rules from the execution policy for cyber-specialized models and models listed in `auto_review.ignore_rules`, while preserving prompt, forbidden, network, and host-executable policy entries.
- Apply the filtered policy consistently to permission instructions, shell commands, unified exec, and the zsh-fork backend.
- Limit cyber-model command approvals to one-time decisions without proposing reusable policy amendments. General models continue to honor saved prefixes, including after switching models within a thread.

## Testing

- Add policy-level coverage for filtering allow-prefix rules while retaining restrictive and network rules.
- Add end-to-end coverage across shell and unified exec paths, zsh-fork execution, user and automatic review, and model switching.

GitOrigin-RevId: f3bd3872424291b12354ec415f33986ec369a368
This commit is contained in:
andrewgu-oai authored and copyberry committed 2026-08-08 00:59:39 +00:00
1 parent c2bcb9a26b
commit e734a1a5c1
16 files changed
+717 -14

No files matched your search

+19
View File
@@ -1,5 +1,6 @@
use super::*;
use crate::environment_selection::TurnEnvironmentSnapshot;
use crate::exec_policy::AllowPrefixRules;
use crate::shell_snapshot::ShellSnapshotFile;
use codex_core_plugins::PluginCommandAttribution;
use codex_core_plugins::TrustedPluginRoots;
@@ -8,6 +9,7 @@ use codex_model_provider::SharedModelProvider;
use codex_protocol::SessionId;
use codex_protocol::ThreadId;
use codex_protocol::models::AdditionalPermissionProfile;
use codex_protocol::openai_models::MODEL_SPECIALTY_CYBER;
use codex_protocol::openai_models::ModelInfo;
use codex_protocol::protocol::ErrorEvent;
use codex_protocol::protocol::MultiAgentVersion;
@@ -206,6 +208,23 @@ impl TurnContext {
self.config.permissions.approval_policy.value()
}
pub(crate) fn allow_prefix_rules(&self) -> AllowPrefixRules {
let ignore_rules = self
.config
.config_layer_stack
.requirements_toml()
.auto_review
.as_ref()
.and_then(|auto_review| auto_review.ignore_rules.as_ref())
.is_some_and(|models| models.contains(&self.model_info.slug));
if self.model_info.model_specialty.as_deref() == Some(MODEL_SPECIALTY_CYBER) || ignore_rules
{
AllowPrefixRules::IgnoreForCyberModel
} else {
AllowPrefixRules::Honor
}
}
pub(crate) fn permission_profile(&self) -> PermissionProfile {
self.config.permissions.effective_permission_profile()
}