mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Update guardian output schema (#17061)
## Summary - Update guardian output schema to separate risk, authorization, outcome, and rationale. - Feed guardian rationale into rejection messages. - Split the guardian policy into template and tenant-config sections. ## Validation - `cargo test -p codex-core mcp_tool_call` - `env -u CODEX_SANDBOX_NETWORK_DISABLED INSTA_UPDATE=always cargo test -p codex-core guardian::` --------- Co-authored-by: Owen Lin <owen@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
49677ec71f
commit
dcbc91fd39
@@ -3231,13 +3231,13 @@ fn loads_compact_prompt_from_file() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_config_uses_requirements_guardian_developer_instructions() -> std::io::Result<()> {
|
||||
fn load_config_uses_requirements_guardian_policy_config() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
let config_layer_stack = ConfigLayerStack::new(
|
||||
Vec::new(),
|
||||
Default::default(),
|
||||
crate::config_loader::ConfigRequirementsToml {
|
||||
guardian_developer_instructions: Some(
|
||||
guardian_policy_config: Some(
|
||||
" Use the workspace-managed guardian policy. ".to_string(),
|
||||
),
|
||||
..Default::default()
|
||||
@@ -3256,7 +3256,7 @@ fn load_config_uses_requirements_guardian_developer_instructions() -> std::io::R
|
||||
)?;
|
||||
|
||||
assert_eq!(
|
||||
config.guardian_developer_instructions.as_deref(),
|
||||
config.guardian_policy_config.as_deref(),
|
||||
Some("Use the workspace-managed guardian policy.")
|
||||
);
|
||||
|
||||
@@ -3264,13 +3264,13 @@ fn load_config_uses_requirements_guardian_developer_instructions() -> std::io::R
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_config_ignores_empty_requirements_guardian_developer_instructions() -> std::io::Result<()> {
|
||||
fn load_config_ignores_empty_requirements_guardian_policy_config() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
let config_layer_stack = ConfigLayerStack::new(
|
||||
Vec::new(),
|
||||
Default::default(),
|
||||
crate::config_loader::ConfigRequirementsToml {
|
||||
guardian_developer_instructions: Some(" ".to_string()),
|
||||
guardian_policy_config: Some(" ".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@@ -3286,7 +3286,7 @@ fn load_config_ignores_empty_requirements_guardian_developer_instructions() -> s
|
||||
config_layer_stack,
|
||||
)?;
|
||||
|
||||
assert_eq!(config.guardian_developer_instructions, None);
|
||||
assert_eq!(config.guardian_policy_config, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -4558,7 +4558,7 @@ fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
|
||||
experimental_realtime_ws_startup_context: None,
|
||||
base_instructions: None,
|
||||
developer_instructions: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
include_permissions_instructions: true,
|
||||
include_apps_instructions: true,
|
||||
include_environment_context: true,
|
||||
@@ -4705,7 +4705,7 @@ fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
|
||||
experimental_realtime_ws_startup_context: None,
|
||||
base_instructions: None,
|
||||
developer_instructions: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
include_permissions_instructions: true,
|
||||
include_apps_instructions: true,
|
||||
include_environment_context: true,
|
||||
@@ -4850,7 +4850,7 @@ fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
|
||||
experimental_realtime_ws_startup_context: None,
|
||||
base_instructions: None,
|
||||
developer_instructions: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
include_permissions_instructions: true,
|
||||
include_apps_instructions: true,
|
||||
include_environment_context: true,
|
||||
@@ -4981,7 +4981,7 @@ fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
|
||||
experimental_realtime_ws_startup_context: None,
|
||||
base_instructions: None,
|
||||
developer_instructions: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
include_permissions_instructions: true,
|
||||
include_apps_instructions: true,
|
||||
include_environment_context: true,
|
||||
@@ -5041,7 +5041,7 @@ fn test_requirements_web_search_mode_allowlist_does_not_warn_when_unset() -> any
|
||||
rules: None,
|
||||
enforce_residency: None,
|
||||
network: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
};
|
||||
let requirement_source = crate::config_loader::RequirementSource::Unknown;
|
||||
let requirement_source_for_error = requirement_source.clone();
|
||||
@@ -5662,7 +5662,7 @@ async fn explicit_sandbox_mode_falls_back_when_disallowed_by_requirements() -> s
|
||||
rules: None,
|
||||
enforce_residency: None,
|
||||
network: None,
|
||||
guardian_developer_instructions: None,
|
||||
guardian_policy_config: None,
|
||||
};
|
||||
|
||||
let config = ConfigBuilder::without_managed_config_for_tests()
|
||||
|
||||
@@ -254,8 +254,11 @@ pub struct Config {
|
||||
/// Developer instructions override injected as a separate message.
|
||||
pub developer_instructions: Option<String>,
|
||||
|
||||
/// Guardian-specific developer instructions override from requirements.toml.
|
||||
pub guardian_developer_instructions: Option<String>,
|
||||
/// Guardian-specific tenant policy config override from requirements.toml.
|
||||
/// This is inserted into the fixed guardian prompt template under the
|
||||
/// `# Policy Configuration` section rather than replacing the whole
|
||||
/// guardian developer prompt.
|
||||
pub guardian_policy_config: Option<String>,
|
||||
|
||||
/// Whether to inject the `<permissions instructions>` developer block.
|
||||
pub include_permissions_instructions: bool,
|
||||
@@ -1840,9 +1843,8 @@ impl Config {
|
||||
.include_environment_context
|
||||
.or(cfg.include_environment_context)
|
||||
.unwrap_or(true);
|
||||
let guardian_developer_instructions = guardian_developer_instructions_from_requirements(
|
||||
config_layer_stack.requirements_toml(),
|
||||
);
|
||||
let guardian_policy_config =
|
||||
guardian_policy_config_from_requirements(config_layer_stack.requirements_toml());
|
||||
let personality = personality
|
||||
.or(config_profile.personality)
|
||||
.or(cfg.personality)
|
||||
@@ -2065,7 +2067,7 @@ impl Config {
|
||||
.show_raw_agent_reasoning
|
||||
.or(show_raw_agent_reasoning)
|
||||
.unwrap_or(false),
|
||||
guardian_developer_instructions,
|
||||
guardian_policy_config,
|
||||
model_reasoning_effort: config_profile
|
||||
.model_reasoning_effort
|
||||
.or(cfg.model_reasoning_effort),
|
||||
@@ -2273,11 +2275,11 @@ pub(crate) fn uses_deprecated_instructions_file(config_layer_stack: &ConfigLayer
|
||||
.any(|layer| toml_uses_deprecated_instructions_file(&layer.config))
|
||||
}
|
||||
|
||||
fn guardian_developer_instructions_from_requirements(
|
||||
fn guardian_policy_config_from_requirements(
|
||||
requirements_toml: &ConfigRequirementsToml,
|
||||
) -> Option<String> {
|
||||
requirements_toml
|
||||
.guardian_developer_instructions
|
||||
.guardian_policy_config
|
||||
.as_deref()
|
||||
.and_then(|value| {
|
||||
let trimmed = value.trim();
|
||||
|
||||
Reference in New Issue
Block a user