mirror of
https://github.com/openai/codex.git
synced 2026-04-29 00:55:38 +00: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:
@@ -225,8 +225,8 @@ pub fn guardian_auto_approval_review_notification(
|
||||
GuardianApprovalReviewStatus::Aborted
|
||||
}
|
||||
},
|
||||
risk_score: assessment.risk_score,
|
||||
risk_level: assessment.risk_level.map(Into::into),
|
||||
user_authorization: assessment.user_authorization.map(Into::into),
|
||||
rationale: assessment.rationale.clone(),
|
||||
};
|
||||
let action = assessment.action.clone().into();
|
||||
|
||||
@@ -2091,8 +2091,8 @@ mod tests {
|
||||
id: "guardian-exec".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
status: GuardianAssessmentStatus::InProgress,
|
||||
risk_score: None,
|
||||
risk_level: None,
|
||||
user_authorization: None,
|
||||
rationale: None,
|
||||
action: serde_json::from_value(serde_json::json!({
|
||||
"type": "command",
|
||||
@@ -2106,8 +2106,8 @@ mod tests {
|
||||
id: "guardian-exec".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
status: GuardianAssessmentStatus::Denied,
|
||||
risk_score: Some(97),
|
||||
risk_level: Some(codex_protocol::protocol::GuardianRiskLevel::High),
|
||||
user_authorization: Some(codex_protocol::protocol::GuardianUserAuthorization::Low),
|
||||
rationale: Some("Would delete user data.".into()),
|
||||
action: serde_json::from_value(serde_json::json!({
|
||||
"type": "command",
|
||||
@@ -2164,8 +2164,8 @@ mod tests {
|
||||
id: "guardian-execve".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
status: GuardianAssessmentStatus::InProgress,
|
||||
risk_score: None,
|
||||
risk_level: None,
|
||||
user_authorization: None,
|
||||
rationale: None,
|
||||
action: serde_json::from_value(serde_json::json!({
|
||||
"type": "execve",
|
||||
|
||||
@@ -54,6 +54,7 @@ use codex_protocol::protocol::ExecCommandSource as CoreExecCommandSource;
|
||||
use codex_protocol::protocol::ExecCommandStatus as CoreExecCommandStatus;
|
||||
use codex_protocol::protocol::GranularApprovalConfig as CoreGranularApprovalConfig;
|
||||
use codex_protocol::protocol::GuardianRiskLevel as CoreGuardianRiskLevel;
|
||||
use codex_protocol::protocol::GuardianUserAuthorization as CoreGuardianUserAuthorization;
|
||||
use codex_protocol::protocol::HookEventName as CoreHookEventName;
|
||||
use codex_protocol::protocol::HookExecutionMode as CoreHookExecutionMode;
|
||||
use codex_protocol::protocol::HookHandlerType as CoreHookHandlerType;
|
||||
@@ -4496,6 +4497,7 @@ pub enum GuardianRiskLevel {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Critical,
|
||||
}
|
||||
|
||||
impl From<CoreGuardianRiskLevel> for GuardianRiskLevel {
|
||||
@@ -4504,6 +4506,29 @@ impl From<CoreGuardianRiskLevel> for GuardianRiskLevel {
|
||||
CoreGuardianRiskLevel::Low => Self::Low,
|
||||
CoreGuardianRiskLevel::Medium => Self::Medium,
|
||||
CoreGuardianRiskLevel::High => Self::High,
|
||||
CoreGuardianRiskLevel::Critical => Self::Critical,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
/// [UNSTABLE] Authorization level assigned by guardian approval review.
|
||||
pub enum GuardianUserAuthorization {
|
||||
Unknown,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
}
|
||||
|
||||
impl From<CoreGuardianUserAuthorization> for GuardianUserAuthorization {
|
||||
fn from(value: CoreGuardianUserAuthorization) -> Self {
|
||||
match value {
|
||||
CoreGuardianUserAuthorization::Unknown => Self::Unknown,
|
||||
CoreGuardianUserAuthorization::Low => Self::Low,
|
||||
CoreGuardianUserAuthorization::Medium => Self::Medium,
|
||||
CoreGuardianUserAuthorization::High => Self::High,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4516,9 +4541,8 @@ impl From<CoreGuardianRiskLevel> for GuardianRiskLevel {
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct GuardianApprovalReview {
|
||||
pub status: GuardianApprovalReviewStatus,
|
||||
#[ts(type = "number | null")]
|
||||
pub risk_score: Option<u8>,
|
||||
pub risk_level: Option<GuardianRiskLevel>,
|
||||
pub user_authorization: Option<GuardianUserAuthorization>,
|
||||
pub rationale: Option<String>,
|
||||
}
|
||||
|
||||
@@ -7789,8 +7813,8 @@ mod tests {
|
||||
fn automatic_approval_review_deserializes_aborted_status() {
|
||||
let review: GuardianApprovalReview = serde_json::from_value(json!({
|
||||
"status": "aborted",
|
||||
"riskScore": null,
|
||||
"riskLevel": null,
|
||||
"userAuthorization": null,
|
||||
"rationale": null
|
||||
}))
|
||||
.expect("aborted automatic review should deserialize");
|
||||
@@ -7798,8 +7822,8 @@ mod tests {
|
||||
review,
|
||||
GuardianApprovalReview {
|
||||
status: GuardianApprovalReviewStatus::Aborted,
|
||||
risk_score: None,
|
||||
risk_level: None,
|
||||
user_authorization: None,
|
||||
rationale: None,
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user