Apply Guardian policies to v2 risk classification (#38618)

## What changed

- Include the resolved Guardian security policy in the v2 classifier's developer instructions.
- Prefer an explicit `guardian_policy_config`, then the reviewer model's catalog policy, and finally the bundled policy.
- Limit the combined classifier instructions and policy to 10,000 tokens.

## Testing

- Cover configured and catalog policies, policy truncation, and the bundled-policy fallback.

GitOrigin-RevId: 1b84d70081dd924e214636b4b470d57a63d7cb88
This commit is contained in:
felixxia-oai
2026-08-14 18:21:22 +00:00
committed by copyberry
parent 086396f7f6
commit 14a6813fa8
6 changed files with 201 additions and 30 deletions
+17
View File
@@ -1,5 +1,6 @@
use crate::config::edit::ConfigEdit;
use crate::config::edit::ConfigEditsBuilder;
use crate::guardian::BUNDLED_GUARDIAN_POLICY;
use crate::path_utils::normalize_for_native_workdir;
use crate::unified_exec::DEFAULT_MAX_BACKGROUND_TERMINAL_TIMEOUT_MS;
use crate::unified_exec::MIN_EMPTY_YIELD_TIME_MS;
@@ -106,6 +107,7 @@ use codex_protocol::models::ActivePermissionProfile;
use codex_protocol::models::BaseInstructionsProvenance;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::SandboxEnforcement;
use codex_protocol::openai_models::ModelMessages;
use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::permissions::FileSystemSandboxPolicy;
@@ -1520,6 +1522,21 @@ impl Config {
&self.sqlite
}
/// Resolves the configured, reviewer-catalog, or bundled Guardian policy.
pub fn resolve_guardian_policy<'a>(
&'a self,
model_messages: Option<&'a ModelMessages>,
) -> &'a str {
self.guardian_policy_config
.as_deref()
.or_else(|| {
model_messages
.and_then(|messages| messages.auto_review.as_ref())
.and_then(|messages| messages.policy.as_deref())
})
.unwrap_or(BUNDLED_GUARDIAN_POLICY)
}
pub(crate) fn multi_agent_version_override(&self) -> Option<MultiAgentVersion> {
if self.features.enabled(Feature::MultiAgentV2) {
Some(MultiAgentVersion::V2)
+1
View File
@@ -34,6 +34,7 @@ pub(crate) use approval_request::GuardianMcpAnnotations;
pub(crate) use approval_request::GuardianNetworkAccessTrigger;
#[cfg(test)]
pub(crate) use approval_request::guardian_approval_request_to_json;
pub(crate) use prompt::BUNDLED_GUARDIAN_POLICY;
pub(crate) use prompt::guardian_truncate_text;
pub(crate) use review::GuardianReviewOptions;
pub(crate) use review::guardian_timeout_message;
+1 -1
View File
@@ -816,7 +816,7 @@ For anything else, use this JSON schema:
}"#
}
pub(super) const BUNDLED_GUARDIAN_POLICY: &str = include_str!("policy.md");
pub(crate) const BUNDLED_GUARDIAN_POLICY: &str = include_str!("policy.md");
pub(super) const BUNDLED_GUARDIAN_POLICY_TEMPLATE: &str = include_str!("policy_template.md");
const TENANT_POLICY_CONFIG_PLACEHOLDER: &str = "{{ tenant_policy_config }}";
+2 -5
View File
@@ -75,6 +75,7 @@ use super::ApprovalRequestReasons;
use super::GUARDIAN_REVIEWER_NAME;
use super::GuardianApprovalRequest;
use super::GuardianReviewContext;
#[cfg(test)]
use super::prompt::BUNDLED_GUARDIAN_POLICY;
use super::prompt::BUNDLED_GUARDIAN_POLICY_TEMPLATE;
use super::prompt::GuardianPromptMode;
@@ -1290,11 +1291,7 @@ pub(crate) fn build_guardian_review_session_config(
guardian_config.memories.use_memories = false;
guardian_config.memories.dedicated_tools = false;
let catalog_auto_review = model_messages.and_then(|messages| messages.auto_review.as_ref());
let tenant_policy_config = parent_config
.guardian_policy_config
.as_deref()
.or_else(|| catalog_auto_review.and_then(|messages| messages.policy.as_deref()))
.unwrap_or(BUNDLED_GUARDIAN_POLICY);
let tenant_policy_config = parent_config.resolve_guardian_policy(model_messages);
let policy_template = catalog_auto_review
.and_then(|messages| messages.policy_template.as_deref())
.unwrap_or(BUNDLED_GUARDIAN_POLICY_TEMPLATE);