//! Guardian review decides whether an `on-request` approval should be granted //! automatically instead of shown to the user. //! //! High-level approach: //! 1. Reconstruct a compact transcript that preserves user intent plus the most //! relevant recent assistant and tool context. //! 2. Ask a dedicated guardian review session to assess the exact planned //! action and return strict JSON. //! The guardian clones the parent config, so it inherits any managed //! network proxy / allowlist that the parent turn already had. //! 3. Fail closed on timeout, execution failure, or malformed output. //! 4. Approve only low- and medium-risk actions (`risk_score < 80`). mod approval_request; mod prompt; mod review; mod review_session; use std::time::Duration; use serde::Deserialize; use serde::Serialize; pub(crate) use approval_request::GuardianApprovalRequest; pub(crate) use approval_request::GuardianMcpAnnotations; pub(crate) use approval_request::guardian_approval_request_to_json; pub(crate) use review::GUARDIAN_REJECTION_MESSAGE; pub(crate) use review::is_guardian_reviewer_source; pub(crate) use review::review_approval_request; pub(crate) use review::review_approval_request_with_cancel; pub(crate) use review::routes_approval_to_guardian; pub(crate) use review_session::GuardianReviewSessionManager; const GUARDIAN_PREFERRED_MODEL: &str = "gpt-5.4"; pub(crate) const GUARDIAN_REVIEW_TIMEOUT: Duration = Duration::from_secs(90); pub(crate) const GUARDIAN_REVIEWER_NAME: &str = "guardian"; const GUARDIAN_MAX_MESSAGE_TRANSCRIPT_TOKENS: usize = 10_000; const GUARDIAN_MAX_TOOL_TRANSCRIPT_TOKENS: usize = 10_000; const GUARDIAN_MAX_MESSAGE_ENTRY_TOKENS: usize = 2_000; const GUARDIAN_MAX_TOOL_ENTRY_TOKENS: usize = 1_000; const GUARDIAN_MAX_ACTION_STRING_TOKENS: usize = 16_000; const GUARDIAN_APPROVAL_RISK_THRESHOLD: u8 = 80; const GUARDIAN_RECENT_ENTRY_LIMIT: usize = 40; const TRUNCATION_TAG: &str = "truncated"; /// Evidence item returned by the guardian reviewer. #[derive(Debug, Clone, Deserialize, Serialize)] pub(crate) struct GuardianEvidence { pub(crate) message: String, pub(crate) why: String, } /// Structured output contract that the guardian reviewer must satisfy. #[derive(Debug, Clone, Deserialize, Serialize)] pub(crate) struct GuardianAssessment { pub(crate) risk_level: codex_protocol::protocol::GuardianRiskLevel, pub(crate) risk_score: u8, pub(crate) rationale: String, pub(crate) evidence: Vec, } #[cfg(test)] use approval_request::format_guardian_action_pretty; #[cfg(test)] use approval_request::guardian_assessment_action; #[cfg(test)] use approval_request::guardian_request_turn_id; #[cfg(test)] use prompt::GuardianTranscriptEntry; #[cfg(test)] use prompt::GuardianTranscriptEntryKind; #[cfg(test)] use prompt::build_guardian_prompt_items; #[cfg(test)] use prompt::collect_guardian_transcript_entries; #[cfg(test)] use prompt::guardian_output_schema; #[cfg(test)] pub(crate) use prompt::guardian_policy_prompt; #[cfg(test)] use prompt::guardian_truncate_text; #[cfg(test)] use prompt::parse_guardian_assessment; #[cfg(test)] use prompt::render_guardian_transcript_entries; #[cfg(test)] use review::GuardianReviewOutcome; #[cfg(test)] use review::run_guardian_review_session as run_guardian_review_session_for_test; #[cfg(test)] use review_session::build_guardian_review_session_config as build_guardian_review_session_config_for_test; #[cfg(test)] mod tests;