codex-rs/core/src/guardian/tests.rs (699 lines):
	- line 10: use crate::guardian::approval_request::guardian_request_target_item_id;
	- line 11: use crate::guardian::prompt::BUNDLED_GUARDIAN_POLICY;
	- line 12: use crate::guardian::prompt::BUNDLED_GUARDIAN_POLICY_TEMPLATE;
	- line 13: use crate::guardian::prompt::guardian_policy_prompt_with_config_and_template;
	- line 14: use crate::guardian::review::guardian_review_session_config;
	- line 15: use crate::guardian::review::routes_approval_to_guardian_with_reviewer;
	- line 20: use codex_analytics::GuardianApprovalRequestSource;
	- line 41: use codex_protocol::approvals::GuardianAssessmentAction;
	- line 56: use codex_protocol::protocol::AskForApproval;
	- line 60: use codex_protocol::protocol::GuardianAssessmentStatus;
	- line 61: use codex_protocol::protocol::GuardianRiskLevel;
	- line 62: use codex_protocol::protocol::GuardianUserAuthorization;
	- line 63: use codex_protocol::protocol::ReviewDecision;
	- line 95: fn fixed_guardian_parent_session_id() -> ThreadId {
	- line 100: const GUARDIAN_MEMORY_CONTEXT_PROBE: &str = "guardian memory context probe";
	- line 101: const GUARDIAN_SKILL_NAME: &str = "guardian-context-probe";
	- line 102: const GUARDIAN_SKILL_BODY_PROBE: &str = "guardian skill body probe";
	- line 104: // The memories extension depends on codex-core, so this probe verifies the nested Guardian config
	- line 106: struct GuardianMemoryContextEnabled(bool);
	- line 108: struct GuardianMemoryContextProbe;
	- line 110: impl codex_extension_api::ThreadLifecycleContributor<Config> for GuardianMemoryContextProbe {
	- line 116: input.thread_store.insert(GuardianMemoryContextEnabled(
	- line 123: impl codex_extension_api::ContextContributor for GuardianMemoryContextProbe {
	- line 131: .get::<GuardianMemoryContextEnabled>()
	- line 137: "guardian.memory_context_probe".to_string(),
	- line 148: fn guardian_rejection_circuit_breaker_interrupts_after_three_consecutive_denials() {
	- line 149: let mut circuit_breaker = GuardianRejectionCircuitBreaker::default();
	- line 151: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 152: GuardianRejectionCircuitBreakerAction::Continue
	- line 155: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 156: GuardianRejectionCircuitBreakerAction::Continue
	- line 159: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 160: GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 166: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 167: GuardianRejectionCircuitBreakerAction::Continue
	- line 172: fn guardian_rejection_circuit_breaker_interrupts_cyber_models_after_one_denial() {
	- line 173: let mut circuit_breaker = GuardianRejectionCircuitBreaker::default();
	- line 175: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::CyberModel),
	- line 176: GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 182: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::CyberModel),
	- line 183: GuardianRejectionCircuitBreakerAction::Continue
	- line 188: fn guardian_rejection_circuit_breaker_resets_consecutive_denials_on_non_denial() {
	- line 189: let mut circuit_breaker = GuardianRejectionCircuitBreaker::default();
	- line 191: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 192: GuardianRejectionCircuitBreakerAction::Continue
	- line 196: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 197: GuardianRejectionCircuitBreakerAction::Continue
	- line 200: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 201: GuardianRejectionCircuitBreakerAction::Continue
	- line 204: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 205: GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 214: let mut circuit_breaker = GuardianRejectionCircuitBreaker::default();
	- line 218: .record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 219: GuardianRejectionCircuitBreakerAction::Continue
	- line 224: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 225: GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 234: let mut circuit_breaker = GuardianRejectionCircuitBreaker::default();
	- line 238: .record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 239: GuardianRejectionCircuitBreakerAction::Continue
	- line 247: circuit_breaker.record_denial("turn-1", GuardianRejectionCircuitBreakerPolicy::Standard),
	- line 248: GuardianRejectionCircuitBreakerAction::Continue
	- line 252: async fn guardian_test_session_and_turn(
	- line 255: guardian_test_session_and_turn_with_base_url(server.uri().as_str()).await
	- line 258: async fn guardian_test_session_turn_and_rx(
	- line 269: .thread_id = fixed_guardian_parent_session_id();
	- line 290: fn guardian_exec_command_request(id: &str) -> GuardianApprovalRequest {
	- line 291: GuardianApprovalRequest::ExecCommand {
	- line 302: fn guardian_mcp_request(server: &str, tool_name: &str) -> GuardianApprovalRequest {
	- line 303: GuardianApprovalRequest::McpToolCall {
	- line 316: annotations: Some(GuardianMcpAnnotations {
	- line 324: async fn guardian_test_session_and_turn_with_base_url(
	- line 328: session.thread_id = fixed_guardian_parent_session_id();
	- line 344: async fn seed_guardian_parent_history(session: &Arc<Session>, turn: &Arc<TurnContext>) {
	- line 410: fn guardian_snapshot_options() -> ContextSnapshotOptions {
	- line 416: fn normalize_guardian_snapshot_paths(text: String) -> String {
	- line 432: let guardian_policy = guardian_policy_prompt_with_config_and_template(
	- line 439: text.replace(&guardian_policy, "<GUARDIAN_POLICY>")
	- line 442: fn guardian_prompt_text(items: &[codex_protocol::user_input::UserInput]) -> String {
	- line 468: fn build_guardian_transcript_keeps_original_numbering() {
	- line 470: GuardianTranscriptEntry {
	- line 471: kind: GuardianTranscriptEntryKind::User,
	- line 474: GuardianTranscriptEntry {
	- line 475: kind: GuardianTranscriptEntryKind::Assistant,
	- line 478: GuardianTranscriptEntry {
	- line 479: kind: GuardianTranscriptEntryKind::Assistant,
	- line 484: let (transcript, omission) = render_guardian_transcript_entries(&entries[..2]);
	- line 497: async fn build_guardian_prompt_full_mode_preserves_initial_review_format() -> anyhow::Result<()> {
	- line 498: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 499: seed_guardian_parent_history(&session, &turn).await;
	- line 501: let prompt = build_guardian_prompt_items(
	- line 504: GuardianApprovalRequest::ExecCommand {
	- line 513: GuardianPromptMode::Full,
	- line 517: let text = guardian_prompt_text(&prompt.items);
	- line 529: async fn build_guardian_prompt_prefers_retry_reason_over_approval_reason() -> anyhow::Result<()> {
	- line 530: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 531: seed_guardian_parent_history(&session, &turn).await;
	- line 532: let context = GuardianReviewContext::from(&turn);
	- line 534: let prompt = build_guardian_prompt_items_with_parent_turn(
	- line 541: GuardianApprovalRequest::ExecCommand {
	- line 550: GuardianPromptMode::Full,
	- line 555: let text = guardian_prompt_text(&prompt.items);
	- line 563: async fn build_guardian_prompt_truncates_oversized_approval_reason() -> anyhow::Result<()> {
	- line 564: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 565: seed_guardian_parent_history(&session, &turn).await;
	- line 566: let context = GuardianReviewContext::from(&turn);
	- line 573: let prompt = build_guardian_prompt_items_with_parent_turn(
	- line 580: GuardianApprovalRequest::ExecCommand {
	- line 589: GuardianPromptMode::Full,
	- line 614: async fn build_guardian_prompt_includes_parent_turn_denied_reads() -> anyhow::Result<()> {
	- line 616: session.thread_id = fixed_guardian_parent_session_id();
	- line 661: seed_guardian_parent_history(&session, &turn).await;
	- line 662: let context = GuardianReviewContext::from(&turn);
	- line 664: let prompt = build_guardian_prompt_items_with_parent_turn(
	- line 671: GuardianApprovalRequest::ExecCommand {
	- line 680: GuardianPromptMode::Full,
	- line 685: let text = guardian_prompt_text(&prompt.items);
	- line 696: async fn build_guardian_prompt_delta_mode_preserves_original_numbering() -> anyhow::Result<()> {
	- line 697: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 698: seed_guardian_parent_history(&session, &turn).await;
	- line 725: let prompt = build_guardian_prompt_items(
	- line 728: GuardianApprovalRequest::ExecCommand {
	- line 737: GuardianPromptMode::Delta {
	- line 738: cursor: GuardianTranscriptCursor {
	- line 746: let text = guardian_prompt_text(&prompt.items);
	- line 760: async fn build_guardian_prompt_delta_mode_handles_empty_delta() -> anyhow::Result<()> {
	- line 761: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 762: seed_guardian_parent_history(&session, &turn).await;
	- line 764: let prompt = build_guardian_prompt_items(
	- line 767: GuardianApprovalRequest::ExecCommand {
	- line 776: GuardianPromptMode::Delta {
	- line 777: cursor: GuardianTranscriptCursor {
	- line 785: let text = guardian_prompt_text(&prompt.items);
	- line 795: async fn build_guardian_prompt_stale_delta_cursor_falls_back_to_full_prompt() -> anyhow::Result<()>
	- line 797: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 798: seed_guardian_parent_history(&session, &turn).await;
	- line 800: let prompt = build_guardian_prompt_items(
	- line 803: GuardianApprovalRequest::ExecCommand {
	- line 812: GuardianPromptMode::Delta {
	- line 813: cursor: GuardianTranscriptCursor {
	- line 821: let text = guardian_prompt_text(&prompt.items);
	- line 831: async fn build_guardian_prompt_stale_delta_version_falls_back_to_full_prompt() -> anyhow::Result<()>
	- line 833: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 834: seed_guardian_parent_history(&session, &turn).await;
	- line 851: text: "Compacted summary of earlier guardian context.".to_string(),
	- line 886: let prompt = build_guardian_prompt_items(
	- line 889: GuardianApprovalRequest::ExecCommand {
	- line 898: GuardianPromptMode::Delta {
	- line 899: cursor: GuardianTranscriptCursor {
	- line 907: let text = guardian_prompt_text(&prompt.items);
	- line 920: fn collect_guardian_transcript_entries_skips_contextual_user_messages() {
	- line 942: let entries = collect_guardian_transcript_entries(&items);
	- line 947: GuardianTranscriptEntry {
	- line 948: kind: GuardianTranscriptEntryKind::Assistant,
	- line 955: fn collect_guardian_transcript_entries_keeps_manual_approval_developer_message() {
	- line 979: let entries = collect_guardian_transcript_entries(&items);
	- line 983: vec![GuardianTranscriptEntry {
	- line 984: kind: GuardianTranscriptEntryKind::Developer,
	- line 991: fn collect_guardian_transcript_entries_includes_recent_tool_calls_and_output() {
	- line 1032: let entries = collect_guardian_transcript_entries(&items);
	- line 1037: GuardianTranscriptEntry {
	- line 1038: kind: GuardianTranscriptEntryKind::Tool("tool read_file call".to_string()),
	- line 1044: GuardianTranscriptEntry {
	- line 1045: kind: GuardianTranscriptEntryKind::Tool("tool read_file result".to_string()),
	- line 1053: collect_guardian_transcript_entries(&items)[2].kind,
	- line 1054: GuardianTranscriptEntryKind::NodeReplToolResult(_)
	- line 1059: fn collect_guardian_transcript_entries_preserves_named_unpaired_tool_sources() {
	- line 1072: collect_guardian_transcript_entries(&items),
	- line 1073: vec![GuardianTranscriptEntry {
	- line 1074: kind: GuardianTranscriptEntryKind::Tool("tool slack.notifications result".to_string()),
	- line 1088: collect_guardian_transcript_entries(&items),
	- line 1089: vec![GuardianTranscriptEntry {
	- line 1090: kind: GuardianTranscriptEntryKind::Tool("tool slack.notifications result".to_string()),
	- line 1097: fn guardian_truncate_text_keeps_prefix_suffix_and_xml_marker() {
	- line 1100: let (truncated, was_truncated) = guardian_truncate_text(&content, /*token_cap*/ 20);
	- line 1109: fn format_guardian_action_pretty_truncates_large_string_fields() -> serde_json::Result<()> {
	- line 1111: let action = GuardianApprovalRequest::ApplyPatch {
	- line 1118: let rendered = format_guardian_action_pretty(&action)?;
	- line 1128: fn format_guardian_action_pretty_reports_no_truncation_for_small_payload() -> serde_json::Result<()>
	- line 1130: let action = GuardianApprovalRequest::ApplyPatch {
	- line 1137: let rendered = format_guardian_action_pretty(&action)?;
	- line 1145: fn guardian_approval_request_to_json_renders_mcp_tool_call_shape() -> serde_json::Result<()> {
	- line 1146: let action = GuardianApprovalRequest::McpToolCall {
	- line 1159: annotations: Some(GuardianMcpAnnotations {
	- line 1167: guardian_approval_request_to_json(&action)?,
	- line 1188: async fn build_guardian_prompt_items_keeps_required_node_repl_reviews_generic() -> anyhow::Result<()>
	- line 1191: guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 1196: seed_guardian_parent_history(&session, &turn).await;
	- line 1197: let context = GuardianReviewContext::from(&turn);
	- line 1199: let prompt = build_guardian_prompt_items_with_parent_turn(
	- line 1206: guardian_mcp_request("node_repl", "js"),
	- line 1207: GuardianPromptMode::Full,
	- line 1212: let text = guardian_prompt_text(&prompt.items);
	- line 1226: async fn build_guardian_prompt_items_keeps_other_requests_generic() -> anyhow::Result<()> {
	- line 1227: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 1228: seed_guardian_parent_history(&session, &turn).await;
	- line 1229: let context = GuardianReviewContext::from(&turn);
	- line 1232: guardian_mcp_request("node_repl", "js"),
	- line 1233: guardian_mcp_request("node_repl", "inspect"),
	- line 1234: guardian_mcp_request("another_server", "js"),
	- line 1235: guardian_exec_command_request("shell-1"),
	- line 1237: let prompt = build_guardian_prompt_items_with_parent_turn(
	- line 1242: GuardianPromptMode::Full,
	- line 1247: let text = guardian_prompt_text(&prompt.items);
	- line 1258: fn guardian_approval_request_to_json_renders_network_access_trigger() -> serde_json::Result<()> {
	- line 1260: let action = GuardianApprovalRequest::NetworkAccess {
	- line 1267: trigger: Some(GuardianNetworkAccessTrigger {
	- line 1280: guardian_approval_request_to_json(&action)?,
	- line 1302: async fn build_guardian_prompt_items_explains_network_access_review_scope() -> anyhow::Result<()> {
	- line 1303: let (session, turn) = guardian_test_session_and_turn_with_base_url("http://localhost").await;
	- line 1304: seed_guardian_parent_history(&session, &turn).await;
	- line 1307: let prompt = build_guardian_prompt_items(
	- line 1310: GuardianApprovalRequest::NetworkAccess {
	- line 1317: trigger: Some(GuardianNetworkAccessTrigger {
	- line 1328: GuardianPromptMode::Full,
	- line 1332: let text = guardian_prompt_text(&prompt.items);
	- line 1362: "codex_core__guardian__tests__network_access_guardian_prompt_layout",
	- line 1363: normalize_guardian_snapshot_paths(text)
	- line 1373: fn guardian_write_stdin_preserves_input_and_foreign_cwd(
	- line 1386: let action = GuardianApprovalRequest::WriteStdin {
	- line 1410: assert_eq!(guardian_approval_request_to_json(&action)?, expected);
	- line 1412: guardian_assessment_action(&action),
	- line 1413: GuardianAssessmentAction::WriteStdin {
	- line 1422: guardian_request_target_item_id(&action),
	- line 1423: guardian_request_turn_id(&action, "current-turn"),
	- line 1431: fn guardian_assessment_action_redacts_apply_patch_patch_text() {
	- line 1433: let file = test_path_buf("/tmp/guardian.txt").abs();
	- line 1434: let action = GuardianApprovalRequest::ApplyPatch {
	- line 1438: patch: "*** Begin Patch\n*** Update File: guardian.txt\n@@\n+secret\n*** End Patch"
	- line 1443: serde_json::to_value(guardian_assessment_action(&action)).expect("serialize action"),
	- line 1453: fn guardian_request_turn_id_prefers_network_access_owner_turn() {
	- line 1454: let network_access = GuardianApprovalRequest::NetworkAccess {
	- line 1463: let apply_patch = GuardianApprovalRequest::ApplyPatch {
	- line 1466: files: vec![test_path_buf("/tmp/guardian.txt").abs()],
	- line 1467: patch: "*** Begin Patch\n*** Update File: guardian.txt\n@@\n+hello\n*** End Patch"
	- line 1472: guardian_request_turn_id(&network_access, "fallback-turn"),
	- line 1476: guardian_request_turn_id(&apply_patch, "fallback-turn"),
	- line 1482: fn guardian_request_target_item_id_omits_network_access_trigger_call_id() {
	- line 1483: let network_access = GuardianApprovalRequest::NetworkAccess {
	- line 1490: trigger: Some(GuardianNetworkAccessTrigger {
	- line 1502: assert_eq!(guardian_request_target_item_id(&network_access), None);
	- line 1506: async fn cancelled_guardian_review_emits_terminal_abort_without_warning() {
	- line 1514: "review-cancelled-guardian".to_string(),
	- line 1515: GuardianApprovalRequest::ApplyPatch {
	- line 1518: files: vec![test_path_buf("/tmp/guardian.txt").abs()],
	- line 1519: patch: "*** Begin Patch\n*** Update File: guardian.txt\n@@\n+hello\n*** End Patch"
	- line 1523: GuardianReviewOptions {
	- line 1525: approval_request_source: GuardianApprovalRequestSource::MainTurn,
	- line 1532: assert_eq!(decision, ReviewDecision::Abort);
	- line 1534: let mut guardian_statuses = Vec::new();
	- line 1538: EventMsg::GuardianAssessment(event) => guardian_statuses.push(event.status),
	- line 1539: EventMsg::GuardianWarning(event) => warnings.push(event.message),
	- line 1545: guardian_statuses,
	- line 1547: GuardianAssessmentStatus::InProgress,
	- line 1548: GuardianAssessmentStatus::Aborted,
	- line 1555: fn guardian_timeout_message_distinguishes_timeout_from_policy_denial() {
	- line 1558: let message = guardian_timeout_message(&model);
	- line 1574: guardian_timeout_message(&model),
	- line 1581: async fn routes_approval_to_guardian_requires_guardian_reviewer() {
	- line 1587: assert!(!routes_approval_to_guardian(&turn));
	- line 1592: assert!(routes_approval_to_guardian(&turn));
	- line 1596: async fn routes_approval_to_guardian_can_use_app_reviewer_override() {
	- line 1599: assert!(!routes_approval_to_guardian_with_reviewer(
	- line 1603: assert!(routes_approval_to_guardian_with_reviewer(
	- line 1610: async fn routes_approval_to_guardian_allows_granular_review_policy() {
	- line 1617: .approval_policy
	- line 1618: .set(AskForApproval::Granular(GranularApprovalConfig {
	- line 1627: assert!(routes_approval_to_guardian(&turn));
	- line 1631: fn build_guardian_transcript_reserves_separate_budget_for_tool_evidence() {
	- line 1634: GuardianTranscriptEntry {
	- line 1635: kind: GuardianTranscriptEntryKind::User,
	- line 1638: GuardianTranscriptEntry {
	- line 1639: kind: GuardianTranscriptEntryKind::Assistant,
	- line 1643: entries.extend((0..12).map(|index| GuardianTranscriptEntry {
	- line 1644: kind: GuardianTranscriptEntryKind::Tool(format!("tool call {index}")),
	- line 1648: let (transcript, omission) = render_guardian_transcript_entries(&entries);
	- line 1672: fn build_guardian_transcript_preserves_recent_tool_context_when_user_history_is_large() {
	- line 1675: .map(|_| GuardianTranscriptEntry {
	- line 1676: kind: GuardianTranscriptEntryKind::User,
	- line 1681: GuardianTranscriptEntry {
	- line 1682: kind: GuardianTranscriptEntryKind::Tool("tool shell call".to_string()),
	- line 1689: GuardianTranscriptEntry {
	- line 1690: kind: GuardianTranscriptEntryKind::Tool("tool shell result".to_string()),
	- line 1695: let (transcript, omission) = render_guardian_transcript_entries(&entries);
	- line 1720: fn parse_guardian_assessment_extracts_embedded_json() {
	- line 1721: let parsed = parse_guardian_assessment(Some(
	- line 1724: .expect("guardian assessment");
	- line 1728: GuardianAssessment {
	- line 1729: risk_level: GuardianRiskLevel::Medium,
	- line 1730: user_authorization: GuardianUserAuthorization::Low,
	- line 1731: outcome: GuardianAssessmentOutcome::Allow,
	- line 1738: fn parse_guardian_assessment_treats_bare_allow_as_low_risk() {
	- line 1740: parse_guardian_assessment(Some(r#"{"outcome":"allow"}"#)).expect("guardian assessment");
	- line 1744: GuardianAssessment {
	- line 1745: risk_level: GuardianRiskLevel::Low,
	- line 1746: user_authorization: GuardianUserAuthorization::Unknown,
	- line 1747: outcome: GuardianAssessmentOutcome::Allow,
	- line 1754: fn parse_guardian_assessment_treats_bare_deny_as_high_risk() {
	- line 1756: parse_guardian_assessment(Some(r#"{"outcome":"deny"}"#)).expect("guardian assessment");
	- line 1760: GuardianAssessment {
	- line 1761: risk_level: GuardianRiskLevel::High,
	- line 1762: user_authorization: GuardianUserAuthorization::Unknown,
	- line 1763: outcome: GuardianAssessmentOutcome::Deny,
	- line 1770: fn guardian_output_schema_requires_only_outcome_and_allows_optional_details() {
	- line 1771: let schema = guardian_output_schema();
	- line 1800: enum GuardianTestCatalog {
	- line 1805: async fn guardian_request_model_for_auto_review(
	- line 1807: catalog: GuardianTestCatalog,
	- line 1812: codex_analytics::GuardianReviewAnalyticsResult,
	- line 1815: let guardian_assessment = serde_json::json!({
	- line 1822: ev_response_created("resp-guardian"),
	- line 1823: ev_assistant_message("msg-guardian", &guardian_assessment),
	- line 1824: ev_completed("resp-guardian"),
	- line 1829: let (mut session, mut turn) = guardian_test_session_and_turn(&server).await;
	- line 1831: GuardianTestCatalog::Bundled => {}
	- line 1832: GuardianTestCatalog::ParentOnly => {
	- line 1857: seed_guardian_parent_history(&session, &turn).await;
	- line 1859: let (outcome, analytics_result) = run_guardian_review_session_for_test(
	- line 1862: GuardianApprovalRequest::ExecCommand {
	- line 1875: guardian_output_schema(),
	- line 1880: let GuardianReviewOutcome::Completed(_) = outcome else {
	- line 1881: panic!("expected guardian assessment");
	- line 1890: .expect("guardian request should include a model")
	- line 1902: async fn guardian_review_uses_model_catalog_override_when_preferred_review_model_exists()
	- line 1906: let override_model = "guardian-review-model-override".to_string();
	- line 1908: guardian_request_model_for_auto_review(
	- line 1910: GuardianTestCatalog::Bundled,
	- line 1918: analytics_result.guardian_catalog_contains_auto_review,
	- line 1922: analytics_result.guardian_default_review_model_id.as_deref(),
	- line 1926: analytics_result.guardian_review_model_overridden,
	- line 1930: analytics_result.guardian_review_model_override.as_deref(),
	- line 1934: analytics_result.guardian_model_provider_id.as_deref(),
	- line 1942: async fn guardian_review_uses_preferred_review_model_without_model_catalog_override()
	- line 1947: guardian_request_model_for_auto_review(
	- line 1949: GuardianTestCatalog::Bundled,
	- line 1956: analytics_result.guardian_catalog_contains_auto_review,
	- line 1960: analytics_result.guardian_default_review_model_id.as_deref(),
	- line 1964: analytics_result.guardian_review_model_overridden,
	- line 1968: analytics_result.guardian_review_model_override.as_deref(),
	- line 1972: analytics_result.guardian_model_provider_id.as_deref(),
	- line 1980: async fn guardian_review_records_missing_auto_review_model_in_analytics_metadata()
	- line 1985: guardian_request_model_for_auto_review(
	- line 1987: GuardianTestCatalog::ParentOnly,
	- line 1994: analytics_result.guardian_catalog_contains_auto_review,
	- line 1998: analytics_result.guardian_default_review_model_id.as_deref(),
	- line 2002: analytics_result.guardian_review_model_overridden,
	- line 2006: analytics_result.guardian_review_model_override.as_deref(),
	- line 2010: analytics_result.guardian_model_provider_id.as_deref(),
	- line 2018: async fn guardian_review_request_layout_matches_model_visible_request_snapshot()
	- line 2023: let guardian_assessment = serde_json::json!({
	- line 2033: ev_response_created("resp-guardian"),
	- line 2034: ev_assistant_message("msg-guardian", &guardian_assessment),
	- line 2035: ev_completed("resp-guardian"),
	- line 2041: session.thread_id = fixed_guardian_parent_session_id();
	- line 2058: let memory_extension = Arc::new(GuardianMemoryContextProbe);
	- line 2073: "---\nname: {GUARDIAN_SKILL_NAME}\ndescription: Guardian skill injection probe.\n---\n\n{GUARDIAN_SKILL_BODY_PROBE}\n"
	- line 2085: seed_guardian_parent_history(&session, &turn).await;
	- line 2103: let request = GuardianApprovalRequest::ExecCommand {
	- line 2109: "guardian-approval-mvp".to_string(),
	- line 2118: let outcome = run_guardian_review_session_for_test(
	- line 2126: guardian_output_schema(),
	- line 2131: let (GuardianReviewOutcome::Completed(assessment), metadata) = outcome else {
	- line 2132: panic!("expected guardian assessment");
	- line 2134: let guardian_thread_id = metadata
	- line 2135: .guardian_thread_id
	- line 2137: .expect("guardian thread id");
	- line 2138: assert_eq!(assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2139: assert_ne!(guardian_thread_id, session.thread_id.to_string());
	- line 2140: ThreadId::from_string(guardian_thread_id).expect("guardian thread id should be a valid UUID");
	- line 2142: metadata.guardian_session_kind,
	- line 2143: Some(codex_analytics::GuardianReviewSessionKind::TrunkNew)
	- line 2149: "guardian request should use Responses Lite tool input"
	- line 2151: let guardian_tools = request_body["input"]
	- line 2162: .expect("guardian request functions namespace");
	- line 2163: let mut guardian_tool_names = guardian_tools
	- line 2165: .map(|tool| tool["name"].as_str().expect("guardian code-mode tool name"))
	- line 2167: guardian_tool_names.sort_unstable();
	- line 2168: assert_eq!(guardian_tool_names, vec!["exec", "wait"]);
	- line 2170: let guardian_exec_description = guardian_tools
	- line 2174: .expect("guardian code-mode exec description");
	- line 2175: let mut guardian_nested_tool_names = guardian_exec_description
	- line 2180: guardian_nested_tool_names.sort_unstable();
	- line 2182: guardian_nested_tool_names,
	- line 2185: let guardian_user_text = request.message_input_texts("user").join("\n");
	- line 2187: guardian_user_text.contains(&format!("${GUARDIAN_SKILL_NAME}")),
	- line 2188: "guardian request should contain the untrusted skill mention from the parent transcript"
	- line 2192: "guardian request should not inject a skill body from its generated review prompt"
	- line 2196: "guardian request should not include memory context"
	- line 2230: .expect("guardian request should include a model");
	- line 2235: assert_eq!(metadata.guardian_model.as_deref(), Some(request_model));
	- line 2237: metadata.guardian_reasoning_effort.as_deref(),
	- line 2243: "guardian review metadata should capture TTFT when the nested turn completes"
	- line 2251: "codex_core__guardian__tests__guardian_review_request_layout",
	- line 2252: normalize_guardian_snapshot_paths(context_snapshot::format_labeled_requests_snapshot(
	- line 2253: "Guardian review request layout",
	- line 2254: &[("Guardian Review Request", &request)],
	- line 2255: &guardian_snapshot_options(),
	- line 2264: async fn build_guardian_prompt_items_includes_parent_session_id() -> anyhow::Result<()> {
	- line 2266: let prompt = build_guardian_prompt_items(
	- line 2269: GuardianApprovalRequest::ExecCommand {
	- line 2278: GuardianPromptMode::Full,
	- line 2296: "guardian prompt should expose the parent session id immediately after the transcript end"
	- line 2303: async fn guardian_reuses_prompt_cache_key_and_appends_prior_reviews() -> anyhow::Result<()> {
	- line 2307: let first_rationale = "first guardian rationale from the prior review";
	- line 2312: ev_response_created("resp-guardian-1"),
	- line 2314: "msg-guardian-1",
	- line 2319: ev_completed("resp-guardian-1"),
	- line 2322: ev_response_created("resp-guardian-2"),
	- line 2324: "msg-guardian-2",
	- line 2325: "{\"risk_level\":\"low\",\"user_authorization\":\"high\",\"outcome\":\"allow\",\"rationale\":\"second guardian rationale\"}",
	- line 2327: ev_completed("resp-guardian-2"),
	- line 2330: ev_response_created("resp-guardian-3"),
	- line 2332: "msg-guardian-3",
	- line 2333: "{\"risk_level\":\"low\",\"user_authorization\":\"high\",\"outcome\":\"allow\",\"rationale\":\"third guardian rationale\"}",
	- line 2335: ev_completed("resp-guardian-3"),
	- line 2338: ev_response_created("resp-guardian-4"),
	- line 2340: "msg-guardian-4",
	- line 2341: "{\"risk_level\":\"low\",\"user_authorization\":\"high\",\"outcome\":\"allow\",\"rationale\":\"fourth guardian rationale\"}",
	- line 2343: ev_completed("resp-guardian-4"),
	- line 2349: let (session, mut turn) = guardian_test_session_and_turn(&server).await;
	- line 2353: .enable(Feature::GuardianReuseParentCompaction)
	- line 2354: .expect("Guardian parent-compaction reuse should be configurable");
	- line 2361: seed_guardian_parent_history(&session, &turn).await;
	- line 2363: let first_request = GuardianApprovalRequest::ExecCommand {
	- line 2372: let first_outcome = run_guardian_review_session_for_test(
	- line 2380: guardian_output_schema(),
	- line 2410: let second_request = GuardianApprovalRequest::ExecCommand {
	- line 2423: let second_outcome = run_guardian_review_session_for_test(
	- line 2431: guardian_output_schema(),
	- line 2437: .guardian_review_session
	- line 2440: .expect("committed guardian fork snapshot");
	- line 2450: "follow-up reminder should be persisted for guardian forks"
	- line 2457: "cmp_guardian_parent_summary".to_string(),
	- line 2459: encrypted_content: "encrypted guardian parent summary".to_string(),
	- line 2484: let third_request = GuardianApprovalRequest::ExecCommand {
	- line 2493: let third_outcome = run_guardian_review_session_for_test(
	- line 2501: guardian_output_schema(),
	- line 2520: let fourth_outcome = run_guardian_review_session_for_test(
	- line 2523: guardian_exec_command_request("shell-4"),
	- line 2525: guardian_output_schema(),
	- line 2531: let (GuardianReviewOutcome::Completed(first_assessment), first_metadata) = first_outcome else {
	- line 2532: panic!("expected first guardian assessment");
	- line 2534: let (GuardianReviewOutcome::Completed(second_assessment), second_metadata) = second_outcome
	- line 2536: panic!("expected second guardian assessment");
	- line 2538: let (GuardianReviewOutcome::Completed(third_assessment), third_metadata) = third_outcome else {
	- line 2539: panic!("expected third guardian assessment");
	- line 2541: let (GuardianReviewOutcome::Completed(fourth_assessment), fourth_metadata) = fourth_outcome
	- line 2543: panic!("expected fourth guardian assessment");
	- line 2545: assert_eq!(first_assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2546: assert_eq!(second_assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2547: assert_eq!(third_assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2548: assert_eq!(fourth_assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2550: first_metadata.guardian_session_kind,
	- line 2551: Some(codex_analytics::GuardianReviewSessionKind::TrunkNew)
	- line 2554: second_metadata.guardian_session_kind,
	- line 2555: Some(codex_analytics::GuardianReviewSessionKind::TrunkReused)
	- line 2558: third_metadata.guardian_session_kind,
	- line 2559: Some(codex_analytics::GuardianReviewSessionKind::TrunkNew)
	- line 2562: fourth_metadata.guardian_session_kind,
	- line 2563: Some(codex_analytics::GuardianReviewSessionKind::TrunkReused)
	- line 2567: .guardian_thread_id
	- line 2569: .expect("first guardian thread id"),
	- line 2571: .expect("first guardian thread id should be a valid UUID");
	- line 2574: .guardian_thread_id
	- line 2576: .expect("second guardian thread id"),
	- line 2578: .expect("second guardian thread id should be a valid UUID");
	- line 2581: .guardian_thread_id
	- line 2583: .expect("third guardian thread id"),
	- line 2585: .expect("third guardian thread id should be a valid UUID");
	- line 2591: first_metadata.guardian_thread_id,
	- line 2592: second_metadata.guardian_thread_id
	- line 2595: second_metadata.guardian_thread_id,
	- line 2596: third_metadata.guardian_thread_id
	- line 2599: third_metadata.guardian_thread_id,
	- line 2600: fourth_metadata.guardian_thread_id
	- line 2612: .expect("guardian review should include input items");
	- line 2615: && item["id"] == "cmp_guardian_parent_summary"
	- line 2616: && item["encrypted_content"] == "encrypted guardian parent summary"
	- line 2630: assert!(fourth_body.to_string().contains("third guardian rationale"));
	- line 2639: "follow-up guardian request should include the follow-up reminder"
	- line 2643: "guardian session should append earlier reviews into the follow-up request"
	- line 2651: "a fresh guardian session should not inherit the follow-up reminder"
	- line 2656: .expect("fresh guardian user message")
	- line 2664: .expect("follow-up guardian user message")
	- line 2678: "codex_core__guardian__tests__guardian_followup_review_request_layout",
	- line 2681: normalize_guardian_snapshot_paths(
	- line 2683: "Guardian follow-up review request layout",
	- line 2685: ("Initial Guardian Review Request", &requests[0]),
	- line 2686: ("Follow-up Guardian Review Request", &requests[1]),
	- line 2688: &guardian_snapshot_options(),
	- line 2701: async fn guardian_reused_trunk_ignores_stale_prior_turn_completion() -> anyhow::Result<()> {
	- line 2709: ev_response_created("resp-guardian-1"),
	- line 2711: "msg-guardian-1",
	- line 2712: "{\"risk_level\":\"low\",\"user_authorization\":\"high\",\"outcome\":\"allow\",\"rationale\":\"first guardian rationale\"}",
	- line 2714: ev_completed("resp-guardian-1"),
	- line 2717: ev_response_created("resp-guardian-2"),
	- line 2719: "msg-guardian-2",
	- line 2720: "{\"risk_level\":\"low\",\"user_authorization\":\"high\",\"outcome\":\"allow\",\"rationale\":\"second guardian rationale\"}",
	- line 2722: ev_completed("resp-guardian-2"),
	- line 2728: let (session, turn) = guardian_test_session_and_turn(&server).await;
	- line 2729: let first_outcome = run_guardian_review_session_for_test(
	- line 2732: GuardianApprovalRequest::ExecCommand {
	- line 2742: guardian_output_schema(),
	- line 2747: let (GuardianReviewOutcome::Completed(first_assessment), first_metadata) = first_outcome else {
	- line 2748: panic!("expected first guardian assessment");
	- line 2750: assert_eq!(first_assessment.rationale, "first guardian rationale");
	- line 2752: first_metadata.guardian_session_kind,
	- line 2753: Some(codex_analytics::GuardianReviewSessionKind::TrunkNew)
	- line 2757: .guardian_review_session
	- line 2764: "{\"risk_level\":\"high\",\"user_authorization\":\"low\",\"outcome\":\"deny\",\"rationale\":\"stale guardian rationale\"}"
	- line 2775: let second_outcome = run_guardian_review_session_for_test(
	- line 2778: GuardianApprovalRequest::ExecCommand {
	- line 2788: guardian_output_schema(),
	- line 2793: let (GuardianReviewOutcome::Completed(second_assessment), second_metadata) = second_outcome
	- line 2795: panic!("expected second guardian assessment");
	- line 2797: assert_eq!(second_assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2798: assert_eq!(second_assessment.rationale, "second guardian rationale");
	- line 2800: second_metadata.guardian_session_kind,
	- line 2801: Some(codex_analytics::GuardianReviewSessionKind::TrunkReused)
	- line 2814: async fn guardian_review_surfaces_responses_api_errors_in_rejection_reason() -> anyhow::Result<()> {
	- line 2853: seed_guardian_parent_history(&session, &turn).await;
	- line 2858: "review-shell-guardian-error".to_string(),
	- line 2859: GuardianApprovalRequest::ExecCommand {
	- line 2860: id: "shell-guardian-error".to_string(),
	- line 2872: let ReviewDecision::Denied { rejection } = decision else {
	- line 2873: panic!("guardian error should deny the approval");
	- line 2881: EventMsg::GuardianWarning(event) => warnings.push(event.message),
	- line 2882: EventMsg::GuardianAssessment(event)
	- line 2883: if event.status == GuardianAssessmentStatus::Denied =>
	- line 2906: !message.contains("guardian review completed without an assessment payload")
	- line 2913: "rejection message should include guardian rationale: {rejection}"
	- line 2920: async fn guardian_review_retries_transient_session_failure_then_approves() -> anyhow::Result<()> {
	- line 2947: let (session, turn) = guardian_test_session_and_turn(&server).await;
	- line 2948: seed_guardian_parent_history(&session, &turn).await;
	- line 2950: let (outcome, metadata) = run_guardian_review_session_for_test(
	- line 2953: guardian_exec_command_request("shell-session-retry"),
	- line 2955: guardian_output_schema(),
	- line 2961: let GuardianReviewOutcome::Completed(assessment) = outcome else {
	- line 2962: panic!("expected guardian assessment");
	- line 2964: assert_eq!(assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 2968: metadata.guardian_session_kind,
	- line 2969: Some(codex_analytics::GuardianReviewSessionKind::TrunkReused)
	- line 2976: async fn guardian_review_does_not_retry_missing_assessment_payload() -> anyhow::Result<()> {
	- line 2988: let (session, turn) = guardian_test_session_and_turn(&server).await;
	- line 2989: seed_guardian_parent_history(&session, &turn).await;
	- line 2995: guardian_exec_command_request("shell-missing-assessment"),
	- line 3000: assert!(matches!(decision, ReviewDecision::Denied { .. }));
	- line 3006: async fn guardian_review_retries_two_parse_failures_then_approves() -> anyhow::Result<()> {
	- line 3022: ev_assistant_message("msg-parse-failure-1", "not valid guardian json"),
	- line 3027: ev_assistant_message("msg-parse-failure-2", "still not valid guardian json"),
	- line 3038: let (session, turn) = guardian_test_session_and_turn(&server).await;
	- line 3039: seed_guardian_parent_history(&session, &turn).await;
	- line 3041: let (outcome, metadata) = run_guardian_review_session_for_test(
	- line 3044: guardian_exec_command_request("shell-parse-retry"),
	- line 3046: guardian_output_schema(),
	- line 3052: let GuardianReviewOutcome::Completed(assessment) = outcome else {
	- line 3053: panic!("expected guardian assessment");
	- line 3055: assert_eq!(assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 3059: metadata.guardian_session_kind,
	- line 3060: Some(codex_analytics::GuardianReviewSessionKind::TrunkReused)
	- line 3067: async fn guardian_review_exhausts_three_failures_with_one_terminal_event() -> anyhow::Result<()> {
	- line 3092: let (session, turn, rx) = guardian_test_session_turn_and_rx(&server).await;
	- line 3093: seed_guardian_parent_history(&session, &turn).await;
	- line 3099: guardian_exec_command_request("shell-exhausted-retry"),
	- line 3104: assert!(matches!(decision, ReviewDecision::Denied { .. }));
	- line 3108: if let EventMsg::GuardianAssessment(event) = event.msg {
	- line 3115: GuardianAssessmentStatus::InProgress,
	- line 3116: GuardianAssessmentStatus::Denied,
	- line 3123: async fn guardian_review_does_not_retry_valid_denial() -> anyhow::Result<()> {
	- line 3143: let (session, turn) = guardian_test_session_and_turn(&server).await;
	- line 3144: seed_guardian_parent_history(&session, &turn).await;
	- line 3150: guardian_exec_command_request("shell-valid-denial"),
	- line 3155: assert!(matches!(decision, ReviewDecision::Denied { .. }));
	- line 3161: async fn escalated_retry_bypasses_extension_approval_and_runs_guardian() -> anyhow::Result<()> {
	- line 3173: ) -> codex_extension_api::ExtensionFuture<'a, Option<ReviewDecision>> {
	- line 3174: Box::pin(async move { Some(ReviewDecision::Approved) })
	- line 3196: let (mut session, turn) = guardian_test_session_and_turn(&server).await;
	- line 3203: seed_guardian_parent_history(&session, &turn).await;
	- line 3210: guardian_exec_command_request("shell-escalated-retry"),
	- line 3218: assert!(matches!(decision, ReviewDecision::Denied { .. }));
	- line 3228: async fn guardian_ephemeral_retry_preserves_parallel_trunk_and_fork_history() -> anyhow::Result<()>
	- line 3234: .name("guardian_ephemeral_retry_preserves_parallel_trunk_and_fork_history".to_string())
	- line 3245: "rationale": "first guardian rationale",
	- line 3252: "rationale": "second guardian rationale",
	- line 3259: "rationale": "third guardian rationale",
	- line 3267: ev_response_created("resp-guardian-1"),
	- line 3268: ev_assistant_message("msg-guardian-1", &first_assessment),
	- line 3269: ev_completed("resp-guardian-1"),
	- line 3275: body: sse(vec![ev_response_created("resp-guardian-2")]),
	- line 3280: ev_assistant_message("msg-guardian-2", &second_assessment),
	- line 3281: ev_completed("resp-guardian-2"),
	- line 3288: ev_response_created("resp-guardian-3"),
	- line 3289: ev_assistant_message("msg-guardian-3", "not valid guardian json"),
	- line 3290: ev_completed("resp-guardian-3"),
	- line 3296: ev_response_created("resp-guardian-4"),
	- line 3297: ev_assistant_message("msg-guardian-4", &third_assessment),
	- line 3298: ev_completed("resp-guardian-4"),
	- line 3304: let (session, turn) = guardian_test_session_and_turn_with_base_url(server.uri()).await;
	- line 3309: seed_guardian_parent_history(&session, &turn).await;
	- line 3311: let initial_request = GuardianApprovalRequest::ExecCommand {
	- line 3312: id: "shell-guardian-1".to_string(),
	- line 3324: "review-shell-guardian-1".to_string(),
	- line 3329: ReviewDecision::Approved
	- line 3355: let second_request = GuardianApprovalRequest::ExecCommand {
	- line 3356: id: "shell-guardian-2".to_string(),
	- line 3364: let third_request = GuardianApprovalRequest::ExecCommand {
	- line 3365: id: "shell-guardian-3".to_string(),
	- line 3380: "review-shell-guardian-2".to_string(),
	- line 3401: "second guardian request was not observed"
	- line 3432: "review-shell-guardian-3".to_string(),
	- line 3440: assert_eq!(third_decision, ReviewDecision::Approved);
	- line 3467: "forked guardian review should reuse the trunk guardian prompt cache key"
	- line 3472: "retried ephemeral review should preserve the guardian prompt cache key"
	- line 3476: third_request_body_text.contains("first guardian rationale"),
	- line 3477: "forked guardian review should include the last committed trunk assessment"
	- line 3487: !third_request_body_text.contains("second guardian rationale"),
	- line 3488: "forked guardian review should not include the still in-flight trunk assessment"
	- line 3494: "the trunk guardian review should still be blocked on its gated response"
	- line 3499: .expect("second guardian review gate should still be open");
	- line 3500: assert_eq!(second_review.await?, ReviewDecision::Approved);
	- line 3510: "guardian_ephemeral_retry_preserves_parallel_trunk_and_fork_history thread panicked"
	- line 3515: async fn guardian_review_session_config_preserves_parent_network_proxy() {
	- line 3534: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3541: .expect("guardian config");
	- line 3543: assert_eq!(guardian_config.permissions.network, Some(network));
	- line 3545: guardian_config.model,
	- line 3549: guardian_config.model_reasoning_effort,
	- line 3553: guardian_config.permissions.approval_policy,
	- line 3554: Constrained::allow_only(AskForApproval::Never)
	- line 3557: guardian_config.permissions.permission_profile(),
	- line 3563: async fn guardian_review_session_config_clears_context_overrides_for_distinct_effective_model() {
	- line 3565: let (session, mut turn) = guardian_test_session_and_turn(&server).await;
	- line 3574: let guardian_config = guardian_review_session_config(session.as_ref(), turn.as_ref())
	- line 3576: .expect("guardian config")
	- line 3581: guardian_config.model_context_window,
	- line 3582: guardian_config.model_auto_compact_token_limit,
	- line 3589: async fn guardian_review_session_config_preserves_context_overrides_for_same_effective_model() {
	- line 3591: let (mut session, mut turn) = guardian_test_session_and_turn(&server).await;
	- line 3611: let guardian_config = guardian_review_session_config(session.as_ref(), turn.as_ref())
	- line 3613: .expect("guardian config")
	- line 3618: guardian_config.model_context_window,
	- line 3619: guardian_config.model_auto_compact_token_limit,
	- line 3626: async fn guardian_review_session_config_clears_parent_developer_instructions() {
	- line 3629: Some("parent or managed config should not replace guardian policy".to_string());
	- line 3631: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3638: .expect("guardian config");
	- line 3640: assert_eq!(guardian_config.developer_instructions, None);
	- line 3642: guardian_config.base_instructions,
	- line 3643: Some(guardian_policy_prompt_with_config_and_template(
	- line 3651: async fn guardian_review_session_config_clears_legacy_notify() {
	- line 3658: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3665: .expect("guardian config");
	- line 3667: assert_eq!(guardian_config.notify, None);
	- line 3671: async fn guardian_review_session_config_uses_live_network_proxy_state() {
	- line 3693: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3700: .expect("guardian config");
	- line 3703: guardian_config.permissions.network,
	- line 3716: async fn guardian_review_session_config_disables_mcp_apps_plugins_memories_and_guardian_v2() {
	- line 3734: .enable(Feature::GuardianV2)
	- line 3735: .expect("guardian v2 feature is configurable");
	- line 3740: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3747: .expect("guardian config");
	- line 3749: assert!(guardian_config.mcp_servers.get().is_empty());
	- line 3750: assert!(!guardian_config.features.enabled(Feature::Apps));
	- line 3751: assert!(!guardian_config.features.enabled(Feature::Plugins));
	- line 3752: assert!(!guardian_config.features.enabled(Feature::GuardianV2));
	- line 3753: assert!(!guardian_config.include_apps_instructions);
	- line 3754: assert!(!guardian_config.memories.use_memories);
	- line 3755: assert!(!guardian_config.memories.dedicated_tools);
	- line 3759: async fn guardian_review_session_config_allows_pinned_disabled_feature() {
	- line 3772: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3779: .expect("guardian config should continue when a disabled feature is pinned on");
	- line 3781: assert!(guardian_config.features.enabled(Feature::Collab));
	- line 3782: assert!(guardian_config.mcp_servers.get().is_empty());
	- line 3783: assert!(!guardian_config.include_apps_instructions);
	- line 3787: async fn guardian_review_session_config_uses_parent_active_model_instead_of_hardcoded_slug() {
	- line 3791: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3798: .expect("guardian config");
	- line 3800: assert_eq!(guardian_config.model, Some("active-model".to_string()));
	- line 3804: async fn guardian_review_session_config_keeps_bedrock_provider_for_bedrock_gpt_5_4() {
	- line 3810: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3817: .expect("guardian config");
	- line 3825: guardian_config.model,
	- line 3826: guardian_config.model_provider_id,
	- line 3827: guardian_config.model_provider,
	- line 3838: async fn guardian_review_session_config_uses_requirements_guardian_policy_config() {
	- line 3845: guardian_policy_config: Some(
	- line 3846: "  Use the workspace-managed guardian policy.  ".to_string(),
	- line 3865: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3872: .expect("guardian config");
	- line 3874: assert_eq!(guardian_config.developer_instructions, None);
	- line 3876: guardian_config.base_instructions,
	- line 3877: Some(guardian_policy_prompt_with_config_and_template(
	- line 3878: "Use the workspace-managed guardian policy.",
	- line 3885: async fn guardian_review_session_config_uses_default_guardian_policy_without_requirements_override()
	- line 3905: let guardian_config = build_guardian_review_session_config_for_test(
	- line 3912: .expect("guardian config");
	- line 3914: assert_eq!(guardian_config.developer_instructions, None);
	- line 3916: guardian_config.base_instructions,
	- line 3917: Some(guardian_policy_prompt_with_config_and_template(


codex-rs/core/src/guardian/review.rs (311 lines):
	- line 1: use codex_analytics::GuardianApprovalRequestSource;
	- line 2: use codex_analytics::GuardianReviewAnalyticsResult;
	- line 3: use codex_analytics::GuardianReviewDecision;
	- line 4: use codex_analytics::GuardianReviewFailureReason;
	- line 5: use codex_analytics::GuardianReviewTerminalStatus;
	- line 6: use codex_analytics::GuardianReviewTrackContext;
	- line 7: use codex_analytics::GuardianReviewedAction;
	- line 15: use codex_protocol::protocol::AskForApproval;
	- line 18: use codex_protocol::protocol::GuardianAssessmentDecisionSource;
	- line 19: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 20: use codex_protocol::protocol::GuardianAssessmentStatus;
	- line 21: use codex_protocol::protocol::GuardianRiskLevel;
	- line 22: use codex_protocol::protocol::GuardianUserAuthorization;
	- line 24: use codex_protocol::protocol::ReviewDecision;
	- line 36: use crate::context::GuardianReviewEvidence;
	- line 46: use super::GuardianApprovalRequest;
	- line 47: use super::GuardianAssessment;
	- line 48: use super::GuardianAssessmentOutcome;
	- line 49: use super::GuardianRejectionCircuitBreakerAction;
	- line 50: use super::GuardianRejectionCircuitBreakerPolicy;
	- line 51: use super::GuardianReviewContext;
	- line 52: use super::approval_request::format_guardian_action_pretty;
	- line 53: use super::approval_request::guardian_approval_request_to_json;
	- line 54: use super::approval_request::guardian_assessment_action;
	- line 55: use super::approval_request::guardian_request_target_item_id;
	- line 56: use super::approval_request::guardian_request_turn_id;
	- line 57: use super::approval_request::guardian_reviewed_action;
	- line 58: use super::metrics::emit_guardian_review_metrics;
	- line 59: use super::prompt::guardian_output_schema;
	- line 60: use super::prompt::parse_guardian_assessment;
	- line 61: use super::review_session::GuardianReviewSessionOutcome;
	- line 62: use super::review_session::GuardianReviewSessionParams;
	- line 63: use super::review_session::build_guardian_review_session_config;
	- line 81: fn plugin_attribution_for_guardian_request(
	- line 83: request: &GuardianApprovalRequest,
	- line 86: GuardianApprovalRequest::ExecCommand { command, cwd, .. } => {
	- line 90: GuardianApprovalRequest::Execve {
	- line 106: pub(crate) fn new_guardian_review_id() -> String {
	- line 110: pub(crate) fn guardian_timeout_message(model_info: &ModelInfo) -> String {
	- line 121: pub(super) enum GuardianReviewOutcome {
	- line 122: Completed(GuardianAssessment),
	- line 123: Error(GuardianReviewError),
	- line 127: pub(super) enum GuardianReviewError {
	- line 142: impl GuardianReviewError {
	- line 169: fn failure_reason(&self) -> GuardianReviewFailureReason {
	- line 171: Self::PromptBuild { .. } => GuardianReviewFailureReason::PromptBuildError,
	- line 172: Self::Session { .. } => GuardianReviewFailureReason::SessionError,
	- line 173: Self::Parse { .. } => GuardianReviewFailureReason::ParseError,
	- line 174: Self::Timeout => GuardianReviewFailureReason::Timeout,
	- line 175: Self::Cancelled => GuardianReviewFailureReason::Cancelled,
	- line 180: fn guardian_risk_level_str(level: GuardianRiskLevel) -> &'static str {
	- line 182: GuardianRiskLevel::Low => "low",
	- line 183: GuardianRiskLevel::Medium => "medium",
	- line 184: GuardianRiskLevel::High => "high",
	- line 185: GuardianRiskLevel::Critical => "critical",
	- line 189: /// Whether this turn should route allowed approval prompts through the guardian
	- line 192: pub(crate) fn routes_approval_to_guardian(turn: &TurnContext) -> bool {
	- line 193: routes_approval_to_guardian_with_reviewer(turn, turn.config.approvals_reviewer)
	- line 196: /// Whether an approval with its own reviewer selection should be routed through guardian.
	- line 197: pub(crate) fn routes_approval_to_guardian_with_reviewer(
	- line 201: routes_approval_policy_to_guardian(turn.approval_policy(), approvals_reviewer)
	- line 204: /// Whether an exact approval policy and reviewer should route through Guardian.
	- line 205: pub(crate) fn routes_approval_policy_to_guardian(
	- line 206: approval_policy: AskForApproval,
	- line 210: approval_policy,
	- line 211: AskForApproval::OnRequest | AskForApproval::Granular(_)
	- line 218: SessionSource::Internal(InternalSessionSource::Guardian) => true,
	- line 223: fn track_guardian_review(
	- line 225: tracking: &GuardianReviewTrackContext,
	- line 226: approval_request_source: GuardianApprovalRequestSource,
	- line 227: reviewed_action: &GuardianReviewedAction,
	- line 228: result: GuardianReviewAnalyticsResult,
	- line 231: emit_guardian_review_metrics(
	- line 241: .track_guardian_review(tracking, result, completed_at_ms);
	- line 244: async fn record_guardian_non_denial(session: &Arc<Session>, turn_id: &str) {
	- line 247: .guardian_rejection_circuit_breaker
	- line 253: async fn record_guardian_denial(session: &Arc<Session>, turn: &Arc<TurnContext>, turn_id: &str) {
	- line 255: GuardianRejectionCircuitBreakerPolicy::CyberModel
	- line 257: GuardianRejectionCircuitBreakerPolicy::Standard
	- line 261: .guardian_rejection_circuit_breaker
	- line 265: let GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 280: EventMsg::GuardianWarning(WarningEvent {
	- line 296: // Guardian aborts bypass normal task completion, so emit its idle lifecycle here.
	- line 306: pub(crate) async fn record_guardian_denial_for_test(
	- line 311: record_guardian_denial(session, turn, turn_id).await;
	- line 314: /// Runs Guardian unless an installed extension explicitly claims the review.
	- line 315: /// Guardian timeouts, review-session failures, and parse failures all block
	- line 317: async fn run_guardian_review(
	- line 319: context: GuardianReviewContext,
	- line 321: request: GuardianApprovalRequest,
	- line 323: options: GuardianReviewOptions,
	- line 324: ) -> ReviewDecision {
	- line 330: GuardianApprovalRequest::ExecCommand {
	- line 335: // Guardian V2 may satisfy ordinary reviews, including required-model reviews, but broader
	- line 343: || turn.config.features.enabled(Feature::GuardianV2))
	- line 349: && let Ok(action) = guardian_approval_request_to_json(&request)
	- line 363: if decision == ReviewDecision::Approved {
	- line 364: record_guardian_non_denial(&session, guardian_request_turn_id(&request, &turn.sub_id))
	- line 370: let GuardianReviewOptions {
	- line 376: let target_item_id = guardian_request_target_item_id(&request).map(str::to_string);
	- line 377: let assessment_turn_id = guardian_request_turn_id(&request, &turn.sub_id).to_string();
	- line 379: .or_else(|| plugin_attribution_for_guardian_request(turn.as_ref(), &request));
	- line 384: let action_summary = guardian_assessment_action(&request);
	- line 385: let reviewed_action = guardian_reviewed_action(&request);
	- line 386: let review_tracking = GuardianReviewTrackContext::new(
	- line 399: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 407: status: GuardianAssessmentStatus::InProgress,
	- line 422: track_guardian_review(
	- line 427: GuardianReviewAnalyticsResult {
	- line 428: decision: GuardianReviewDecision::Aborted,
	- line 429: terminal_status: GuardianReviewTerminalStatus::Aborted,
	- line 430: failure_reason: Some(GuardianReviewFailureReason::Cancelled),
	- line 431: ..GuardianReviewAnalyticsResult::without_session()
	- line 438: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 446: status: GuardianAssessmentStatus::Aborted,
	- line 450: decision_source: Some(GuardianAssessmentDecisionSource::Agent),
	- line 455: record_guardian_non_denial(&session, &assessment_turn_id).await;
	- line 456: return ReviewDecision::Abort;
	- line 459: let schema = guardian_output_schema();
	- line 464: .get::<GuardianReviewEvidence>()
	- line 476: format_guardian_action_pretty(&request).ok().map(|action| {
	- line 487: let (outcome, analytics_result) = Box::pin(run_guardian_review_session_with_retry(
	- line 499: let completed_review = matches!(&outcome, GuardianReviewOutcome::Completed(_));
	- line 501: GuardianReviewOutcome::Completed(assessment) => {
	- line 502: let approved = matches!(assessment.outcome, GuardianAssessmentOutcome::Allow);
	- line 503: track_guardian_review(
	- line 508: GuardianReviewAnalyticsResult {
	- line 510: GuardianReviewDecision::Approved
	- line 512: GuardianReviewDecision::Denied
	- line 515: GuardianReviewTerminalStatus::Approved
	- line 517: GuardianReviewTerminalStatus::Denied
	- line 528: matches!(assessment.outcome, GuardianAssessmentOutcome::Deny);
	- line 531: GuardianReviewOutcome::Error(error) => match error {
	- line 532: GuardianReviewError::Timeout => {
	- line 536: track_guardian_review(
	- line 541: GuardianReviewAnalyticsResult {
	- line 542: decision: GuardianReviewDecision::Denied,
	- line 543: terminal_status: GuardianReviewTerminalStatus::TimedOut,
	- line 552: EventMsg::GuardianWarning(WarningEvent {
	- line 560: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 568: status: GuardianAssessmentStatus::TimedOut,
	- line 572: decision_source: Some(GuardianAssessmentDecisionSource::Agent),
	- line 577: record_guardian_non_denial(&session, &assessment_turn_id).await;
	- line 578: return ReviewDecision::TimedOut;
	- line 580: GuardianReviewError::Cancelled => {
	- line 581: track_guardian_review(
	- line 586: GuardianReviewAnalyticsResult {
	- line 587: decision: GuardianReviewDecision::Aborted,
	- line 588: terminal_status: GuardianReviewTerminalStatus::Aborted,
	- line 597: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 605: status: GuardianAssessmentStatus::Aborted,
	- line 609: decision_source: Some(GuardianAssessmentDecisionSource::Agent),
	- line 614: record_guardian_non_denial(&session, &assessment_turn_id).await;
	- line 615: return ReviewDecision::Abort;
	- line 617: GuardianReviewError::PromptBuild { .. }
	- line 618: | GuardianReviewError::Session { .. }
	- line 619: | GuardianReviewError::Parse { .. } => {
	- line 621: GuardianReviewError::PromptBuild { message }
	- line 622: | GuardianReviewError::Session { message, .. }
	- line 623: | GuardianReviewError::Parse { message } => message,
	- line 624: GuardianReviewError::Timeout | GuardianReviewError::Cancelled => {
	- line 625: "guardian review failed"
	- line 629: track_guardian_review(
	- line 634: GuardianReviewAnalyticsResult {
	- line 635: decision: GuardianReviewDecision::Denied,
	- line 636: terminal_status: GuardianReviewTerminalStatus::FailedClosed,
	- line 643: GuardianAssessment {
	- line 644: risk_level: GuardianRiskLevel::High,
	- line 645: user_authorization: GuardianUserAuthorization::Unknown,
	- line 646: outcome: GuardianAssessmentOutcome::Deny,
	- line 656: GuardianAssessmentOutcome::Allow => true,
	- line 657: GuardianAssessmentOutcome::Deny => false,
	- line 661: GuardianUserAuthorization::Unknown => "unknown",
	- line 662: GuardianUserAuthorization::Low => "low",
	- line 663: GuardianUserAuthorization::Medium => "medium",
	- line 664: GuardianUserAuthorization::High => "high",
	- line 668: guardian_risk_level_str(assessment.risk_level),
	- line 674: EventMsg::GuardianWarning(WarningEvent { message: warning }),
	- line 678: GuardianAssessmentStatus::Approved
	- line 680: GuardianAssessmentStatus::Denied
	- line 682: let assessment_event = GuardianAssessmentEvent {
	- line 694: decision_source: Some(GuardianAssessmentDecisionSource::Agent),
	- line 711: EventMsg::GuardianAssessment(assessment_event),
	- line 716: record_guardian_denial(&session, &turn, &assessment_turn_id).await;
	- line 718: record_guardian_non_denial(&session, &assessment_turn_id).await;
	- line 722: ReviewDecision::Approved
	- line 736: ReviewDecision::denied(format!(
	- line 742: pub(crate) struct GuardianReviewOptions {
	- line 744: pub(crate) approval_request_source: GuardianApprovalRequestSource,
	- line 746: /// Escalate from extension fast approval to the synchronous Guardian reviewer.
	- line 750: /// Public entrypoint for approval requests that should be reviewed by guardian.
	- line 753: context: impl Into<GuardianReviewContext>,
	- line 755: request: GuardianApprovalRequest,
	- line 757: ) -> ReviewDecision {
	- line 759: let review: BoxFuture<'_, ReviewDecision> = Box::pin(run_guardian_review(
	- line 765: GuardianReviewOptions {
	- line 767: approval_request_source: GuardianApprovalRequestSource::MainTurn,
	- line 777: context: impl Into<GuardianReviewContext>,
	- line 779: request: GuardianApprovalRequest,
	- line 781: options: GuardianReviewOptions,
	- line 782: ) -> ReviewDecision {
	- line 783: run_guardian_review(
	- line 799: context: impl Into<GuardianReviewContext>,
	- line 801: request: GuardianApprovalRequest,
	- line 803: options: GuardianReviewOptions,
	- line 804: ) -> oneshot::Receiver<ReviewDecision> {
	- line 812: let decision = runtime.block_on(run_guardian_review(
	- line 823: pub(super) struct GuardianReviewSessionConfig {
	- line 833: pub(super) async fn guardian_review_session_config(
	- line 836: ) -> anyhow::Result<GuardianReviewSessionConfig> {
	- line 863: let guardian_catalog_contains_auto_review = available_models
	- line 866: let guardian_review_model_overridden = model_override.is_some();
	- line 867: let guardian_review_model_override = model_override.map(str::to_string);
	- line 868: let (guardian_model, guardian_reasoning_effort) = if let Some(preset) = review_model {
	- line 895: let guardian_model_info = session
	- line 899: guardian_model.as_str(),
	- line 903: let mut spawn_config = build_guardian_review_session_config(
	- line 906: guardian_model.as_str(),
	- line 907: guardian_reasoning_effort.clone(),
	- line 908: guardian_model_info.model_messages.as_ref(),
	- line 916: "guardian review session could not preserve REPL developer policy: {error}"
	- line 920: if guardian_model != turn.model_info().slug {
	- line 924: Ok(GuardianReviewSessionConfig {
	- line 926: model: guardian_model,
	- line 927: reasoning_effort: guardian_reasoning_effort,
	- line 929: catalog_contains_auto_review: guardian_catalog_contains_auto_review,
	- line 930: model_overridden: guardian_review_model_overridden,
	- line 931: model_override: guardian_review_model_override,
	- line 935: /// Runs the guardian in a locked-down reusable review session.
	- line 937: /// The guardian itself should not mutate state or trigger further approvals, so
	- line 938: /// it is pinned to a read-only sandbox with `approval_policy = never` and
	- line 940: /// later approvals append onto that same guardian conversation to preserve a
	- line 945: /// must continue to preserve the guardian policy as exact top-level developer
	- line 949: async fn run_guardian_review_session_before_deadline(
	- line 951: context: GuardianReviewContext,
	- line 952: request: GuardianApprovalRequest,
	- line 957: ) -> (GuardianReviewOutcome, GuardianReviewAnalyticsResult) {
	- line 959: let session_config = match guardian_review_session_config(session.as_ref(), turn.as_ref()).await
	- line 964: GuardianReviewOutcome::Error(GuardianReviewError::prompt_build(err)),
	- line 965: GuardianReviewAnalyticsResult::without_session(),
	- line 971: .guardian_review_session
	- line 972: .run_review(GuardianReviewSessionParams {
	- line 981: guardian_default_review_model_id: session_config.default_review_model_id,
	- line 982: guardian_catalog_contains_auto_review: session_config.catalog_contains_auto_review,
	- line 983: guardian_review_model_overridden: session_config.model_overridden,
	- line 984: guardian_review_model_override: session_config.model_override,
	- line 994: GuardianReviewSessionOutcome::Completed(Ok(last_agent_message)) => match last_agent_message
	- line 997: match parse_guardian_assessment(Some(&last_agent_message)) {
	- line 999: GuardianReviewOutcome::Completed(assessment),
	- line 1003: GuardianReviewOutcome::Error(GuardianReviewError::parse(err)),
	- line 1009: GuardianReviewOutcome::Error(GuardianReviewError::session(anyhow::anyhow!(
	- line 1010: "guardian review completed without an assessment payload"
	- line 1015: GuardianReviewSessionOutcome::Completed(Err(err)) => (
	- line 1016: GuardianReviewOutcome::Error(GuardianReviewError::session(err)),
	- line 1019: GuardianReviewSessionOutcome::PromptBuildFailed(err) => (
	- line 1020: GuardianReviewOutcome::Error(GuardianReviewError::prompt_build(err)),
	- line 1023: GuardianReviewSessionOutcome::SessionFailed { error, error_info } => {
	- line 1025: Some(error_info) => GuardianReviewError::session_with_error_info(error, error_info),
	- line 1026: None => GuardianReviewError::session(error),
	- line 1029: GuardianReviewOutcome::Error(error),
	- line 1033: GuardianReviewSessionOutcome::TimedOut => (
	- line 1034: GuardianReviewOutcome::Error(GuardianReviewError::Timeout),
	- line 1037: GuardianReviewSessionOutcome::Aborted => (
	- line 1038: GuardianReviewOutcome::Error(GuardianReviewError::Cancelled),
	- line 1044: pub(super) async fn run_guardian_review_session_with_retry(
	- line 1046: context: impl Into<GuardianReviewContext>,
	- line 1047: request: GuardianApprovalRequest,
	- line 1052: ) -> (GuardianReviewOutcome, GuardianReviewAnalyticsResult) {
	- line 1054: assert!(max_attempts > 0, "guardian review must run at least once");
	- line 1058: let (outcome, mut analytics_result) = run_guardian_review_session_before_deadline(
	- line 1069: if attempt_count >= max_attempts || !should_retry_guardian_review(&outcome) {
	- line 1073: wait_before_guardian_retry(attempt_count, deadline, external_cancel.as_ref()).await
	- line 1075: return (GuardianReviewOutcome::Error(error), analytics_result);
	- line 1081: async fn wait_before_guardian_retry(
	- line 1085: ) -> Option<GuardianReviewError> {
	- line 1090: (Instant::now() >= deadline).then_some(GuardianReviewError::Timeout)
	- line 1098: } => Some(GuardianReviewError::Cancelled),
	- line 1102: fn should_retry_guardian_review(outcome: &GuardianReviewOutcome) -> bool {
	- line 1105: GuardianReviewOutcome::Error(
	- line 1106: GuardianReviewError::Session {
	- line 1115: } | GuardianReviewError::Parse { .. }
	- line 1126: fn guardian_review_error_reason_distinguishes_error_kinds() {
	- line 1127: let parse_error = GuardianReviewError::parse(anyhow::anyhow!("bad guardian JSON"));
	- line 1128: let prompt_error = GuardianReviewError::prompt_build(anyhow::anyhow!("bad prompt/config"));
	- line 1130: GuardianReviewError::session(anyhow::anyhow!("guardian runtime failed"));
	- line 1131: let structured_session_error = GuardianReviewError::session_with_error_info(
	- line 1132: anyhow::anyhow!("temporary guardian failure"),
	- line 1138: GuardianReviewFailureReason::ParseError
	- line 1142: GuardianReviewFailureReason::PromptBuildError
	- line 1146: GuardianReviewFailureReason::SessionError
	- line 1150: GuardianReviewFailureReason::SessionError
	- line 1155: fn guardian_review_retry_only_retries_transient_session_and_parse_errors() {
	- line 1156: let assessment = GuardianAssessment {
	- line 1157: risk_level: GuardianRiskLevel::High,
	- line 1158: user_authorization: GuardianUserAuthorization::Unknown,
	- line 1159: outcome: GuardianAssessmentOutcome::Deny,
	- line 1179: GuardianReviewOutcome::Error(GuardianReviewError::session_with_error_info(
	- line 1188: (GuardianReviewOutcome::Completed(assessment), false),
	- line 1190: GuardianReviewOutcome::Error(GuardianReviewError::prompt_build(anyhow::anyhow!(
	- line 1196: GuardianReviewOutcome::Error(GuardianReviewError::session(anyhow::anyhow!(
	- line 1202: GuardianReviewOutcome::Error(GuardianReviewError::session_with_error_info(
	- line 1209: GuardianReviewOutcome::Error(GuardianReviewError::parse(anyhow::anyhow!("parse"))),
	- line 1213: GuardianReviewOutcome::Error(GuardianReviewError::Timeout),
	- line 1217: GuardianReviewOutcome::Error(GuardianReviewError::Cancelled),
	- line 1223: assert_eq!(should_retry_guardian_review(&outcome), expected);
	- line 1228: async fn guardian_review_retry_wait_honors_cancellation() {
	- line 1232: let error = wait_before_guardian_retry(
	- line 1239: assert!(matches!(error, Some(GuardianReviewError::Cancelled)));
	- line 1243: async fn guardian_review_retry_wait_honors_deadline() {
	- line 1244: let error = wait_before_guardian_retry(
	- line 1251: assert!(matches!(error, Some(GuardianReviewError::Timeout)));


codex-rs/core/src/guardian/review_session.rs (198 lines):
	- line 9: use codex_analytics::GuardianReviewAnalyticsResult;
	- line 10: use codex_analytics::GuardianReviewSessionAnalyticsParams;
	- line 11: use codex_analytics::GuardianReviewSessionKind;
	- line 31: use codex_protocol::protocol::AskForApproval;
	- line 55: use crate::context::GuardianFollowupReviewReminder;
	- line 56: use crate::context::GuardianNodeReplPolicy;
	- line 80: use super::GuardianApprovalRequest;
	- line 81: use super::GuardianReviewContext;
	- line 86: use super::prompt::GuardianPromptMode;
	- line 87: use super::prompt::GuardianTranscriptCursor;
	- line 88: use super::prompt::build_guardian_prompt_items_with_parent_turn;
	- line 89: use super::prompt::guardian_policy_prompt_with_config_and_template;
	- line 90: use super::review::guardian_review_session_config;
	- line 95: pub(crate) enum GuardianReviewSessionOutcome {
	- line 106: pub(crate) struct GuardianReviewSessionParams {
	- line 108: pub(crate) parent_context: GuardianReviewContext,
	- line 110: pub(crate) request: GuardianApprovalRequest,
	- line 115: pub(crate) guardian_default_review_model_id: String,
	- line 116: pub(crate) guardian_catalog_contains_auto_review: bool,
	- line 117: pub(crate) guardian_review_model_overridden: bool,
	- line 118: pub(crate) guardian_review_model_override: Option<String>,
	- line 126: pub(crate) struct GuardianReviewSessionManager {
	- line 127: state: Arc<Mutex<GuardianReviewSessionState>>,
	- line 132: struct GuardianReviewSessionState {
	- line 133: trunk: Option<Arc<GuardianReviewSession>>,
	- line 134: ephemeral_reviews: Vec<Arc<GuardianReviewSession>>,
	- line 137: struct GuardianReviewSession {
	- line 141: reuse_key: GuardianReviewSessionReuseKey,
	- line 143: state: Mutex<GuardianReviewState>,
	- line 146: struct GuardianReviewState {
	- line 148: last_reviewed_transcript_cursor: Option<GuardianTranscriptCursor>,
	- line 151: last_committed_fork_snapshot: Option<GuardianReviewForkSnapshot>,
	- line 159: fn had_prior_review_context(prompt_mode: &GuardianPromptMode) -> bool {
	- line 160: matches!(prompt_mode, GuardianPromptMode::Delta { .. })
	- line 178: state: Arc<Mutex<GuardianReviewSessionState>>,
	- line 179: review_session: Option<Arc<GuardianReviewSession>>,
	- line 183: struct GuardianReviewForkSnapshot {
	- line 186: last_reviewed_transcript_cursor: Option<GuardianTranscriptCursor>,
	- line 191: struct GuardianReviewSessionReuseKey {
	- line 218: impl GuardianReviewSessionReuseKey {
	- line 227: .enabled(Feature::GuardianReuseParentCompaction)
	- line 310: Some(format!("guardian:{parent_thread_id}"))
	- line 313: impl GuardianReviewSession {
	- line 326: async fn fork_snapshot(&self) -> Option<GuardianReviewForkSnapshot> {
	- line 338: state.last_committed_fork_snapshot = Some(GuardianReviewForkSnapshot {
	- line 348: warn!("failed to refresh guardian trunk rollout snapshot: {err}");
	- line 379: state: Arc<Mutex<GuardianReviewSessionState>>,
	- line 380: review_session: Arc<GuardianReviewSession>,
	- line 415: impl GuardianReviewSessionManager {
	- line 421: // Boxing breaks the Session::new -> Guardian -> Session::new future recursion.
	- line 423: let spawn_config = guardian_review_session_config(&parent_session, &parent_turn)
	- line 429: .enabled(Feature::GuardianReuseParentCompaction)
	- line 432: let parent_context = GuardianReviewContext::from(parent_turn);
	- line 433: let reuse_key = GuardianReviewSessionReuseKey::from_spawn_config(
	- line 447: let review_session = spawn_guardian_review_session(
	- line 477: warn!("failed to resolve guardian trunk rollout path: {err}");
	- line 512: params: GuardianReviewSessionParams,
	- line 513: ) -> (GuardianReviewSessionOutcome, GuardianReviewAnalyticsResult) {
	- line 519: .enabled(Feature::GuardianReuseParentCompaction)
	- line 522: let mut next_reuse_key = GuardianReviewSessionReuseKey::from_spawn_config(
	- line 565: Box::pin(spawn_guardian_review_session(
	- line 580: GuardianReviewSessionOutcome::PromptBuildFailed(err),
	- line 581: GuardianReviewAnalyticsResult::without_session(),
	- line 585: return (outcome, GuardianReviewAnalyticsResult::without_session());
	- line 595: return (outcome, GuardianReviewAnalyticsResult::without_session());
	- line 601: GuardianReviewSessionOutcome::Completed(Err(anyhow!(
	- line 602: "guardian review session was not available after spawn"
	- line 604: GuardianReviewAnalyticsResult::without_session(),
	- line 633: let guardian_session_kind = if spawned_trunk {
	- line 634: GuardianReviewSessionKind::TrunkNew
	- line 636: GuardianReviewSessionKind::TrunkReused
	- line 641: guardian_session_kind,
	- line 645: if keep_review_session && matches!(outcome, GuardianReviewSessionOutcome::Completed(_)) {
	- line 662: let reuse_key = GuardianReviewSessionReuseKey::from_spawn_config(
	- line 667: self.state.lock().await.trunk = Some(Arc::new(GuardianReviewSession {
	- line 673: state: Mutex::new(GuardianReviewState {
	- line 685: let reuse_key = GuardianReviewSessionReuseKey::from_spawn_config(
	- line 694: .push(Arc::new(GuardianReviewSession {
	- line 700: state: Mutex::new(GuardianReviewState {
	- line 729: .expect("guardian trunk should exist");
	- line 735: trunk: &Arc<GuardianReviewSession>,
	- line 736: ) -> Option<Arc<GuardianReviewSession>> {
	- line 749: async fn register_active_ephemeral(&self, review_session: Arc<GuardianReviewSession>) {
	- line 759: review_session: &Arc<GuardianReviewSession>,
	- line 760: ) -> Option<Arc<GuardianReviewSession>> {
	- line 771: params: GuardianReviewSessionParams,
	- line 772: reuse_key: GuardianReviewSessionReuseKey,
	- line 775: fork_snapshot: Option<GuardianReviewForkSnapshot>,
	- line 776: ) -> (GuardianReviewSessionOutcome, GuardianReviewAnalyticsResult) {
	- line 784: Box::pin(spawn_guardian_review_session(
	- line 799: GuardianReviewSessionOutcome::PromptBuildFailed(err),
	- line 800: GuardianReviewAnalyticsResult::without_session(),
	- line 804: return (outcome, GuardianReviewAnalyticsResult::without_session());
	- line 815: GuardianReviewSessionKind::EphemeralForked,
	- line 827: async fn spawn_guardian_review_session(
	- line 829: parent_context: &GuardianReviewContext,
	- line 831: reuse_key: GuardianReviewSessionReuseKey,
	- line 834: fork_snapshot: Option<GuardianReviewForkSnapshot>,
	- line 835: ) -> anyhow::Result<GuardianReviewSession> {
	- line 871: Ok(GuardianReviewSession {
	- line 877: state: Mutex::new(GuardianReviewState {
	- line 888: review_session: &GuardianReviewSession,
	- line 889: params: &GuardianReviewSessionParams,
	- line 890: guardian_session_kind: GuardianReviewSessionKind,
	- line 893: GuardianReviewSessionOutcome,
	- line 895: GuardianReviewAnalyticsResult,
	- line 906: let guardian_reasoning_effort = params
	- line 918: GuardianReviewAnalyticsResult::from_session(GuardianReviewSessionAnalyticsParams {
	- line 919: guardian_thread_id: review_session.session.thread_id().to_string(),
	- line 920: guardian_session_kind,
	- line 921: guardian_model: params.model.clone(),
	- line 922: guardian_reasoning_effort: guardian_reasoning_effort.map(|effort| effort.to_string()),
	- line 923: guardian_default_review_model_id: params.guardian_default_review_model_id.clone(),
	- line 924: guardian_catalog_contains_auto_review: params.guardian_catalog_contains_auto_review,
	- line 925: guardian_review_model_overridden: params.guardian_review_model_overridden,
	- line 926: guardian_review_model_override: params.guardian_review_model_override.clone(),
	- line 927: guardian_model_provider_id: params.spawn_config.model_provider_id.clone(),
	- line 931: ensure_guardian_followup_reminder(review_session).await;
	- line 937: Box::pin(ensure_guardian_node_repl_policy(review_session, params)),
	- line 944: GuardianReviewSessionOutcome::SessionFailed {
	- line 975: GuardianReviewSessionOutcome::SessionFailed {
	- line 985: let (outcome, keep_review_session, _) = wait_for_guardian_review(
	- line 993: if !matches!(outcome, GuardianReviewSessionOutcome::Completed(Ok(_))) {
	- line 998: ensure_guardian_followup_reminder(review_session).await;
	- line 1024: .map_or(GuardianPromptMode::Full, |cursor| {
	- line 1025: GuardianPromptMode::Delta { cursor }
	- line 1042: let mut prompt_items = build_guardian_prompt_items_with_parent_turn(
	- line 1146: GuardianReviewSessionOutcome::PromptBuildFailed(err),
	- line 1162: let guardian_permission_snapshot = params
	- line 1167: // Guardian must receive read-only permissions for every inherited environment.
	- line 1176: PermissionProfileSnapshot::legacy(read_only_guardian_permission_profile(
	- line 1183: // TODO(anp): Migrate guardian review thread settings to a PathUri fallback cwd so foreign
	- line 1200: approval_policy: Some(AskForApproval::Never),
	- line 1202: permission_profile: Some(guardian_permission_snapshot.permission_profile().clone()),
	- line 1234: GuardianReviewSessionOutcome::SessionFailed {
	- line 1235: error: anyhow!("guardian review input was not started: {submission:?}"),
	- line 1244: GuardianReviewSessionOutcome::SessionFailed {
	- line 1263: let outcome = wait_for_guardian_review(
	- line 1271: if matches!(outcome.0, GuardianReviewSessionOutcome::Completed(_)) {
	- line 1287: async fn ensure_guardian_followup_reminder(review_session: &GuardianReviewSession) {
	- line 1288: let followup_reminder = GuardianFollowupReviewReminder.body();
	- line 1306: let reminder: ResponseItem = ContextualUserFragment::into(GuardianFollowupReviewReminder);
	- line 1313: async fn ensure_guardian_node_repl_policy(
	- line 1314: review_session: &GuardianReviewSession,
	- line 1315: params: &GuardianReviewSessionParams,
	- line 1324: GuardianApprovalRequest::McpToolCall { server, tool_name, .. }
	- line 1331: let policy = GuardianNodeReplPolicy;
	- line 1386: let live_thread = session.live_thread_for_persistence("guardian review fork")?;
	- line 1391: async fn wait_for_guardian_review(
	- line 1392: review_session: &GuardianReviewSession,
	- line 1396: analytics_result: &mut GuardianReviewAnalyticsResult,
	- line 1397: ) -> (GuardianReviewSessionOutcome, bool, bool) {
	- line 1411: return (GuardianReviewSessionOutcome::TimedOut, keep_review_session, false);
	- line 1426: return (GuardianReviewSessionOutcome::Aborted, keep_review_session, false);
	- line 1443: GuardianReviewSessionOutcome::SessionFailed {
	- line 1452: GuardianReviewSessionOutcome::Completed(Ok(turn_complete.last_agent_message)),
	- line 1461: return (GuardianReviewSessionOutcome::Aborted, true, false);
	- line 1467: GuardianReviewSessionOutcome::Completed(Err(err.into())),
	- line 1492: fn read_only_guardian_permission_profile(
	- line 1502: pub(crate) fn build_guardian_review_session_config(
	- line 1509: let mut guardian_config = parent_config.clone();
	- line 1510: guardian_config.model = Some(active_model.to_string());
	- line 1511: guardian_config.model_reasoning_effort = reasoning_effort;
	- line 1512: guardian_config.model_provider.request_max_retries = Some(1);
	- line 1513: guardian_config.model_provider.stream_max_retries = Some(1);
	- line 1514: guardian_config.include_skill_instructions = false;
	- line 1515: guardian_config.memories.use_memories = false;
	- line 1516: guardian_config.memories.dedicated_tools = false;
	- line 1518: let tenant_policy_config = parent_config.resolve_guardian_policy(model_messages);
	- line 1522: guardian_config.base_instructions = Some(guardian_policy_prompt_with_config_and_template(
	- line 1526: guardian_config.base_instructions_provenance = Some(BaseInstructionsProvenance::Custom);
	- line 1527: guardian_config.notify = None;
	- line 1528: guardian_config.developer_instructions = None;
	- line 1529: guardian_config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);
	- line 1530: let guardian_permission_profile =
	- line 1531: read_only_guardian_permission_profile(parent_config.permissions.permission_profile());
	- line 1532: guardian_config
	- line 1534: .set_permission_profile(guardian_permission_profile)
	- line 1536: anyhow::anyhow!("guardian review session could not set permission profile: {err}")
	- line 1538: guardian_config.include_apps_instructions = false;
	- line 1539: guardian_config
	- line 1543: anyhow::anyhow!("guardian review session could not clear MCP servers: {err}")
	- line 1546: && guardian_config.permissions.network.is_some()
	- line 1548: let network_constraints = guardian_config
	- line 1554: guardian_config.permissions.network = Some(NetworkProxySpec::from_config_and_constraints(
	- line 1557: guardian_config.permissions.permission_profile(),
	- line 1563: Feature::GuardianV2,
	- line 1570: guardian_config.features.disable(feature).map_err(|err| {
	- line 1572: "guardian review session could not disable `features.{}`: {err}",
	- line 1576: if guardian_config.features.enabled(feature) {
	- line 1578: "guardian review session could not disable `features.{}`; continuing with the feature enabled",
	- line 1583: Ok(guardian_config)
	- line 1590: ) -> Result<T, GuardianReviewSessionOutcome> {
	- line 1592: _ = tokio::time::sleep_until(deadline) => Err(GuardianReviewSessionOutcome::TimedOut),
	- line 1600: } => Err(GuardianReviewSessionOutcome::Aborted),
	- line 1609: ) -> Result<T, GuardianReviewSessionOutcome> {
	- line 1618: review_session: &GuardianReviewSession,
	- line 1639: .map_err(|_| anyhow!("timed out draining guardian review session after interrupt"))??;


codex-rs/app-server/src/bespoke_event_handling.rs (152 lines):
	- line 30: use codex_app_server_protocol::ExecPolicyAmendment as V2ExecPolicyAmendment;
	- line 35: use codex_app_server_protocol::GuardianWarningNotification;
	- line 90: use codex_app_server_protocol::build_item_from_guardian_event;
	- line 91: use codex_app_server_protocol::guardian_auto_approval_review_notification;
	- line 96: use codex_guardian_v2::StrictReviewReason;
	- line 108: use codex_protocol::protocol::ReviewDecision;
	- line 291: EventMsg::GuardianWarning(warning_event) => {
	- line 292: let notification = GuardianWarningNotification {
	- line 297: .send_server_notification(ServerNotification::GuardianWarning(notification))
	- line 300: EventMsg::GuardianAssessment(assessment) => {
	- line 301: let pending_command_execution = match build_item_from_guardian_event(
	- line 330: if assessment.status == codex_protocol::protocol::GuardianAssessmentStatus::InProgress
	- line 348: let notification = guardian_auto_approval_review_notification(
	- line 354: if assessment.status == codex_protocol::protocol::GuardianAssessmentStatus::InProgress
	- line 371: codex_protocol::protocol::GuardianAssessmentStatus::Denied
	- line 372: | codex_protocol::protocol::GuardianAssessmentStatus::Aborted => {
	- line 375: codex_protocol::protocol::GuardianAssessmentStatus::TimedOut => {
	- line 378: codex_protocol::protocol::GuardianAssessmentStatus::InProgress
	- line 379: | codex_protocol::protocol::GuardianAssessmentStatus::Approved => None,
	- line 669: decision: ReviewDecision::denied("invalid command approval cwd"),
	- line 737: proposed_execpolicy_amendment.map(V2ExecPolicyAmendment::from);
	- line 1051: // Approval and guardian flows can emit the command start notification before core
	- line 1981: fn map_file_change_approval_decision(decision: FileChangeApprovalDecision) -> ReviewDecision {
	- line 1983: FileChangeApprovalDecision::Accept => ReviewDecision::Approved,
	- line 1984: FileChangeApprovalDecision::AcceptForSession => ReviewDecision::ApprovedForSession,
	- line 1985: FileChangeApprovalDecision::Decline => ReviewDecision::denied("rejected by user"),
	- line 1986: FileChangeApprovalDecision::Cancel => ReviewDecision::Abort,
	- line 2007: ReviewDecision::denied("approval request failed")
	- line 2013: ReviewDecision::denied("approval request failed")
	- line 2017: ReviewDecision::denied("approval request failed")
	- line 2053: CommandExecutionApprovalDecision::Accept => (ReviewDecision::Approved, None),
	- line 2055: (ReviewDecision::ApprovedForSession, None)
	- line 2060: ReviewDecision::ApprovedExecpolicyAmendment {
	- line 2075: ReviewDecision::NetworkPolicyAmendment {
	- line 2082: ReviewDecision::denied("rejected by user"),
	- line 2086: ReviewDecision::Abort,
	- line 2093: ReviewDecision::denied("approval request failed"),
	- line 2103: ReviewDecision::denied("approval request failed"),
	- line 2110: ReviewDecision::denied("approval request failed"),
	- line 2180: use codex_app_server_protocol::AutoReviewDecisionSource;
	- line 2181: use codex_app_server_protocol::GuardianApprovalReviewStatus;
	- line 2203: use codex_protocol::protocol::AskForApproval;
	- line 2207: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 2208: use codex_protocol::protocol::GuardianAssessmentStatus;
	- line 2308: approval_mode: AskForApproval::OnRequest,
	- line 2372: fn guardian_command_assessment(
	- line 2375: status: GuardianAssessmentStatus,
	- line 2376: ) -> GuardianAssessmentEvent {
	- line 2378: GuardianAssessmentStatus::InProgress => (None, None, None),
	- line 2379: GuardianAssessmentStatus::Approved => (
	- line 2380: Some(codex_protocol::protocol::GuardianRiskLevel::Low),
	- line 2381: Some(codex_protocol::protocol::GuardianUserAuthorization::High),
	- line 2384: GuardianAssessmentStatus::Denied => (
	- line 2385: Some(codex_protocol::protocol::GuardianRiskLevel::High),
	- line 2386: Some(codex_protocol::protocol::GuardianUserAuthorization::Low),
	- line 2389: GuardianAssessmentStatus::TimedOut => {
	- line 2392: GuardianAssessmentStatus::Aborted => (None, None, None),
	- line 2394: GuardianAssessmentEvent {
	- line 2401: completed_at_ms: (!matches!(status, GuardianAssessmentStatus::InProgress))
	- line 2407: decision_source: if matches!(status, GuardianAssessmentStatus::InProgress) {
	- line 2410: Some(codex_protocol::protocol::GuardianAssessmentDecisionSource::Agent)
	- line 2418: .expect("guardian action"),
	- line 2422: struct GuardianAssessmentTestContext {
	- line 2431: impl GuardianAssessmentTestContext {
	- line 2432: async fn apply_guardian_assessment_event(&self, assessment: GuardianAssessmentEvent) {
	- line 2437: msg: EventMsg::GuardianAssessment(assessment),
	- line 2453: fn guardian_assessment_started_uses_event_turn_id_fallback() {
	- line 2455: let action = codex_protocol::protocol::GuardianAssessmentAction::Command {
	- line 2456: source: codex_protocol::protocol::GuardianCommandSource::Shell,
	- line 2460: let notification = guardian_auto_approval_review_notification(
	- line 2463: &GuardianAssessmentEvent {
	- line 2471: status: codex_protocol::protocol::GuardianAssessmentStatus::InProgress,
	- line 2481: ServerNotification::ItemGuardianApprovalReviewStarted(payload) => {
	- line 2489: GuardianApprovalReviewStatus::InProgress
	- line 2501: fn guardian_assessment_completed_emits_review_payload() {
	- line 2503: let action = codex_protocol::protocol::GuardianAssessmentAction::Command {
	- line 2504: source: codex_protocol::protocol::GuardianCommandSource::Shell,
	- line 2508: let notification = guardian_auto_approval_review_notification(
	- line 2511: &GuardianAssessmentEvent {
	- line 2519: status: codex_protocol::protocol::GuardianAssessmentStatus::Denied,
	- line 2520: risk_level: Some(codex_protocol::protocol::GuardianRiskLevel::High),
	- line 2521: user_authorization: Some(codex_protocol::protocol::GuardianUserAuthorization::Low),
	- line 2524: codex_protocol::protocol::GuardianAssessmentDecisionSource::Agent,
	- line 2531: ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => {
	- line 2538: assert_eq!(payload.decision_source, AutoReviewDecisionSource::Agent);
	- line 2539: assert_eq!(payload.review.status, GuardianApprovalReviewStatus::Denied);
	- line 2542: Some(codex_app_server_protocol::GuardianRiskLevel::High)
	- line 2546: Some(codex_app_server_protocol::GuardianUserAuthorization::Low)
	- line 2556: fn guardian_assessment_aborted_emits_completed_review_payload() {
	- line 2558: let action = codex_protocol::protocol::GuardianAssessmentAction::NetworkAccess {
	- line 2564: let notification = guardian_auto_approval_review_notification(
	- line 2567: &GuardianAssessmentEvent {
	- line 2575: status: codex_protocol::protocol::GuardianAssessmentStatus::Aborted,
	- line 2580: codex_protocol::protocol::GuardianAssessmentDecisionSource::Agent,
	- line 2587: ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => {
	- line 2592: assert_eq!(payload.decision_source, AutoReviewDecisionSource::Agent);
	- line 2593: assert_eq!(payload.review.status, GuardianApprovalReviewStatus::Aborted);
	- line 2767: async fn guardian_command_execution_notifications_wrap_review_lifecycle() -> Result<()> {
	- line 2797: let guardian_context = GuardianAssessmentTestContext {
	- line 2806: guardian_context
	- line 2807: .apply_guardian_assessment_event(guardian_command_assessment(
	- line 2808: "cmd-guardian-approved",
	- line 2809: "turn-guardian-approved",
	- line 2810: GuardianAssessmentStatus::InProgress,
	- line 2816: assert_eq!(payload.turn_id, "turn-guardian-approved");
	- line 2827: assert_eq!(id, "cmd-guardian-approved");
	- line 2836: ServerNotification::ItemGuardianApprovalReviewStarted(payload) => {
	- line 2837: assert_eq!(payload.review_id, "review-cmd-guardian-approved");
	- line 2840: Some("cmd-guardian-approved")
	- line 2844: GuardianApprovalReviewStatus::InProgress
	- line 2850: guardian_context
	- line 2851: .apply_guardian_assessment_event(guardian_command_assessment(
	- line 2852: "cmd-guardian-approved",
	- line 2853: "turn-guardian-approved",
	- line 2854: GuardianAssessmentStatus::Approved,
	- line 2859: ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => {
	- line 2860: assert_eq!(payload.review_id, "review-cmd-guardian-approved");
	- line 2863: Some("cmd-guardian-approved")
	- line 2865: assert_eq!(payload.decision_source, AutoReviewDecisionSource::Agent);
	- line 2868: GuardianApprovalReviewStatus::Approved
	- line 2878: guardian_context
	- line 2879: .apply_guardian_assessment_event(guardian_command_assessment(
	- line 2880: "cmd-guardian-denied",
	- line 2881: "turn-guardian-denied",
	- line 2882: GuardianAssessmentStatus::InProgress,
	- line 2888: assert_eq!(payload.turn_id, "turn-guardian-denied");
	- line 2899: assert_eq!(id, "cmd-guardian-denied");
	- line 2908: ServerNotification::ItemGuardianApprovalReviewStarted(payload) => {
	- line 2909: assert_eq!(payload.review_id, "review-cmd-guardian-denied");
	- line 2912: Some("cmd-guardian-denied")
	- line 2916: GuardianApprovalReviewStatus::InProgress
	- line 2922: guardian_context
	- line 2923: .apply_guardian_assessment_event(guardian_command_assessment(
	- line 2924: "cmd-guardian-denied",
	- line 2925: "turn-guardian-denied",
	- line 2926: GuardianAssessmentStatus::Denied,
	- line 2931: ServerNotification::ItemGuardianApprovalReviewCompleted(payload) => {
	- line 2932: assert_eq!(payload.review_id, "review-cmd-guardian-denied");
	- line 2935: Some("cmd-guardian-denied")
	- line 2937: assert_eq!(payload.decision_source, AutoReviewDecisionSource::Agent);
	- line 2938: assert_eq!(payload.review.status, GuardianApprovalReviewStatus::Denied);
	- line 2955: assert_eq!(id, "cmd-guardian-denied");
	- line 2963: let mut missing_target = guardian_command_assessment(
	- line 2964: "cmd-guardian-missing-target",
	- line 2965: "turn-guardian-missing-target",
	- line 2966: GuardianAssessmentStatus::InProgress,
	- line 2969: guardian_context
	- line 2970: .apply_guardian_assessment_event(missing_target)
	- line 2974: ServerNotification::ItemGuardianApprovalReviewStarted(payload) => {
	- line 2975: assert_eq!(payload.review_id, "review-cmd-guardian-missing-target");
	- line 2979: GuardianApprovalReviewStatus::InProgress
	- line 2994: assert_eq!(decision, ReviewDecision::ApprovedForSession);


codex-rs/core/src/exec_policy.rs (117 lines):
	- line 12: use codex_execpolicy::Error as ExecPolicyRuleError;
	- line 18: use codex_execpolicy::RequirementsExecPolicy;
	- line 22: use codex_protocol::approvals::ExecPolicyAmendment;
	- line 26: use codex_protocol::protocol::AskForApproval;
	- line 48: "approval required by policy, but AskForApproval is set to Never";
	- line 50: "approval required by policy, but AskForApproval::Granular.sandbox_approval is false";
	- line 52: "approval required by policy rule, but AskForApproval::Granular.rules is false";
	- line 156: pub(crate) enum ExecPolicyCommandOrigin {
	- line 168: pub(crate) approval_policy: AskForApproval,
	- line 174: pub(crate) command_origin: ExecPolicyCommandOrigin,
	- line 178: struct ExecPolicyCommands {
	- line 180: command_origin: ExecPolicyCommandOrigin,
	- line 183: pub(crate) fn child_uses_parent_exec_policy(parent_config: &Config, child_config: &Config) -> bool {
	- line 184: fn exec_policy_config_folders(config: &Config) -> Vec<AbsolutePathBuf> {
	- line 192: exec_policy_config_folders(parent_config) == exec_policy_config_folders(child_config)
	- line 195: .ignore_user_and_project_exec_policy_rules()
	- line 198: .ignore_user_and_project_exec_policy_rules()
	- line 199: && parent_config.config_layer_stack.requirements().exec_policy
	- line 200: == child_config.config_layer_stack.requirements().exec_policy
	- line 210: /// Returns a rejection reason when `approval_policy` disallows surfacing the
	- line 217: approval_policy: AskForApproval,
	- line 220: match approval_policy {
	- line 221: AskForApproval::Never => Some(PROMPT_CONFLICT_REASON),
	- line 222: AskForApproval::OnRequest => None,
	- line 223: AskForApproval::UnlessTrusted => None,
	- line 224: AskForApproval::Granular(granular_config) => {
	- line 241: pub enum ExecPolicyError {
	- line 262: pub enum ExecPolicyUpdateError {
	- line 272: source: ExecPolicyRuleError,
	- line 276: pub(crate) struct ExecPolicyManager {
	- line 283: pub(crate) approval_policy: AskForApproval,
	- line 285: pub(crate) environment_policy: Option<&'a RequirementsExecPolicy>,
	- line 294: impl ExecPolicyManager {
	- line 303: pub(crate) async fn load(config_stack: &ConfigLayerStack) -> Result<Self, ExecPolicyError> {
	- line 304: let (policy, warning) = load_exec_policy_with_warning(config_stack).await?;
	- line 319: let commands = commands_for_exec_policy(req.command);
	- line 327: ExecPolicyCommands {
	- line 330: }: ExecPolicyCommands,
	- line 334: approval_policy,
	- line 342: let exec_policy = self.current_for_environment(environment_policy, allow_prefix_rules);
	- line 345: let exec_policy_fallback = |cmd: &[String]| {
	- line 349: approval_policy,
	- line 360: let evaluation = exec_policy.check_multiple_with_options(
	- line 362: &exec_policy_fallback,
	- line 370: exec_policy.as_ref(),
	- line 372: &exec_policy_fallback,
	- line 395: match prompt_is_rejected_by_policy(approval_policy, prompt_is_rule) {
	- line 427: exec_policy
	- line 450: amendment: &ExecPolicyAmendment,
	- line 451: ) -> Result<(), ExecPolicyUpdateError> {
	- line 456: .map_err(|_| ExecPolicyUpdateError::AddRule {
	- line 457: source: ExecPolicyRuleError::InvalidRule(
	- line 468: .map_err(|source| ExecPolicyUpdateError::JoinBlockingTask { source })?
	- line 469: .map_err(|source| ExecPolicyUpdateError::AppendRule {
	- line 504: ) -> Result<(), ExecPolicyUpdateError> {
	- line 509: .map_err(|_| ExecPolicyUpdateError::AddRule {
	- line 510: source: ExecPolicyRuleError::InvalidRule(
	- line 531: .map_err(|source| ExecPolicyUpdateError::JoinBlockingTask { source })?
	- line 532: .map_err(|source| ExecPolicyUpdateError::AppendRule {
	- line 544: impl Default for ExecPolicyManager {
	- line 552: ) -> Result<Option<ExecPolicyError>, ExecPolicyError> {
	- line 553: let (_, warning) = load_exec_policy_with_warning(config_stack).await?;
	- line 557: fn exec_policy_message_for_display(source: &codex_execpolicy::Error) -> String {
	- line 595: pub fn format_exec_policy_error_with_source(error: &ExecPolicyError) -> String {
	- line 597: ExecPolicyError::ParsePolicy { path, source } => {
	- line 610: let message = exec_policy_message_for_display(source);
	- line 628: pub(crate) async fn load_exec_policy_with_warning(
	- line 630: ) -> Result<(Policy, Option<ExecPolicyError>), ExecPolicyError> {
	- line 631: match load_exec_policy(config_stack).await {
	- line 633: Err(err @ ExecPolicyError::ParsePolicy { .. }) => {
	- line 636: .exec_policy
	- line 645: pub async fn load_exec_policy(config_stack: &ConfigLayerStack) -> Result<Policy, ExecPolicyError> {
	- line 653: if config_stack.ignore_user_and_project_exec_policy_rules()
	- line 677: .map_err(|source| ExecPolicyError::ReadFile {
	- line 684: .map_err(|source| ExecPolicyError::ParsePolicy {
	- line 694: let Some(requirements_policy) = config_stack.requirements().exec_policy.as_deref() else {
	- line 703: command_origin: ExecPolicyCommandOrigin,
	- line 706: ExecPolicyCommandOrigin::Generic => dangerous_command_match(command),
	- line 708: ExecPolicyCommandOrigin::PowerShell => {
	- line 718: command_origin: ExecPolicyCommandOrigin,
	- line 742: approval_policy,
	- line 765: return match approval_policy {
	- line 766: AskForApproval::Never => Decision::Forbidden,
	- line 767: AskForApproval::OnRequest
	- line 768: | AskForApproval::UnlessTrusted
	- line 769: | AskForApproval::Granular(_) => Decision::Prompt,
	- line 773: match approval_policy {
	- line 774: AskForApproval::Never => {
	- line 779: AskForApproval::UnlessTrusted => {
	- line 784: AskForApproval::OnRequest => {
	- line 804: AskForApproval::Granular(_) => match file_system_sandbox_policy.kind {
	- line 835: fn commands_for_exec_policy(command: &[String]) -> ExecPolicyCommands {
	- line 839: return ExecPolicyCommands {
	- line 841: command_origin: ExecPolicyCommandOrigin::Generic,
	- line 851: return ExecPolicyCommands {
	- line 853: command_origin: ExecPolicyCommandOrigin::PowerShell,
	- line 858: ExecPolicyCommands {
	- line 860: command_origin: ExecPolicyCommandOrigin::Generic,
	- line 876: ) -> Option<ExecPolicyAmendment> {
	- line 890: } => Some(ExecPolicyAmendment::from(command.clone())),
	- line 900: ) -> Option<ExecPolicyAmendment> {
	- line 911: } => Some(ExecPolicyAmendment::from(command.clone())),
	- line 919: exec_policy: &Policy,
	- line 921: exec_policy_fallback: &impl Fn(&[String]) -> Decision,
	- line 923: ) -> Option<ExecPolicyAmendment> {
	- line 943: let amendment = ExecPolicyAmendment::new(prefix_rule.clone());
	- line 945: exec_policy,
	- line 948: exec_policy_fallback,
	- line 958: exec_policy: &Policy,
	- line 961: exec_policy_fallback: &impl Fn(&[String]) -> Decision,
	- line 964: let mut policy_with_prefix_rule = exec_policy.clone();
	- line 974: .check_with_options(command, exec_policy_fallback, match_options)
	- line 1079: async fn collect_policy_files(dir: impl AsRef<Path>) -> Result<Vec<PathBuf>, ExecPolicyError> {
	- line 1085: return Err(ExecPolicyError::ReadDir {
	- line 1097: .map_err(|source| ExecPolicyError::ReadDir {
	- line 1106: .map_err(|source| ExecPolicyError::ReadDir {
	- line 1132: #[path = "exec_policy_tests.rs"]


codex-rs/analytics/src/events.rs (110 lines):
	- line 37: use codex_protocol::protocol::GuardianAssessmentOutcome;
	- line 38: use codex_protocol::protocol::GuardianCommandSource;
	- line 39: use codex_protocol::protocol::GuardianRiskLevel;
	- line 40: use codex_protocol::protocol::GuardianUserAuthorization;
	- line 71: GuardianReview(Box<GuardianReviewEventRequest>),
	- line 284: pub(crate) struct GuardianReviewEventRequest {
	- line 286: pub(crate) event_params: GuardianReviewEventPayload,
	- line 291: pub enum GuardianReviewDecision {
	- line 299: pub enum GuardianReviewTerminalStatus {
	- line 309: pub enum GuardianReviewFailureReason {
	- line 319: pub enum GuardianReviewSessionKind {
	- line 327: pub enum GuardianApprovalRequestSource {
	- line 331: /// session for guardian review.
	- line 337: pub enum GuardianReviewedAction {
	- line 351: source: GuardianCommandSource,
	- line 371: pub struct GuardianReviewEventParams {
	- line 376: pub approval_request_source: GuardianApprovalRequestSource,
	- line 377: pub reviewed_action: GuardianReviewedAction,
	- line 379: pub decision: GuardianReviewDecision,
	- line 380: pub terminal_status: GuardianReviewTerminalStatus,
	- line 381: pub failure_reason: Option<GuardianReviewFailureReason>,
	- line 383: pub risk_level: Option<GuardianRiskLevel>,
	- line 384: pub user_authorization: Option<GuardianUserAuthorization>,
	- line 385: pub outcome: Option<GuardianAssessmentOutcome>,
	- line 386: pub guardian_thread_id: Option<String>,
	- line 387: pub guardian_session_kind: Option<GuardianReviewSessionKind>,
	- line 388: pub guardian_model: Option<String>,
	- line 389: pub guardian_reasoning_effort: Option<String>,
	- line 390: pub guardian_default_review_model_id: Option<String>,
	- line 391: pub guardian_catalog_contains_auto_review: Option<bool>,
	- line 392: pub guardian_review_model_overridden: Option<bool>,
	- line 393: pub guardian_review_model_override: Option<String>,
	- line 394: pub guardian_model_provider_id: Option<String>,
	- line 410: pub struct GuardianReviewTrackContext {
	- line 415: approval_request_source: GuardianApprovalRequestSource,
	- line 416: reviewed_action: GuardianReviewedAction,
	- line 422: impl GuardianReviewTrackContext {
	- line 428: approval_request_source: GuardianApprovalRequestSource,
	- line 429: reviewed_action: GuardianReviewedAction,
	- line 447: result: GuardianReviewAnalyticsResult,
	- line 449: ) -> GuardianReviewEventParams {
	- line 450: GuardianReviewEventParams {
	- line 465: guardian_thread_id: result.guardian_thread_id,
	- line 466: guardian_session_kind: result.guardian_session_kind,
	- line 467: guardian_model: result.guardian_model,
	- line 468: guardian_reasoning_effort: result.guardian_reasoning_effort,
	- line 469: guardian_default_review_model_id: result.guardian_default_review_model_id,
	- line 470: guardian_catalog_contains_auto_review: result.guardian_catalog_contains_auto_review,
	- line 471: guardian_review_model_overridden: result.guardian_review_model_overridden,
	- line 472: guardian_review_model_override: result.guardian_review_model_override,
	- line 473: guardian_model_provider_id: result.guardian_model_provider_id,
	- line 476: // TODO(rhan-oai): plumb nested Guardian review session tool-call counts.
	- line 502: pub struct GuardianReviewAnalyticsResult {
	- line 503: pub decision: GuardianReviewDecision,
	- line 504: pub terminal_status: GuardianReviewTerminalStatus,
	- line 505: pub failure_reason: Option<GuardianReviewFailureReason>,
	- line 507: pub risk_level: Option<GuardianRiskLevel>,
	- line 508: pub user_authorization: Option<GuardianUserAuthorization>,
	- line 509: pub outcome: Option<GuardianAssessmentOutcome>,
	- line 510: pub guardian_thread_id: Option<String>,
	- line 511: pub guardian_session_kind: Option<GuardianReviewSessionKind>,
	- line 512: pub guardian_model: Option<String>,
	- line 513: pub guardian_reasoning_effort: Option<String>,
	- line 514: pub guardian_default_review_model_id: Option<String>,
	- line 515: pub guardian_catalog_contains_auto_review: Option<bool>,
	- line 516: pub guardian_review_model_overridden: Option<bool>,
	- line 517: pub guardian_review_model_override: Option<String>,
	- line 518: pub guardian_model_provider_id: Option<String>,
	- line 525: impl GuardianReviewAnalyticsResult {
	- line 528: decision: GuardianReviewDecision::Denied,
	- line 529: terminal_status: GuardianReviewTerminalStatus::FailedClosed,
	- line 535: guardian_thread_id: None,
	- line 536: guardian_session_kind: None,
	- line 537: guardian_model: None,
	- line 538: guardian_reasoning_effort: None,
	- line 539: guardian_default_review_model_id: None,
	- line 540: guardian_catalog_contains_auto_review: None,
	- line 541: guardian_review_model_overridden: None,
	- line 542: guardian_review_model_override: None,
	- line 543: guardian_model_provider_id: None,
	- line 551: pub fn from_session(params: GuardianReviewSessionAnalyticsParams) -> Self {
	- line 553: guardian_thread_id: Some(params.guardian_thread_id),
	- line 554: guardian_session_kind: Some(params.guardian_session_kind),
	- line 555: guardian_model: Some(params.guardian_model),
	- line 556: guardian_reasoning_effort: params.guardian_reasoning_effort,
	- line 557: guardian_default_review_model_id: Some(params.guardian_default_review_model_id),
	- line 558: guardian_catalog_contains_auto_review: Some(
	- line 559: params.guardian_catalog_contains_auto_review,
	- line 561: guardian_review_model_overridden: Some(params.guardian_review_model_overridden),
	- line 562: guardian_review_model_override: params.guardian_review_model_override,
	- line 563: guardian_model_provider_id: Some(params.guardian_model_provider_id),
	- line 570: pub struct GuardianReviewSessionAnalyticsParams {
	- line 571: pub guardian_thread_id: String,
	- line 572: pub guardian_session_kind: GuardianReviewSessionKind,
	- line 573: pub guardian_model: String,
	- line 574: pub guardian_reasoning_effort: Option<String>,
	- line 575: pub guardian_default_review_model_id: String,
	- line 576: pub guardian_catalog_contains_auto_review: bool,
	- line 577: pub guardian_review_model_overridden: bool,
	- line 578: pub guardian_review_model_override: Option<String>,
	- line 579: pub guardian_model_provider_id: String,
	- line 584: pub(crate) struct GuardianReviewEventPayload {
	- line 589: pub(crate) guardian_review: GuardianReviewEventParams,
	- line 600: GuardianApproved,
	- line 601: GuardianDenied,
	- line 602: GuardianAborted,
	- line 656: pub(crate) guardian_review_count: u64,
	- line 681: Guardian,
	- line 711: ExecPolicyAmendment,
	- line 1031: pub(crate) approval_policy: String,


codex-rs/core/src/guardian/prompt.rs (109 lines):
	- line 6: use codex_protocol::protocol::GuardianRiskLevel;
	- line 7: use codex_protocol::protocol::GuardianUserAuthorization;
	- line 13: use crate::context::GuardianReviewEvidence;
	- line 33: use super::GuardianApprovalRequest;
	- line 34: use super::GuardianAssessment;
	- line 35: use super::GuardianReviewContext;
	- line 37: use super::approval_request::format_guardian_action_pretty;
	- line 42: /// Transcript entry retained for guardian review after filtering.
	- line 44: pub(crate) struct GuardianTranscriptEntry {
	- line 45: pub(crate) kind: GuardianTranscriptEntryKind,
	- line 50: pub(crate) enum GuardianTranscriptEntryKind {
	- line 58: impl GuardianTranscriptEntryKind {
	- line 77: pub(crate) struct GuardianPromptItems {
	- line 79: pub(crate) transcript_cursor: GuardianTranscriptCursor,
	- line 84: /// Points to the end of the transcript that the guardian has already reviewed.
	- line 87: pub(crate) struct GuardianTranscriptCursor {
	- line 92: pub(crate) enum GuardianPromptMode {
	- line 94: Delta { cursor: GuardianTranscriptCursor },
	- line 97: /// Builds the guardian user content items from:
	- line 101: /// The fixed guardian policy lives in the review session developer message.
	- line 106: pub(crate) async fn build_guardian_prompt_items(
	- line 109: request: GuardianApprovalRequest,
	- line 110: mode: GuardianPromptMode,
	- line 111: ) -> serde_json::Result<GuardianPromptItems> {
	- line 112: build_guardian_prompt_items_with_parent_turn(
	- line 126: pub(crate) async fn build_guardian_prompt_items_with_parent_turn(
	- line 128: parent_context: Option<&GuardianReviewContext>,
	- line 130: request: GuardianApprovalRequest,
	- line 131: mode: GuardianPromptMode,
	- line 133: ) -> serde_json::Result<GuardianPromptItems> {
	- line 153: .get::<GuardianReviewEvidence>()
	- line 156: let transcript_entries = collect_guardian_transcript_entries(history.review_items());
	- line 157: let transcript_cursor = GuardianTranscriptCursor {
	- line 161: let planned_action_json = format_guardian_action_pretty(&request)?;
	- line 164: GuardianPromptMode::Full => GuardianPromptShape::Full,
	- line 165: GuardianPromptMode::Delta { cursor } => {
	- line 169: GuardianPromptShape::Delta {
	- line 173: GuardianPromptShape::Full
	- line 178: GuardianPromptShape::Full => {
	- line 180: render_guardian_transcript_entries_with_offset(
	- line 189: GuardianPromptHeadings {
	- line 197: GuardianPromptShape::Delta {
	- line 201: render_guardian_transcript_entries_with_offset(
	- line 210: GuardianPromptHeadings {
	- line 284: GuardianApprovalRequest::NetworkAccess { trigger, .. } => {
	- line 315: let action_scope = if matches!(&request, GuardianApprovalRequest::WriteStdin { .. }) {
	- line 326: Ok(GuardianPromptItems {
	- line 334: fn parent_turn_denied_reads_context(context: &GuardianReviewContext) -> Option<String> {
	- line 366: enum GuardianPromptShape {
	- line 371: struct GuardianPromptHeadings {
	- line 378: /// Renders a compact guardian transcript from the retained history entries,
	- line 395: pub(crate) fn render_guardian_transcript_entries(
	- line 396: entries: &[GuardianTranscriptEntry],
	- line 398: render_guardian_transcript_entries_with_offset(
	- line 406: fn render_guardian_transcript_entries_with_offset(
	- line 407: entries: &[GuardianTranscriptEntry],
	- line 422: GuardianTranscriptEntryKind::NodeReplToolResult(_)
	- line 430: let (text, _) = guardian_truncate_text(&entry.text, token_cap);
	- line 517: /// evidence for guardian review and skips synthetic contextual scaffolding that
	- line 518: /// would just add noise because the guardian reviewer already gets the normal
	- line 524: pub(crate) fn collect_guardian_transcript_entries<'a>(
	- line 526: ) -> Vec<GuardianTranscriptEntry> {
	- line 530: (!text.trim().is_empty()).then_some(GuardianTranscriptEntry { kind, text })
	- line 543: content_entry(GuardianTranscriptEntryKind::User, content)
	- line 549: // Guardian context; other developer messages are intentionally
	- line 552: .then_some(GuardianTranscriptEntry {
	- line 553: kind: GuardianTranscriptEntryKind::Developer,
	- line 559: content_entry(GuardianTranscriptEntryKind::Assistant, content)
	- line 563: } => plaintext_agent_message_content(content).map(|text| GuardianTranscriptEntry {
	- line 564: kind: GuardianTranscriptEntryKind::Assistant,
	- line 568: GuardianTranscriptEntryKind::Tool("tool shell call".to_string()),
	- line 580: (!arguments.trim().is_empty()).then(|| GuardianTranscriptEntry {
	- line 581: kind: GuardianTranscriptEntryKind::Tool(format!("tool {name} call")),
	- line 594: (!input.trim().is_empty()).then(|| GuardianTranscriptEntry {
	- line 595: kind: GuardianTranscriptEntryKind::Tool(format!("tool {name} call")),
	- line 601: GuardianTranscriptEntryKind::Tool("tool web_search call".to_string()),
	- line 615: GuardianTranscriptEntryKind::NodeReplToolResult(format!(
	- line 620: GuardianTranscriptEntryKind::Tool(format!("tool {name} result"))
	- line 622: None => GuardianTranscriptEntryKind::Tool("tool result".to_string()),
	- line 642: GuardianTranscriptEntryKind::Tool(format!("tool {name} result")),
	- line 657: pub(crate) fn guardian_truncate_text(content: &str, token_cap: usize) -> (String, bool) {
	- line 676: let (prefix, suffix) = split_guardian_truncation_bounds(content, prefix_budget, suffix_budget);
	- line 681: fn split_guardian_truncation_bounds(
	- line 723: pub(crate) fn parse_guardian_assessment(text: Option<&str>) -> anyhow::Result<GuardianAssessment> {
	- line 725: anyhow::bail!("guardian review completed without an assessment payload");
	- line 728: if let Ok(payload) = serde_json::from_str::<GuardianAssessmentPayload>(text) {
	- line 734: serde_json::from_str::<GuardianAssessmentPayload>(slice)?
	- line 736: anyhow::bail!("guardian assessment was not valid JSON");
	- line 741: super::GuardianAssessmentOutcome::Allow => GuardianRiskLevel::Low,
	- line 742: super::GuardianAssessmentOutcome::Deny => GuardianRiskLevel::High,
	- line 748: super::GuardianAssessmentOutcome::Allow => {
	- line 751: super::GuardianAssessmentOutcome::Deny => {
	- line 756: Ok(GuardianAssessment {
	- line 760: .unwrap_or(GuardianUserAuthorization::Unknown),
	- line 767: struct GuardianAssessmentPayload {
	- line 768: risk_level: Option<GuardianRiskLevel>,
	- line 769: user_authorization: Option<GuardianUserAuthorization>,
	- line 770: outcome: super::GuardianAssessmentOutcome,
	- line 775: /// final answer from the guardian review session.
	- line 777: /// Keep this next to `guardian_output_contract_prompt()` so the prompt text and
	- line 779: pub(crate) fn guardian_output_schema() -> Value {
	- line 805: /// `guardian_output_schema()`.
	- line 806: fn guardian_output_contract_prompt() -> &'static str {
	- line 820: pub(crate) const BUNDLED_GUARDIAN_POLICY: &str = include_str!("../../assets/guardian/policy.md");
	- line 822: include_str!("../../assets/guardian/policy_template.md");
	- line 825: /// Guardian policy prompt.
	- line 829: /// contract is appended from code so it stays near `guardian_output_schema()`.
	- line 834: pub(super) fn guardian_policy_prompt_with_config_and_template(
	- line 843: format!("{prompt}\n\n{}\n", guardian_output_contract_prompt())


codex-rs/core/src/guardian/approval_request.rs (98 lines):
	- line 3: use codex_analytics::GuardianReviewedAction;
	- line 4: use codex_protocol::approvals::GuardianAssessmentAction;
	- line 5: use codex_protocol::approvals::GuardianCommandSource;
	- line 16: use super::prompt::guardian_truncate_text;
	- line 19: pub(crate) enum GuardianApprovalRequest {
	- line 43: source: GuardianCommandSource,
	- line 62: trigger: Option<GuardianNetworkAccessTrigger>,
	- line 75: annotations: Option<GuardianMcpAnnotations>,
	- line 87: pub(crate) struct GuardianNetworkAccessTrigger {
	- line 102: pub(crate) struct GuardianMcpAnnotations {
	- line 169: annotations: Option<&'a GuardianMcpAnnotations>,
	- line 181: trigger: Option<&'a GuardianNetworkAccessTrigger>,
	- line 193: fn serialize_guardian_action(value: impl Serialize) -> serde_json::Result<Value> {
	- line 197: fn serialize_command_guardian_action(
	- line 206: serialize_guardian_action(CommandApprovalAction {
	- line 218: source: GuardianCommandSource,
	- line 221: ) -> GuardianAssessmentAction {
	- line 222: GuardianAssessmentAction::Command {
	- line 230: fn guardian_command_source_tool_name(source: GuardianCommandSource) -> &'static str {
	- line 232: GuardianCommandSource::Shell => "shell",
	- line 233: GuardianCommandSource::UnifiedExec => "exec_command",
	- line 237: fn truncate_guardian_action_value(value: Value) -> (Value, bool) {
	- line 241: guardian_truncate_text(&text, GUARDIAN_MAX_ACTION_STRING_TOKENS);
	- line 249: let (value, value_truncated) = truncate_guardian_action_value(value);
	- line 263: let (value, value_truncated) = truncate_guardian_action_value(value);
	- line 275: pub(crate) struct FormattedGuardianAction {
	- line 280: pub(crate) fn guardian_approval_request_to_json(
	- line 281: action: &GuardianApprovalRequest,
	- line 284: GuardianApprovalRequest::ExecCommand {
	- line 292: } => serialize_command_guardian_action(
	- line 301: GuardianApprovalRequest::WriteStdin {
	- line 310: } => serialize_guardian_action(WriteStdinApprovalAction {
	- line 321: GuardianApprovalRequest::Execve {
	- line 328: } => serialize_guardian_action(ExecveApprovalAction {
	- line 329: tool: guardian_command_source_tool_name(*source),
	- line 335: GuardianApprovalRequest::ApplyPatch {
	- line 346: GuardianApprovalRequest::NetworkAccess {
	- line 355: let mut value = serialize_guardian_action(NetworkAccessApprovalAction {
	- line 368: GuardianApprovalRequest::McpToolCall {
	- line 380: } => serialize_guardian_action(McpToolCallApprovalAction {
	- line 393: GuardianApprovalRequest::RequestPermissions {
	- line 398: } => serialize_guardian_action(RequestPermissionsApprovalAction {
	- line 407: pub(crate) fn guardian_assessment_action(
	- line 408: action: &GuardianApprovalRequest,
	- line 409: ) -> GuardianAssessmentAction {
	- line 411: GuardianApprovalRequest::ExecCommand { command, cwd, .. } => {
	- line 412: command_assessment_action(GuardianCommandSource::UnifiedExec, command, cwd)
	- line 414: GuardianApprovalRequest::WriteStdin {
	- line 420: } => GuardianAssessmentAction::WriteStdin {
	- line 427: GuardianApprovalRequest::Execve {
	- line 433: } => GuardianAssessmentAction::Execve {
	- line 439: GuardianApprovalRequest::ApplyPatch { cwd, files, .. } => {
	- line 440: GuardianAssessmentAction::ApplyPatch {
	- line 445: GuardianApprovalRequest::NetworkAccess {
	- line 453: } => GuardianAssessmentAction::NetworkAccess {
	- line 459: GuardianApprovalRequest::McpToolCall {
	- line 466: } => GuardianAssessmentAction::McpToolCall {
	- line 473: GuardianApprovalRequest::RequestPermissions {
	- line 477: } => GuardianAssessmentAction::RequestPermissions {
	- line 484: pub(crate) fn guardian_reviewed_action(
	- line 485: request: &GuardianApprovalRequest,
	- line 486: ) -> GuardianReviewedAction {
	- line 488: GuardianApprovalRequest::ExecCommand {
	- line 493: } => GuardianReviewedAction::UnifiedExec {
	- line 498: GuardianApprovalRequest::WriteStdin { tty, .. } => {
	- line 499: GuardianReviewedAction::WriteStdin { tty: *tty }
	- line 502: GuardianApprovalRequest::Execve {
	- line 507: } => GuardianReviewedAction::Execve {
	- line 512: GuardianApprovalRequest::ApplyPatch { .. } => GuardianReviewedAction::ApplyPatch {},
	- line 513: GuardianApprovalRequest::NetworkAccess { protocol, port, .. } => {
	- line 514: GuardianReviewedAction::NetworkAccess {
	- line 519: GuardianApprovalRequest::McpToolCall {
	- line 526: } => GuardianReviewedAction::McpToolCall {
	- line 533: GuardianApprovalRequest::RequestPermissions { .. } => {
	- line 534: GuardianReviewedAction::RequestPermissions {}
	- line 539: pub(crate) fn guardian_request_target_item_id(request: &GuardianApprovalRequest) -> Option<&str> {
	- line 541: GuardianApprovalRequest::ExecCommand { id, .. }
	- line 542: | GuardianApprovalRequest::WriteStdin { id, .. }
	- line 543: | GuardianApprovalRequest::ApplyPatch { id, .. }
	- line 544: | GuardianApprovalRequest::McpToolCall { id, .. }
	- line 545: | GuardianApprovalRequest::RequestPermissions { id, .. } => Some(id),
	- line 546: GuardianApprovalRequest::NetworkAccess { .. } => None,
	- line 548: GuardianApprovalRequest::Execve { id, .. } => Some(id),
	- line 552: pub(crate) fn guardian_request_turn_id<'a>(
	- line 553: request: &'a GuardianApprovalRequest,
	- line 557: GuardianApprovalRequest::NetworkAccess { turn_id, .. }
	- line 558: | GuardianApprovalRequest::RequestPermissions { turn_id, .. } => turn_id,
	- line 559: GuardianApprovalRequest::ExecCommand { .. }
	- line 560: | GuardianApprovalRequest::WriteStdin { .. }
	- line 561: | GuardianApprovalRequest::ApplyPatch { .. }
	- line 562: | GuardianApprovalRequest::McpToolCall { .. } => default_turn_id,
	- line 564: GuardianApprovalRequest::Execve { .. } => default_turn_id,
	- line 568: pub(crate) fn format_guardian_action_pretty(
	- line 569: action: &GuardianApprovalRequest,
	- line 570: ) -> serde_json::Result<FormattedGuardianAction> {
	- line 571: let value = guardian_approval_request_to_json(action)?;
	- line 572: let (value, truncated) = truncate_guardian_action_value(value);
	- line 573: Ok(FormattedGuardianAction {


codex-rs/tui/src/app/tests.rs (95 lines):
	- line 78: use codex_app_server_protocol::AskForApproval;
	- line 2793: approval_policy: None,
	- line 2829: approval_policy: None,
	- line 2857: async fn update_feature_flags_enabling_guardian_selects_auto_review() -> Result<()> {
	- line 2864: app.update_feature_flags(&mut app_server, vec![(Feature::GuardianApproval, true)])
	- line 2867: assert!(app.config.features.enabled(Feature::GuardianApproval));
	- line 2872: .enabled(Feature::GuardianApproval)
	- line 2879: AskForApproval::from(app.config.permissions.approval_policy.value()),
	- line 2880: auto_review.approval_policy
	- line 2883: AskForApproval::from(
	- line 2887: .approval_policy
	- line 2890: auto_review.approval_policy
	- line 2914: assert_eq!(app.runtime_approval_policy_override, None);
	- line 2923: approval_policy: Some(auto_review.approval_policy),
	- line 2949: assert!(config.contains("guardian_approval = true"));
	- line 2951: assert!(config.contains("approval_policy = \"on-request\""));
	- line 2958: async fn update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default()
	- line 2964: let config_toml = "approvals_reviewer = \"guardian_subagent\"\napproval_policy = \"on-request\"\nsandbox_mode = \"workspace-write\"\n\n[features]\nguardian_approval = true\n";
	- line 2973: .set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
	- line 2975: .set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
	- line 2981: .approval_policy
	- line 2982: .set(AskForApproval::OnRequest.to_core())?;
	- line 2987: .set_approval_policy(AskForApproval::OnRequest);
	- line 2994: app.update_feature_flags(&mut app_server, vec![(Feature::GuardianApproval, false)])
	- line 2997: assert!(!app.config.features.enabled(Feature::GuardianApproval));
	- line 3002: .enabled(Feature::GuardianApproval)
	- line 3006: AskForApproval::from(app.config.permissions.approval_policy.value()),
	- line 3007: AskForApproval::OnRequest
	- line 3013: assert_eq!(app.runtime_approval_policy_override, None);
	- line 3018: approval_policy: None,
	- line 3044: assert!(!config.contains("guardian_approval = true"));
	- line 3046: assert!(config.contains("approval_policy = \"on-request\""));
	- line 3053: async fn update_feature_flags_enabling_guardian_overrides_explicit_manual_review_policy()
	- line 3072: app.update_feature_flags(&mut app_server, vec![(Feature::GuardianApproval, true)])
	- line 3075: assert!(app.config.features.enabled(Feature::GuardianApproval));
	- line 3085: AskForApproval::from(app.config.permissions.approval_policy.value()),
	- line 3086: auto_review.approval_policy
	- line 3099: approval_policy: Some(auto_review.approval_policy),
	- line 3115: assert!(config.contains("guardian_approval = true"));
	- line 3116: assert!(config.contains("approval_policy = \"on-request\""));
	- line 3123: async fn update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history()
	- line 3129: let config_toml = "approvals_reviewer = \"user\"\napproval_policy = \"on-request\"\nsandbox_mode = \"workspace-write\"\n\n[features]\nguardian_approval = true\n";
	- line 3138: .set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
	- line 3140: .set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
	- line 3146: app.update_feature_flags(&mut app_server, vec![(Feature::GuardianApproval, false)])
	- line 3149: assert!(!app.config.features.enabled(Feature::GuardianApproval));
	- line 3159: approval_policy: None,
	- line 3178: assert!(!config.contains("guardian_approval = true"));
	- line 3267: approval_policy: AskForApproval::OnRequest,
	- line 3428: approval_policy: AskForApproval::OnRequest,
	- line 3937: approval_policy: AskForApproval::OnRequest,
	- line 3992: approval_policy: AskForApproval::OnRequest,
	- line 4073: assert_eq!(session.approval_policy, primary_session.approval_policy);
	- line 4104: approval_policy: AskForApproval::OnRequest,
	- line 4184: approval_policy: AskForApproval::OnRequest,
	- line 4300: let original_approval_policy = app.config.permissions.approval_policy.value();
	- line 4307: fork_config.permissions.approval_policy.value(),
	- line 4308: original_approval_policy
	- line 4356: .set_approval_policy(AskForApproval::OnRequest);
	- line 4372: fork_config.permissions.approval_policy.value(),
	- line 4380: AskForApproval::OnRequest.to_core(),
	- line 5291: approval_policy: AskForApproval::Never,
	- line 5430: runtime_approval_policy_override: None,
	- line 5512: runtime_approval_policy_override: None,
	- line 5800: approval_policy: AskForApproval::Never,
	- line 6637: approval_policy: AskForApproval::Never,
	- line 6708: approval_policy: AskForApproval::Never,
	- line 7782: approval_policy: AskForApproval::Never,
	- line 7924: Some(AskForApproval::OnRequest),
	- line 7965: notification.thread_settings.approval_policy,
	- line 7966: AskForApproval::OnRequest
	- line 8015: assert_eq!(updated_session.approval_policy, AskForApproval::OnRequest);
	- line 8038: .approval_policy
	- line 8039: .set(AskForApproval::UnlessTrusted.to_core())
	- line 8042: .set_approval_policy(AskForApproval::UnlessTrusted);
	- line 8062: started.session.approval_policy,
	- line 8063: AskForApproval::UnlessTrusted
	- line 8082: notification.thread_settings.approval_policy,
	- line 8083: AskForApproval::OnRequest
	- line 8120: approval_policy: Some(AskForApproval::OnRequest),
	- line 8184: assert_eq!(settings.approval_policy, AskForApproval::OnRequest);
	- line 8218: let _ = app.config.features.disable(Feature::GuardianApproval);
	- line 8220: .set_feature_enabled(Feature::GuardianApproval, /*enabled*/ false);
	- line 8228: params.approval_policy,
	- line 8229: Some(codex_app_server_protocol::AskForApproval::OnRequest)
	- line 8242: allowed_approval_policies: Some(vec![AskForApproval::UnlessTrusted.to_core()]),
	- line 8257: .approval_policy
	- line 8258: .set(AskForApproval::UnlessTrusted.to_core())
	- line 8261: .set_approval_policy(AskForApproval::UnlessTrusted);
	- line 8283: started.session.approval_policy,
	- line 8284: AskForApproval::UnlessTrusted
	- line 8302: notification.thread_settings.approval_policy,
	- line 8303: AskForApproval::UnlessTrusted
	- line 8408: approval_policy: AskForApproval::OnRequest,
	- line 8483: approval_policy: AskForApproval::Never,


codex-rs/app-server-protocol/src/protocol/v2/item.rs (87 lines):
	- line 2: use super::ExecPolicyAmendment;
	- line 24: use codex_protocol::approvals::GuardianAssessmentAction as CoreGuardianAssessmentAction;
	- line 25: use codex_protocol::approvals::GuardianAssessmentDecisionSource as CoreGuardianAssessmentDecisionSource;
	- line 26: use codex_protocol::approvals::GuardianCommandSource as CoreGuardianCommandSource;
	- line 45: use codex_protocol::protocol::GuardianRiskLevel as CoreGuardianRiskLevel;
	- line 46: use codex_protocol::protocol::GuardianUserAuthorization as CoreGuardianUserAuthorization;
	- line 48: use codex_protocol::protocol::ReviewDecision as CoreReviewDecision;
	- line 72: execpolicy_amendment: ExecPolicyAmendment,
	- line 84: impl From<CoreReviewDecision> for CommandExecutionApprovalDecision {
	- line 85: fn from(value: CoreReviewDecision) -> Self {
	- line 87: CoreReviewDecision::Approved => Self::Accept,
	- line 90: CoreReviewDecision::ApprovedMcpPolicyAmendment => Self::Decline,
	- line 91: CoreReviewDecision::ApprovedExecpolicyAmendment {
	- line 96: CoreReviewDecision::ApprovedForSession => Self::AcceptForSession,
	- line 97: CoreReviewDecision::NetworkPolicyAmendment {
	- line 102: CoreReviewDecision::Abort => Self::Cancel,
	- line 103: CoreReviewDecision::Denied { .. } => Self::Decline,
	- line 104: CoreReviewDecision::TimedOut => Self::Decline,
	- line 465: pub enum GuardianApprovalReviewStatus {
	- line 477: pub enum AutoReviewDecisionSource {
	- line 481: impl From<CoreGuardianAssessmentDecisionSource> for AutoReviewDecisionSource {
	- line 482: fn from(value: CoreGuardianAssessmentDecisionSource) -> Self {
	- line 484: CoreGuardianAssessmentDecisionSource::Agent => Self::Agent,
	- line 493: pub enum GuardianRiskLevel {
	- line 500: impl From<CoreGuardianRiskLevel> for GuardianRiskLevel {
	- line 501: fn from(value: CoreGuardianRiskLevel) -> Self {
	- line 503: CoreGuardianRiskLevel::Low => Self::Low,
	- line 504: CoreGuardianRiskLevel::Medium => Self::Medium,
	- line 505: CoreGuardianRiskLevel::High => Self::High,
	- line 506: CoreGuardianRiskLevel::Critical => Self::Critical,
	- line 515: pub enum GuardianUserAuthorization {
	- line 522: impl From<CoreGuardianUserAuthorization> for GuardianUserAuthorization {
	- line 523: fn from(value: CoreGuardianUserAuthorization) -> Self {
	- line 525: CoreGuardianUserAuthorization::Unknown => Self::Unknown,
	- line 526: CoreGuardianUserAuthorization::Low => Self::Low,
	- line 527: CoreGuardianUserAuthorization::Medium => Self::Medium,
	- line 528: CoreGuardianUserAuthorization::High => Self::High,
	- line 539: pub struct GuardianApprovalReview {
	- line 540: pub status: GuardianApprovalReviewStatus,
	- line 541: pub risk_level: Option<GuardianRiskLevel>,
	- line 542: pub user_authorization: Option<GuardianUserAuthorization>,
	- line 550: pub enum GuardianCommandSource {
	- line 555: impl From<CoreGuardianCommandSource> for GuardianCommandSource {
	- line 556: fn from(value: CoreGuardianCommandSource) -> Self {
	- line 558: CoreGuardianCommandSource::Shell => Self::Shell,
	- line 559: CoreGuardianCommandSource::UnifiedExec => Self::UnifiedExec,
	- line 564: impl From<GuardianCommandSource> for CoreGuardianCommandSource {
	- line 565: fn from(value: GuardianCommandSource) -> Self {
	- line 567: GuardianCommandSource::Shell => Self::Shell,
	- line 568: GuardianCommandSource::UnifiedExec => Self::UnifiedExec,
	- line 576: pub struct GuardianCommandReviewAction {
	- line 577: pub source: GuardianCommandSource,
	- line 585: pub struct GuardianExecveReviewAction {
	- line 586: pub source: GuardianCommandSource,
	- line 595: pub struct GuardianApplyPatchReviewAction {
	- line 603: pub struct GuardianNetworkAccessReviewAction {
	- line 613: pub struct GuardianMcpToolCallReviewAction {
	- line 624: pub struct GuardianRequestPermissionsReviewAction {
	- line 633: pub enum GuardianApprovalReviewAction {
	- line 637: source: GuardianCommandSource,
	- line 644: source: GuardianCommandSource,
	- line 689: impl From<CoreGuardianAssessmentAction> for GuardianApprovalReviewAction {
	- line 690: fn from(value: CoreGuardianAssessmentAction) -> Self {
	- line 692: CoreGuardianAssessmentAction::Command {
	- line 701: CoreGuardianAssessmentAction::Execve {
	- line 712: CoreGuardianAssessmentAction::WriteStdin {
	- line 723: CoreGuardianAssessmentAction::ApplyPatch { cwd, files } => {
	- line 726: CoreGuardianAssessmentAction::NetworkAccess {
	- line 737: CoreGuardianAssessmentAction::McpToolCall {
	- line 750: CoreGuardianAssessmentAction::RequestPermissions {
	- line 761: impl TryFrom<GuardianApprovalReviewAction> for CoreGuardianAssessmentAction {
	- line 764: fn try_from(value: GuardianApprovalReviewAction) -> Result<Self, Self::Error> {
	- line 766: GuardianApprovalReviewAction::Command {
	- line 775: GuardianApprovalReviewAction::Execve {
	- line 786: GuardianApprovalReviewAction::WriteStdin {
	- line 799: GuardianApprovalReviewAction::ApplyPatch { cwd, files } => {
	- line 802: GuardianApprovalReviewAction::NetworkAccess {
	- line 813: GuardianApprovalReviewAction::McpToolCall {
	- line 826: GuardianApprovalReviewAction::RequestPermissions {
	- line 1331: pub struct ItemGuardianApprovalReviewStartedNotification {
	- line 1353: pub review: GuardianApprovalReview,
	- line 1354: pub action: GuardianApprovalReviewAction,
	- line 1362: pub struct ItemGuardianApprovalReviewCompletedNotification {
	- line 1387: pub decision_source: AutoReviewDecisionSource,
	- line 1388: pub review: GuardianApprovalReview,
	- line 1389: pub action: GuardianApprovalReviewAction,
	- line 1581: pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,


codex-rs/core/src/guardian/metrics.rs (87 lines):
	- line 3: use codex_analytics::GuardianApprovalRequestSource;
	- line 4: use codex_analytics::GuardianReviewAnalyticsResult;
	- line 5: use codex_analytics::GuardianReviewDecision;
	- line 6: use codex_analytics::GuardianReviewFailureReason;
	- line 7: use codex_analytics::GuardianReviewSessionKind;
	- line 8: use codex_analytics::GuardianReviewTerminalStatus;
	- line 9: use codex_analytics::GuardianReviewedAction;
	- line 16: use codex_protocol::protocol::GuardianAssessmentOutcome;
	- line 17: use codex_protocol::protocol::GuardianRiskLevel;
	- line 18: use codex_protocol::protocol::GuardianUserAuthorization;
	- line 21: pub(crate) fn emit_guardian_review_metrics(
	- line 23: result: &GuardianReviewAnalyticsResult,
	- line 24: approval_request_source: GuardianApprovalRequestSource,
	- line 25: reviewed_action: &GuardianReviewedAction,
	- line 28: let tags = guardian_review_metric_tags(result, approval_request_source, reviewed_action);
	- line 50: emit_guardian_token_usage_histograms(session_telemetry, token_usage, tags);
	- line 54: fn emit_guardian_token_usage_histograms(
	- line 84: fn guardian_review_metric_tags(
	- line 85: result: &GuardianReviewAnalyticsResult,
	- line 86: approval_request_source: GuardianApprovalRequestSource,
	- line 87: reviewed_action: &GuardianReviewedAction,
	- line 106: session_kind_tag(result.guardian_session_kind).to_string(),
	- line 123: "guardian_model",
	- line 125: .guardian_model
	- line 131: "guardian_reasoning_effort",
	- line 133: .guardian_reasoning_effort
	- line 141: fn decision_tag(decision: GuardianReviewDecision) -> &'static str {
	- line 143: GuardianReviewDecision::Approved => "approved",
	- line 144: GuardianReviewDecision::Denied => "denied",
	- line 145: GuardianReviewDecision::Aborted => "aborted",
	- line 149: fn terminal_status_tag(status: GuardianReviewTerminalStatus) -> &'static str {
	- line 151: GuardianReviewTerminalStatus::Approved => "approved",
	- line 152: GuardianReviewTerminalStatus::Denied => "denied",
	- line 153: GuardianReviewTerminalStatus::Aborted => "aborted",
	- line 154: GuardianReviewTerminalStatus::TimedOut => "timed_out",
	- line 155: GuardianReviewTerminalStatus::FailedClosed => "failed_closed",
	- line 159: fn failure_reason_tag(reason: Option<GuardianReviewFailureReason>) -> &'static str {
	- line 161: Some(GuardianReviewFailureReason::Timeout) => "timeout",
	- line 162: Some(GuardianReviewFailureReason::Cancelled) => "cancelled",
	- line 163: Some(GuardianReviewFailureReason::PromptBuildError) => "prompt_build_error",
	- line 164: Some(GuardianReviewFailureReason::SessionError) => "session_error",
	- line 165: Some(GuardianReviewFailureReason::ParseError) => "parse_error",
	- line 170: fn approval_request_source_tag(source: GuardianApprovalRequestSource) -> &'static str {
	- line 172: GuardianApprovalRequestSource::MainTurn => "main_turn",
	- line 173: GuardianApprovalRequestSource::DelegatedSubagent => "delegated_subagent",
	- line 177: fn reviewed_action_tag(action: &GuardianReviewedAction) -> &'static str {
	- line 179: GuardianReviewedAction::Shell { .. } => "shell",
	- line 180: GuardianReviewedAction::UnifiedExec { .. } => "unified_exec",
	- line 181: GuardianReviewedAction::WriteStdin { .. } => "write_stdin",
	- line 182: GuardianReviewedAction::Execve { .. } => "execve",
	- line 183: GuardianReviewedAction::ApplyPatch {} => "apply_patch",
	- line 184: GuardianReviewedAction::NetworkAccess { .. } => "network_access",
	- line 185: GuardianReviewedAction::McpToolCall { .. } => "mcp_tool_call",
	- line 186: GuardianReviewedAction::RequestPermissions {} => "request_permissions",
	- line 190: fn session_kind_tag(kind: Option<GuardianReviewSessionKind>) -> &'static str {
	- line 192: Some(GuardianReviewSessionKind::TrunkNew) => "trunk_new",
	- line 193: Some(GuardianReviewSessionKind::TrunkReused) => "trunk_reused",
	- line 194: Some(GuardianReviewSessionKind::EphemeralForked) => "ephemeral_forked",
	- line 211: fn risk_level_tag(risk_level: Option<GuardianRiskLevel>) -> &'static str {
	- line 213: Some(GuardianRiskLevel::Low) => "low",
	- line 214: Some(GuardianRiskLevel::Medium) => "medium",
	- line 215: Some(GuardianRiskLevel::High) => "high",
	- line 216: Some(GuardianRiskLevel::Critical) => "critical",
	- line 221: fn user_authorization_tag(user_authorization: Option<GuardianUserAuthorization>) -> &'static str {
	- line 223: Some(GuardianUserAuthorization::Unknown) => "unknown",
	- line 224: Some(GuardianUserAuthorization::Low) => "low",
	- line 225: Some(GuardianUserAuthorization::Medium) => "medium",
	- line 226: Some(GuardianUserAuthorization::High) => "high",
	- line 231: fn outcome_tag(outcome: Option<GuardianAssessmentOutcome>) -> &'static str {
	- line 233: Some(GuardianAssessmentOutcome::Allow) => "allow",
	- line 234: Some(GuardianAssessmentOutcome::Deny) => "deny",
	- line 340: fn guardian_review_metrics_record_counts_durations_and_token_usage() {
	- line 342: let result = GuardianReviewAnalyticsResult {
	- line 343: decision: GuardianReviewDecision::Approved,
	- line 344: terminal_status: GuardianReviewTerminalStatus::Approved,
	- line 345: risk_level: Some(GuardianRiskLevel::Low),
	- line 346: user_authorization: Some(GuardianUserAuthorization::High),
	- line 347: outcome: Some(GuardianAssessmentOutcome::Allow),
	- line 348: guardian_session_kind: Some(GuardianReviewSessionKind::TrunkReused),
	- line 349: guardian_model: Some("gpt-5.4 guardian".to_string()),
	- line 350: guardian_reasoning_effort: Some("low".to_string()),
	- line 363: ..GuardianReviewAnalyticsResult::without_session()
	- line 366: emit_guardian_review_metrics(
	- line 369: GuardianApprovalRequestSource::DelegatedSubagent,
	- line 370: &GuardianReviewedAction::NetworkAccess {
	- line 393: ("guardian_model".to_string(), "gpt-5.4_guardian".to_string()),
	- line 394: ("guardian_reasoning_effort".to_string(), "low".to_string()),


codex-rs/core/src/tools/approvals.rs (86 lines):
	- line 4: use crate::exec_policy::prompt_is_rejected_by_policy;
	- line 5: use crate::guardian::GuardianNetworkAccessTrigger;
	- line 6: use crate::guardian::GuardianReviewContext;
	- line 7: use crate::guardian::GuardianReviewOptions;
	- line 8: use crate::guardian::guardian_timeout_message;
	- line 9: use crate::guardian::new_guardian_review_id;
	- line 10: use crate::guardian::review_approval_request;
	- line 11: use crate::guardian::review_approval_request_with_cancel;
	- line 12: use crate::guardian::routes_approval_policy_to_guardian;
	- line 13: use crate::guardian::spawn_approval_request_review;
	- line 25: use codex_analytics::GuardianApprovalRequestSource;
	- line 30: use codex_protocol::approvals::ExecPolicyAmendment;
	- line 32: use codex_protocol::approvals::GuardianCommandSource;
	- line 39: use codex_protocol::protocol::AskForApproval;
	- line 42: use codex_protocol::protocol::ReviewDecision;
	- line 56: pub(crate) review_context: GuardianReviewContext,
	- line 78: proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 96: source: GuardianCommandSource,
	- line 123: annotations: Option<crate::guardian::GuardianMcpAnnotations>,
	- line 125: approval_policy: AskForApproval,
	- line 139: trigger: Option<GuardianNetworkAccessTrigger>,
	- line 275: pub(crate) fn into_guardian_request(
	- line 277: ) -> std::io::Result<crate::guardian::GuardianApprovalRequest> {
	- line 289: } => crate::guardian::GuardianApprovalRequest::ExecCommand {
	- line 292: cwd: guardian_cwd(&environment_id, cwd)?,
	- line 308: } => crate::guardian::GuardianApprovalRequest::WriteStdin {
	- line 328: } => crate::guardian::GuardianApprovalRequest::Execve {
	- line 343: } => crate::guardian::GuardianApprovalRequest::ApplyPatch {
	- line 345: cwd: guardian_cwd(&environment_id, cwd)?,
	- line 365: } => crate::guardian::GuardianApprovalRequest::McpToolCall {
	- line 387: } => crate::guardian::GuardianApprovalRequest::NetworkAccess {
	- line 401: } => crate::guardian::GuardianApprovalRequest::RequestPermissions {
	- line 411: fn guardian_cwd(environment_id: &str, cwd: PathUri) -> std::io::Result<AbsolutePathBuf> {
	- line 435: Guardian,
	- line 440: fn for_policy(approval_policy: AskForApproval, reviewer: ApprovalsReviewer) -> Self {
	- line 441: if routes_approval_policy_to_guardian(approval_policy, reviewer) {
	- line 442: Self::Guardian
	- line 452: Guardian,
	- line 458: decision: ReviewDecision,
	- line 463: fn into_tool_result(self, model_info: &ModelInfo) -> Result<ReviewDecision, ToolError> {
	- line 466: ReviewDecision::ApprovedMcpPolicyAmendment => {
	- line 472: ReviewDecision::NetworkPolicyAmendment {
	- line 477: ApprovalResolutionSource::Guardian => {
	- line 484: ReviewDecision::Denied { rejection } => Err(ToolError::Rejected(rejection)),
	- line 485: ReviewDecision::TimedOut => {
	- line 486: Err(ToolError::Rejected(guardian_timeout_message(model_info)))
	- line 488: ReviewDecision::Abort => Err(ToolError::Codex(CodexErr::TurnAborted)),
	- line 499: ) -> Result<ReviewDecision, ToolError> {
	- line 502: let policy = ctx.review_context.turn().approval_policy();
	- line 505: && !(ctx.strict_auto_review && matches!(policy, AskForApproval::Never))
	- line 523: // 2. If StrictAutoReview || Guardian enabled, then Guardian. Else, user.
	- line 533: decision: ReviewDecision::Approved,
	- line 537: decision: ReviewDecision::denied(message),
	- line 546: if is_mcp_tool_call && resolution.decision == ReviewDecision::ApprovedMcpPolicyAmendment {
	- line 552: ReviewDecision::NetworkPolicyAmendment {
	- line 559: (ReviewDecision::Abort, ApprovalResolutionSource::Guardian) => {
	- line 576: ApprovalReviewer::Guardian
	- line 578: approval_policy,
	- line 583: ApprovalReviewer::for_policy(*approval_policy, *reviewer)
	- line 586: ctx.review_context.approval_policy,
	- line 592: ApprovalReviewer::Guardian => self.request_guardian_approval(action, ctx).await,
	- line 596: ApprovalReviewer::Guardian => ApprovalResolutionSource::Guardian,
	- line 602: pub(crate) async fn request_guardian_approval(
	- line 606: ) -> ReviewDecision {
	- line 607: // Guardian inherits only the current turn's ready environments. A retained
	- line 617: return ReviewDecision::denied(
	- line 622: let review_id = new_guardian_review_id();
	- line 623: let action = match action.into_guardian_request() {
	- line 627: return ReviewDecision::denied(
	- line 643: GuardianReviewOptions {
	- line 645: approval_request_source: GuardianApprovalRequestSource::MainTurn,
	- line 651: ReviewDecision::denied("automatic approval review could not complete")
	- line 666: GuardianReviewOptions {
	- line 668: approval_request_source: GuardianApprovalRequestSource::MainTurn,
	- line 676: warn!("network Guardian review task failed: {err}");
	- line 677: ReviewDecision::denied("automatic approval review could not complete")
	- line 700: ) -> ReviewDecision {
	- line 711: let cwd = match guardian_cwd(environment_id, cwd.clone()) {
	- line 715: return ReviewDecision::denied(format!(
	- line 731: .and_then(|environment| environment.config().exec_policy.as_ref())
	- line 732: .map(codex_execpolicy::RequirementsExecPolicy::fingerprint);
	- line 785: Some(vec![ReviewDecision::Approved, ReviewDecision::Abort]),
	- line 811: Some(vec![ReviewDecision::Approved, ReviewDecision::Abort]),
	- line 826: return ReviewDecision::Approved;
	- line 889: unreachable!("permission requests are routed directly to Guardian")
	- line 898: ApprovalResolutionSource::Guardian => ToolDecisionSource::AutomatedReviewer,


codex-rs/ext/guardian-v2/src/async_scorer/extension.rs (77 lines):
	- line 10: use codex_core::GuardianRootMessage;
	- line 13: use codex_core::context::GuardianReviewEvidence;
	- line 42: use codex_protocol::protocol::ReviewDecision;
	- line 46: use super::action::GuardianAction;
	- line 49: use super::config::GuardianV2Config;
	- line 50: use super::config::GuardianV2ReviewScope;
	- line 70: review_scope: GuardianV2ReviewScope,
	- line 72: let GuardianV2ReviewScope::Standard {
	- line 99: /// Explains why Guardian v2 requires synchronous approval review.
	- line 106: struct GuardianV2Enabled;
	- line 114: struct GuardianV2ScoreProgress {
	- line 126: struct GuardianV2Extension {
	- line 132: impl ThreadLifecycleContributor<Config> for GuardianV2Extension {
	- line 138: if !input.config.features.enabled(Feature::GuardianV2)
	- line 139: || !input.config.features.enabled(Feature::GuardianApproval)
	- line 145: let guardian_config = match GuardianV2Config::resolve(input.config) {
	- line 183: free_guardian: input.config.free_guardian_enabled(),
	- line 189: if guardian_config.transcript.include_images {
	- line 199: input.thread_store.insert(guardian_config);
	- line 200: input.thread_store.insert(GuardianV2ScoreProgress {
	- line 204: input.thread_store.insert(GuardianReviewEvidence::default());
	- line 208: input.thread_store.insert(GuardianV2Enabled);
	- line 217: impl SkillInvocationContributor for GuardianV2Extension {
	- line 233: let Some(evidence) = input.thread_store.get::<GuardianReviewEvidence>() else {
	- line 241: impl ApprovalReviewContributor for GuardianV2Extension {
	- line 248: ) -> ExtensionFuture<'a, Option<ReviewDecision>> {
	- line 250: thread_store.get::<GuardianV2Enabled>()?;
	- line 251: let guardian_config = thread_store.get::<GuardianV2Config>()?;
	- line 252: if guardian_config.review_scope == GuardianV2ReviewScope::ComputerUseOnly {
	- line 266: // The first REPL execution never waits for synchronous Guardian review.
	- line 274: .get::<GuardianV2ScoreProgress>()?
	- line 284: return Some(ReviewDecision::Approved);
	- line 305: let Some(score_progress) = thread_store.get::<GuardianV2ScoreProgress>() else {
	- line 334: if tool_call_lag > guardian_config.max_tool_call_lag {
	- line 363: if score < guardian_config.review_threshold {
	- line 374: return Some(ReviewDecision::Approved);
	- line 376: if score >= guardian_config.review_threshold {
	- line 387: impl ToolLifecycleContributor for GuardianV2Extension {
	- line 393: impl GuardianV2Extension {
	- line 411: let Some(guardian_config) = input.thread_store.get::<GuardianV2Config>() else {
	- line 414: let Some(score_progress) = input.thread_store.get::<GuardianV2ScoreProgress>() else {
	- line 417: if !should_classify_tool(input.tool_name, input.payload, guardian_config.review_scope) {
	- line 418: if guardian_config.review_scope != GuardianV2ReviewScope::ComputerUseOnly {
	- line 472: message: format!("Guardian V2 risk scoring failed: {error}"),
	- line 479: if guardian_config.review_scope != GuardianV2ReviewScope::ComputerUseOnly
	- line 493: .and_then(|messages| messages.guardian_v2.as_ref());
	- line 494: let guardian_config = match guardian_config.with_model_defaults(model_defaults) {
	- line 511: if guardian_config.transcript.include_images {
	- line 517: input.thread_store.insert(guardian_config.clone());
	- line 518: let parent_compaction = if guardian_config.reuse_parent_compaction {
	- line 521: guardian_config.max_parent_compaction_tokens,
	- line 539: let action = GuardianAction {
	- line 550: let guardian_evidence = input
	- line 552: .get_or_init(GuardianReviewEvidence::default);
	- line 553: let sync_reviews = guardian_evidence.snapshot();
	- line 555: guardian_evidence.authorization_version(input.conversation_history.as_ref());
	- line 557: guardian_evidence.user_input_fragments(input.conversation_history.as_ref());
	- line 558: let transcript = guardian_config
	- line 561: let local_trusted_skill_paths = guardian_evidence.trusted_skill_paths(input.turn_id);
	- line 562: let node_repl_images = if guardian_config.transcript.include_images {
	- line 571: let rendered_images = guardian_config
	- line 583: let root_snapshot = thread.guardian_root_snapshot().await;
	- line 609: let planned_action = match action.render(guardian_config.max_action_tokens) {
	- line 627: message: format!("Guardian V2 action serialization failed: {error}"),
	- line 644: .map(GuardianRootMessage::render),
	- line 677: let review_model_messages = if config.guardian_policy_config.is_none() {
	- line 700: let policy = config.resolve_guardian_policy(review_model_messages.as_ref());
	- line 701: let instructions = guardian_config.render_classifier_instructions(policy);
	- line 712: reasoning_effort: guardian_config.reasoning_effort.clone(),
	- line 727: _ => return Err("invalid Guardian V2 classification".to_owned()),
	- line 763: review_threshold = guardian_config.review_threshold,
	- line 766: "Guardian V2 classification result"
	- line 776: if guardian_config.persist_scores
	- line 787: "failed to persist Guardian V2 classification result"
	- line 816: message: format!("Guardian V2 risk scoring failed: {error}"),
	- line 872: /// Installs feature-gated Guardian V2 tool classification for each thread.
	- line 878: let extension = Arc::new(GuardianV2Extension {


codex-rs/analytics/src/reducer.rs (75 lines):
	- line 48: use crate::events::GuardianReviewEventParams;
	- line 49: use crate::events::GuardianReviewEventPayload;
	- line 50: use crate::events::GuardianReviewEventRequest;
	- line 135: use codex_app_server_protocol::GuardianApprovalReviewAction;
	- line 136: use codex_app_server_protocol::GuardianApprovalReviewStatus;
	- line 245: fn guardian(input: &'a GuardianReviewEventParams) -> Self {
	- line 247: event_name: "guardian",
	- line 342: guardian_review_count: u64,
	- line 621: CustomAnalyticsFact::GuardianReview(input) => {
	- line 622: self.ingest_guardian_review(*input, out);
	- line 1094: // Guardian prewarm can register lineage before parent client metadata is set.
	- line 1103: fn ingest_guardian_review(
	- line 1105: input: GuardianReviewEventParams,
	- line 1109: self.thread_context_or_warn(AnalyticsDropSite::guardian(&input))
	- line 1113: out.push(TrackEventRequest::GuardianReview(Box::new(
	- line 1114: GuardianReviewEventRequest {
	- line 1115: event_type: "codex_guardian_review",
	- line 1116: event_params: GuardianReviewEventPayload {
	- line 1120: guardian_review: input,
	- line 1923: ServerNotification::ItemGuardianApprovalReviewStarted(notification) => {
	- line 1926: ServerNotification::ItemGuardianApprovalReviewCompleted(notification) => {
	- line 1927: self.ingest_guardian_review_completed(notification, out);
	- line 2114: fn ingest_guardian_review_completed(
	- line 2116: notification: codex_app_server_protocol::ItemGuardianApprovalReviewCompletedNotification,
	- line 2119: let Some((status, resolution)) = guardian_review_result(notification.review.status) else {
	- line 2123: guardian_review_subject_metadata(&notification.action);
	- line 2136: requested_additional_permissions: guardian_review_requested_additional_permissions(
	- line 2139: requested_network_access: guardian_review_requested_network_access(
	- line 2148: Reviewer::Guardian,
	- line 2281: Reviewer::Guardian => summary.guardian_review_count += 1,
	- line 2947: guardian_review_count: review_summary.guardian_review_count,
	- line 2979: ReviewResolution::ExecPolicyAmendment,
	- line 3026: fn guardian_review_result(
	- line 3027: status: GuardianApprovalReviewStatus,
	- line 3030: GuardianApprovalReviewStatus::InProgress => None,
	- line 3031: GuardianApprovalReviewStatus::Approved => {
	- line 3034: GuardianApprovalReviewStatus::Denied => {
	- line 3037: GuardianApprovalReviewStatus::TimedOut => {
	- line 3040: GuardianApprovalReviewStatus::Aborted => {
	- line 3046: fn guardian_review_subject_metadata(
	- line 3047: action: &GuardianApprovalReviewAction,
	- line 3050: GuardianApprovalReviewAction::Command { .. } => (
	- line 3055: GuardianApprovalReviewAction::WriteStdin { .. } => (
	- line 3060: GuardianApprovalReviewAction::Execve { .. } => (
	- line 3065: GuardianApprovalReviewAction::ApplyPatch { .. } => (
	- line 3070: GuardianApprovalReviewAction::NetworkAccess { .. } => (
	- line 3075: GuardianApprovalReviewAction::RequestPermissions { permissions, .. } => {
	- line 3094: GuardianApprovalReviewAction::McpToolCall { tool_name, .. } => (
	- line 3102: fn guardian_review_requested_additional_permissions(action: &GuardianApprovalReviewAction) -> bool {
	- line 3104: GuardianApprovalReviewAction::ApplyPatch { .. }
	- line 3105: | GuardianApprovalReviewAction::NetworkAccess { .. } => true,
	- line 3106: GuardianApprovalReviewAction::RequestPermissions { permissions, .. } => {
	- line 3107: guardian_review_request_permissions_network_enabled(permissions)
	- line 3110: GuardianApprovalReviewAction::Command { .. }
	- line 3111: | GuardianApprovalReviewAction::WriteStdin { .. }
	- line 3112: | GuardianApprovalReviewAction::Execve { .. }
	- line 3113: | GuardianApprovalReviewAction::McpToolCall { .. } => false,
	- line 3117: fn guardian_review_requested_network_access(action: &GuardianApprovalReviewAction) -> bool {
	- line 3119: GuardianApprovalReviewAction::NetworkAccess { .. } => true,
	- line 3120: GuardianApprovalReviewAction::RequestPermissions { permissions, .. } => {
	- line 3121: guardian_review_request_permissions_network_enabled(permissions)
	- line 3123: GuardianApprovalReviewAction::ApplyPatch { .. }
	- line 3124: | GuardianApprovalReviewAction::Command { .. }
	- line 3125: | GuardianApprovalReviewAction::WriteStdin { .. }
	- line 3126: | GuardianApprovalReviewAction::Execve { .. }
	- line 3127: | GuardianApprovalReviewAction::McpToolCall { .. } => false,
	- line 3131: fn guardian_review_request_permissions_network_enabled(
	- line 3147: (Reviewer::Guardian, ReviewStatus::Approved, _) => FinalApprovalOutcome::GuardianApproved,
	- line 3148: (Reviewer::Guardian, ReviewStatus::Denied, _) => FinalApprovalOutcome::GuardianDenied,
	- line 3149: (Reviewer::Guardian, _, _) => FinalApprovalOutcome::GuardianAborted,
	- line 3404: approval_policy,
	- line 3448: approval_policy: approval_policy.to_string(),
	- line 3682: fn guardian_review_result_maps_terminal_statuses() {
	- line 3683: assert!(guardian_review_result(GuardianApprovalReviewStatus::InProgress).is_none());
	- line 3685: guardian_review_result(GuardianApprovalReviewStatus::TimedOut),


codex-rs/config/src/config_requirements.rs (74 lines):
	- line 8: use codex_protocol::protocol::AskForApproval;
	- line 21: use super::requirements_exec_policy::RequirementsExecPolicyToml;
	- line 29: use crate::RequirementsExecPolicy;
	- line 170: pub approval_policy: ConstrainedWithSource<AskForApproval>,
	- line 186: pub exec_policy: Option<Sourced<RequirementsExecPolicy>>,
	- line 194: /// Source for the managed guardian policy config, when one is configured.
	- line 195: pub guardian_policy_config_source: Option<RequirementSource>,
	- line 211: approval_policy: ConstrainedWithSource::new(
	- line 242: exec_policy: None,
	- line 250: guardian_policy_config_source: None,
	- line 297: pub fn exec_policy_source(&self) -> Option<&RequirementSource> {
	- line 298: self.exec_policy.as_ref().map(|policy| &policy.source)
	- line 917: pub allowed_approval_policies: Option<Vec<AskForApproval>>,
	- line 939: pub rules: Option<RequirementsExecPolicyToml>,
	- line 947: pub guardian_policy_config: Option<String>,
	- line 1022: pub allowed_approval_policies: Option<Sourced<Vec<AskForApproval>>>,
	- line 1042: pub rules: Option<Sourced<RequirementsExecPolicyToml>>,
	- line 1049: pub guardian_policy_config: Option<Sourced<String>>,
	- line 1109: guardian_policy_config: _,
	- line 1114: .guardian_policy_config
	- line 1118: other.guardian_policy_config = None;
	- line 1160: guardian_policy_config,
	- line 1244: guardian_policy_config,
	- line 1287: guardian_policy_config: guardian_policy_config.map(|sourced| sourced.value),
	- line 1434: .guardian_policy_config
	- line 1464: config.features.get_or_insert_default().guardianv2 = Some(FeatureToml::Enabled(false));
	- line 1610: guardian_policy_config,
	- line 1659: let approval_policy = match allowed_approval_policies {
	- line 1674: field_name: "approval_policy",
	- line 1812: let exec_policy = match rules {
	- line 1815: ConstraintError::ExecPolicyParse {
	- line 1934: let guardian_policy_config_source = guardian_policy_config.map(|sourced| sourced.source);
	- line 1946: approval_policy,
	- line 1962: exec_policy,
	- line 1967: guardian_policy_config_source,
	- line 2147: guardian_policy_config,
	- line 2208: guardian_policy_config: guardian_policy_config
	- line 2610: let allowed_approval_policies = vec![AskForApproval::UnlessTrusted, AskForApproval::Never];
	- line 2666: let guardian_policy_config = "Use the company-managed guardian policy.".to_string();
	- line 2709: guardian_policy_config: Some(guardian_policy_config.clone()),
	- line 2796: guardian_policy_config: Some(Sourced::new(guardian_policy_config, source)),
	- line 2820: vec![AskForApproval::OnRequest],
	- line 2846: guardian_policy_config: None,
	- line 2879: vec![AskForApproval::Never],
	- line 2905: guardian_policy_config: None,
	- line 2913: fn merge_unset_fields_ignores_blank_guardian_override() {
	- line 2918: guardian_policy_config: Some("   \n\t".to_string()),
	- line 2928: guardian_policy_config: Some("Use the system guardian policy.".to_string()),
	- line 2934: target.guardian_policy_config,
	- line 2936: "Use the system guardian policy.".to_string(),
	- line 2946: fn deserialize_guardian_policy_config() -> Result<()> {
	- line 2949: guardian_policy_config = """
	- line 2950: Use the cloud-managed guardian policy.
	- line 2956: requirements.guardian_policy_config.as_deref(),
	- line 2957: Some("Use the cloud-managed guardian policy.\n")
	- line 2963: fn blank_guardian_policy_config_is_empty() -> Result<()> {
	- line 2966: guardian_policy_config = """
	- line 3347: requirements.approval_policy.can_set(&AskForApproval::Never),
	- line 3349: field_name: "approval_policy",
	- line 3402: requirements.approval_policy.can_set(&AskForApproval::Never),
	- line 3404: field_name: "approval_policy",
	- line 3434: requirements.approval_policy.source,
	- line 3470: requirements.approval_policy.value(),
	- line 3471: AskForApproval::OnRequest,
	- line 3476: .approval_policy
	- line 3477: .can_set(&AskForApproval::OnRequest)
	- line 3482: .approval_policy
	- line 3483: .can_set(&AskForApproval::UnlessTrusted),
	- line 3485: field_name: "approval_policy",
	- line 3598: allowed_approvals_reviewers = ["guardian_subagent", "user"]
	- line 4582: fn deserialize_exec_policy_requirements() -> Result<()> {
	- line 4591: let policy = requirements.exec_policy.expect("exec policy").value;
	- line 4612: fn exec_policy_error_includes_requirement_source() -> Result<()> {
	- line 4632: ConstraintError::ExecPolicyParse {


codex-rs/core/src/session/mcp.rs (73 lines):
	- line 45: enum GuardianElicitationReview {
	- line 48: ApprovalRequest(Box<crate::guardian::GuardianApprovalRequest>),
	- line 51: struct GuardianMcpElicitationReviewer {
	- line 67: impl GuardianMcpElicitationReviewer {
	- line 75: impl ElicitationReviewer for GuardianMcpElicitationReviewer {
	- line 85: review_guardian_mcp_elicitation(session, request).await
	- line 520: .get_or_init(|| Arc::new(GuardianMcpElicitationReviewer::new(self))),
	- line 713: async fn review_guardian_mcp_elicitation(
	- line 743: let trusted_guardian_request = if request.server_name == CODEX_APPS_MCP_SERVER_NAME {
	- line 771: crate::mcp_tool_call::build_guardian_mcp_tool_review_request(
	- line 783: .enabled(Feature::GuardianApproval)
	- line 805: let GuardianElicitationReview::ApprovalRequest(guardian_request) =
	- line 806: guardian_elicitation_review_request(&request)
	- line 810: let guardian_request = trusted_guardian_request.unwrap_or(*guardian_request);
	- line 811: let decision = crate::guardian::review_approval_request_with_cancel(
	- line 814: crate::guardian::new_guardian_review_id(),
	- line 815: guardian_request,
	- line 817: crate::guardian::GuardianReviewOptions {
	- line 819: approval_request_source: codex_analytics::GuardianApprovalRequestSource::MainTurn,
	- line 828: ReviewDecision::Approved
	- line 829: | ReviewDecision::Denied { .. }
	- line 830: | ReviewDecision::TimedOut
	- line 831: | ReviewDecision::Abort
	- line 834: mcp_elicitation_response_from_guardian_decision(decision, turn_context.model_info())
	- line 838: let approval_policy = mcp_config.approval_policy.value();
	- line 839: match approval_policy {
	- line 840: AskForApproval::Never => {
	- line 847: approval_policy,
	- line 867: AskForApproval::Granular(config) if !config.allows_mcp_elicitations() => {
	- line 870: AskForApproval::OnRequest | AskForApproval::UnlessTrusted | AskForApproval::Granular(_) => {
	- line 881: if !crate::guardian::routes_approval_policy_to_guardian(approval_policy, approvals_reviewer) {
	- line 885: let guardian_request = match guardian_elicitation_review_request(&request) {
	- line 886: GuardianElicitationReview::NotRequested => return Ok(None),
	- line 887: GuardianElicitationReview::Decline(reason) => {
	- line 892: "declining Guardian MCP elicitation before review"
	- line 896: GuardianElicitationReview::ApprovalRequest(guardian_request) => *guardian_request,
	- line 899: let review_id = crate::guardian::new_guardian_review_id();
	- line 900: let decision = crate::guardian::review_approval_request_with_cancel(
	- line 904: guardian_request,
	- line 906: crate::guardian::GuardianReviewOptions {
	- line 908: approval_request_source: codex_analytics::GuardianApprovalRequestSource::MainTurn,
	- line 914: Ok(Some(mcp_elicitation_response_from_guardian_decision(
	- line 920: fn guardian_elicitation_review_request(
	- line 922: ) -> GuardianElicitationReview {
	- line 933: GuardianElicitationReview::Decline(
	- line 934: "guardian MCP elicitation review only supports form elicitations",
	- line 937: GuardianElicitationReview::NotRequested
	- line 941: return GuardianElicitationReview::Decline(
	- line 942: "guardian MCP elicitation review does not support this elicitation mode",
	- line 946: return GuardianElicitationReview::NotRequested;
	- line 951: return GuardianElicitationReview::NotRequested;
	- line 956: return GuardianElicitationReview::NotRequested;
	- line 961: return GuardianElicitationReview::Decline(
	- line 962: "guardian MCP elicitation metadata must declare mcp_tool_call approval kind",
	- line 966: return GuardianElicitationReview::Decline(
	- line 967: "guardian MCP elicitation review only supports empty form schemas",
	- line 972: return GuardianElicitationReview::Decline(
	- line 973: "guardian MCP elicitation metadata must include a non-empty tool_name",
	- line 979: return GuardianElicitationReview::Decline(
	- line 980: "guardian MCP elicitation tool_params must be an object",
	- line 986: GuardianElicitationReview::ApprovalRequest(Box::new(
	- line 987: crate::guardian::GuardianApprovalRequest::McpToolCall {
	- line 1067: fn mcp_elicitation_response_from_guardian_decision(
	- line 1068: decision: ReviewDecision,
	- line 1072: ReviewDecision::Approved
	- line 1073: | ReviewDecision::ApprovedForSession
	- line 1074: | ReviewDecision::ApprovedMcpPolicyAmendment
	- line 1075: | ReviewDecision::ApprovedExecpolicyAmendment { .. }
	- line 1076: | ReviewDecision::NetworkPolicyAmendment { .. } => ElicitationResponse {
	- line 1081: ReviewDecision::Denied { rejection } => mcp_elicitation_decline_with_message(rejection),
	- line 1082: ReviewDecision::TimedOut => mcp_elicitation_decline_with_message(
	- line 1083: crate::guardian::guardian_timeout_message(model_info),
	- line 1085: ReviewDecision::Abort => ElicitationResponse {


codex-rs/core/src/mcp_tool_call.rs (72 lines):
	- line 9: use crate::guardian::GuardianApprovalRequest;
	- line 10: use crate::guardian::GuardianMcpAnnotations;
	- line 11: use crate::guardian::GuardianReviewContext;
	- line 69: use codex_protocol::protocol::AskForApproval;
	- line 71: use codex_protocol::protocol::ReviewDecision;
	- line 239: let approval_policy = if prepared_call.is_selected_plugin_server() {
	- line 255: approval_policy,
	- line 260: decision @ (ReviewDecision::Approved
	- line 261: | ReviewDecision::ApprovedForSession
	- line 262: | ReviewDecision::ApprovedMcpPolicyAmendment
	- line 263: | ReviewDecision::ApprovedExecpolicyAmendment { .. }
	- line 264: | ReviewDecision::NetworkPolicyAmendment { .. }) => {
	- line 276: policy: approval_policy,
	- line 281: ReviewDecision::Denied { rejection } => {
	- line 293: ReviewDecision::TimedOut => {
	- line 300: crate::guardian::guardian_timeout_message(turn_context.model_info()),
	- line 305: ReviewDecision::Abort => {
	- line 526: prepared_call.config().approval_policy.value(),
	- line 693: approval_policy: AskForApproval,
	- line 711: match approval_policy {
	- line 712: AskForApproval::Never => return result,
	- line 713: AskForApproval::Granular(granular_config) if !granular_config.allows_mcp_elicitations() => {
	- line 716: AskForApproval::OnRequest | AskForApproval::UnlessTrusted | AskForApproval::Granular(_) => {
	- line 1075: decision: ReviewDecision,
	- line 1264: /// waits. Only `node_repl`/`cua_repl` receive them; Guardian sessions are excluded.
	- line 1272: || crate::guardian::is_basic_session_source(&step_context.turn.session_source)
	- line 1373: ) -> Option<ReviewDecision> {
	- line 1394: config.approval_policy.value(),
	- line 1420: return Some(ReviewDecision::Approved);
	- line 1439: .map(|annotations| GuardianMcpAnnotations {
	- line 1445: approval_policy: config.approval_policy.value(),
	- line 1452: review_context: GuardianReviewContext::from(step_context),
	- line 1464: Err(ToolError::Rejected(rejection)) => ReviewDecision::denied(rejection),
	- line 1465: Err(ToolError::Codex(_)) => ReviewDecision::Abort,
	- line 1475: ) -> ReviewDecision {
	- line 1487: approval_policy,
	- line 1497: if *approval_policy == AskForApproval::Never {
	- line 1498: return ReviewDecision::denied(
	- line 1617: pub(crate) fn build_guardian_mcp_tool_review_request(
	- line 1621: ) -> GuardianApprovalRequest {
	- line 1622: GuardianApprovalRequest::McpToolCall {
	- line 1637: .map(|annotations| GuardianMcpAnnotations {
	- line 1934: ) -> ReviewDecision {
	- line 1936: return ReviewDecision::Abort;
	- line 1948: return ReviewDecision::ApprovedForSession;
	- line 1951: return ReviewDecision::ApprovedMcpPolicyAmendment;
	- line 1960: ReviewDecision::Abort => ReviewDecision::Approved,
	- line 1964: ElicitationAction::Decline => ReviewDecision::denied("user rejected MCP tool call"),
	- line 1965: ElicitationAction::Cancel => ReviewDecision::Abort,
	- line 1966: _ => ReviewDecision::Abort,
	- line 2000: ) -> ReviewDecision {
	- line 2002: return ReviewDecision::Abort;
	- line 2009: return ReviewDecision::Abort;
	- line 2015: ReviewDecision::ApprovedForSession
	- line 2020: ReviewDecision::ApprovedMcpPolicyAmendment
	- line 2025: ReviewDecision::Approved
	- line 2027: ReviewDecision::Abort
	- line 2032: decision: ReviewDecision,
	- line 2034: ) -> ReviewDecision {
	- line 2040: ReviewDecision::ApprovedForSession | ReviewDecision::ApprovedMcpPolicyAmendment
	- line 2042: ReviewDecision::Approved
	- line 2050: matches!(store.get(key), Some(ReviewDecision::ApprovedForSession))
	- line 2055: store.put(key, ReviewDecision::ApprovedForSession);
	- line 2061: decision: &ReviewDecision,
	- line 2066: ReviewDecision::ApprovedForSession => {
	- line 2071: ReviewDecision::ApprovedMcpPolicyAmendment => {
	- line 2078: ReviewDecision::Approved
	- line 2079: | ReviewDecision::ApprovedExecpolicyAmendment { .. }
	- line 2080: | ReviewDecision::NetworkPolicyAmendment { .. }
	- line 2081: | ReviewDecision::Denied { .. }
	- line 2082: | ReviewDecision::TimedOut
	- line 2083: | ReviewDecision::Abort => {}


codex-rs/core/src/session/mod.rs (72 lines):
	- line 25: use crate::context::GuardianPolicy;
	- line 34: use crate::exec_policy::BANNED_PREFIX_SUGGESTIONS;
	- line 35: use crate::exec_policy::ExecPolicyManager;
	- line 36: use crate::exec_policy::default_policy_path;
	- line 97: use codex_protocol::approvals::ExecPolicyAmendment;
	- line 282: use crate::exec_policy::ExecPolicyUpdateError;
	- line 283: use crate::guardian::GuardianReviewSessionManager;
	- line 339: use codex_protocol::protocol::AskForApproval;
	- line 353: use codex_protocol::protocol::ReviewDecision;
	- line 433: pub(crate) inherited_exec_policy: Option<Arc<ExecPolicyManager>>,
	- line 537: inherited_exec_policy,
	- line 564: let exec_policy = if crate::guardian::is_basic_session_source(&session_source) {
	- line 568: .exec_policy
	- line 573: Arc::new(ExecPolicyManager::new(Arc::new(managed_policy)))
	- line 574: } else if let Some(exec_policy) = &inherited_exec_policy {
	- line 575: Arc::clone(exec_policy)
	- line 579: .ignore_user_and_project_exec_policy_rules()
	- line 594: ExecPolicyManager::load(&config.config_layer_stack)
	- line 624: let trusted_guardian_reviewer = crate::guardian::is_basic_session_source(&session_source)
	- line 630: && !trusted_guardian_reviewer
	- line 728: approval_policy: config.permissions.approval_policy.clone(),
	- line 747: trusted_guardian_reviewer,
	- line 774: exec_policy,
	- line 1085: exec_policy: &codex_execpolicy::Policy,
	- line 1093: .with_exec_policy_network_rules(exec_policy)
	- line 1150: let current_exec_policy = self.services.exec_policy.current();
	- line 1151: let spec = match spec.with_exec_policy_network_rules(current_exec_policy.as_ref()) {
	- line 1175: current_exec_policy.as_ref(),
	- line 1384: Some(ThreadSource::Subagent | ThreadSource::GuardianReview)
	- line 2045: // Private reviewers have no app-server listener; publicly resumed Guardian threads do.
	- line 2049: if name == crate::guardian::GUARDIAN_REVIEWER_NAME
	- line 2057: .trusted_guardian_reviewer
	- line 2061: .track_guardian_session_event(self.thread_id, &event);
	- line 2397: amendment: &ExecPolicyAmendment,
	- line 2398: ) -> Result<(), ExecPolicyUpdateError> {
	- line 2408: .exec_policy
	- line 2479: .exec_policy
	- line 2553: proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 2555: available_decisions: Option<Vec<ReviewDecision>>,
	- line 2557: ) -> ReviewDecision {
	- line 2628: rx_approve.await.unwrap_or(ReviewDecision::Abort)
	- line 2642: ) -> ReviewDecision {
	- line 2670: rx_approve.await.unwrap_or(ReviewDecision::Abort)
	- line 2686: let approval_policy = step_context.settings.approval_policy();
	- line 2688: match approval_policy {
	- line 2689: AskForApproval::Never => {
	- line 2696: AskForApproval::Granular(granular_config)
	- line 2705: AskForApproval::OnRequest
	- line 2706: | AskForApproval::UnlessTrusted
	- line 2707: | AskForApproval::Granular(_) => {}
	- line 2724: if crate::guardian::routes_approval_policy_to_guardian(approval_policy, approvals_reviewer)
	- line 2737: review_context: crate::guardian::GuardianReviewContext::from(step_context),
	- line 2749: decision = self.request_guardian_approval(
	- line 2755: ReviewDecision::Approved | ReviewDecision::ApprovedExecpolicyAmendment { .. } => {
	- line 2762: ReviewDecision::ApprovedForSession => RequestPermissionsResponse {
	- line 2767: ReviewDecision::NetworkPolicyAmendment {
	- line 2781: ReviewDecision::ApprovedMcpPolicyAmendment
	- line 2782: | ReviewDecision::Abort
	- line 2783: | ReviewDecision::Denied { .. }
	- line 2784: | ReviewDecision::TimedOut => RequestPermissionsResponse {
	- line 3106: pub async fn notify_approval(&self, approval_id: &str, decision: ReviewDecision) {
	- line 3808: let separate_guardian_developer_message =
	- line 3809: crate::guardian::is_basic_session_source(&session_source);
	- line 3810: // Keep the guardian policy prompt out of the aggregated developer bundle so it
	- line 3811: // stays isolated as its own top-level developer message for guardian subagents.
	- line 3812: if !separate_guardian_developer_message
	- line 3999: // Emit the guardian policy prompt as a separate developer item so the guardian
	- line 4001: if separate_guardian_developer_message
	- line 4004: && let Some(guardian_developer_message) =
	- line 4006: GuardianPolicy::new(developer_instructions).render_fragment(),
	- line 4009: items.push(guardian_developer_message);
	- line 4492: && subagent_source.kind() != crate::guardian::GUARDIAN_REVIEWER_NAME


codex-rs/core/src/guardian/mod.rs (63 lines):
	- line 1: //! Guardian review decides whether an `on-request` approval should be granted
	- line 7: //! 2. Ask a dedicated guardian review session to assess the exact planned
	- line 9: //!    The guardian clones the parent config, so it inherits any managed
	- line 12: //! 4. Apply the guardian's explicit allow/deny outcome.
	- line 27: use codex_protocol::protocol::AskForApproval;
	- line 28: use codex_protocol::protocol::GuardianAssessmentOutcome;
	- line 38: pub(crate) use approval_request::GuardianApprovalRequest;
	- line 39: pub(crate) use approval_request::GuardianMcpAnnotations;
	- line 40: pub(crate) use approval_request::GuardianNetworkAccessTrigger;
	- line 42: pub(crate) use approval_request::guardian_approval_request_to_json;
	- line 45: pub(crate) use prompt::guardian_truncate_text;
	- line 46: pub(crate) use review::GuardianReviewOptions;
	- line 47: pub(crate) use review::guardian_timeout_message;
	- line 49: pub(crate) use review::new_guardian_review_id;
	- line 51: pub(crate) use review::record_guardian_denial_for_test;
	- line 54: pub(crate) use review::routes_approval_policy_to_guardian;
	- line 55: pub(crate) use review::routes_approval_to_guardian;
	- line 57: pub(crate) use review_session::GuardianReviewSessionManager;
	- line 61: pub(crate) const GUARDIAN_REVIEWER_NAME: &str = "guardian";
	- line 86: pub(crate) struct GuardianReviewContext {
	- line 89: // Model and reasoning inputs are carried for the follow-up Guardian and V2 migrations.
	- line 96: pub(crate) approval_policy: AskForApproval,
	- line 100: impl GuardianReviewContext {
	- line 110: approval_policy: settings.approval_policy(),
	- line 125: impl From<&Arc<StepContext>> for GuardianReviewContext {
	- line 133: approval_policy: step.settings.approval_policy(),
	- line 139: impl From<Arc<TurnContext>> for GuardianReviewContext {
	- line 146: approval_policy: turn.approval_policy(),
	- line 153: impl From<&Arc<TurnContext>> for GuardianReviewContext {
	- line 159: /// Structured output contract that the guardian reviewer must satisfy.
	- line 161: pub(crate) struct GuardianAssessment {
	- line 162: pub(crate) risk_level: codex_protocol::protocol::GuardianRiskLevel,
	- line 163: pub(crate) user_authorization: codex_protocol::protocol::GuardianUserAuthorization,
	- line 164: pub(crate) outcome: GuardianAssessmentOutcome,
	- line 169: pub(crate) struct GuardianRejectionCircuitBreaker {
	- line 170: turns: std::collections::HashMap<String, GuardianRejectionCircuitBreakerTurn>,
	- line 174: struct GuardianRejectionCircuitBreakerTurn {
	- line 181: pub(crate) enum GuardianRejectionCircuitBreakerPolicy {
	- line 187: pub(crate) enum GuardianRejectionCircuitBreakerAction {
	- line 195: impl GuardianRejectionCircuitBreaker {
	- line 203: policy: GuardianRejectionCircuitBreakerPolicy,
	- line 204: ) -> GuardianRejectionCircuitBreakerAction {
	- line 210: GuardianRejectionCircuitBreakerPolicy::Standard => (
	- line 214: GuardianRejectionCircuitBreakerPolicy::CyberModel => (
	- line 224: GuardianRejectionCircuitBreakerAction::InterruptTurn {
	- line 229: GuardianRejectionCircuitBreakerAction::Continue
	- line 239: fn record_recent_review(turn: &mut GuardianRejectionCircuitBreakerTurn, denied: bool) {
	- line 247: pub(crate) use approval_request::format_guardian_action_pretty;
	- line 249: use approval_request::guardian_assessment_action;
	- line 251: use approval_request::guardian_request_turn_id;
	- line 253: use prompt::GuardianPromptMode;
	- line 255: use prompt::GuardianTranscriptCursor;
	- line 257: use prompt::GuardianTranscriptEntry;
	- line 259: use prompt::GuardianTranscriptEntryKind;
	- line 261: use prompt::build_guardian_prompt_items;
	- line 263: use prompt::build_guardian_prompt_items_with_parent_turn;
	- line 265: use prompt::collect_guardian_transcript_entries;
	- line 267: use prompt::guardian_output_schema;
	- line 269: use prompt::parse_guardian_assessment;
	- line 271: use prompt::render_guardian_transcript_entries;
	- line 273: use review::GuardianReviewOutcome;
	- line 275: use review::run_guardian_review_session_with_retry as run_guardian_review_session_for_test;
	- line 277: use review_session::build_guardian_review_session_config as build_guardian_review_session_config_for_test;


codex-rs/tui/src/chatwidget/tool_requests.rs (61 lines):
	- line 29: /// Handle guardian review lifecycle events for the current thread.
	- line 36: pub(super) fn on_guardian_assessment(&mut self, ev: GuardianAssessmentEvent) {
	- line 45: let guardian_action_summary = |action: &GuardianAssessmentAction| match action {
	- line 46: GuardianAssessmentAction::Command { command, .. } => Some(command.clone()),
	- line 47: GuardianAssessmentAction::Execve { program, argv, .. } => {
	- line 57: GuardianAssessmentAction::WriteStdin { .. } => {
	- line 60: GuardianAssessmentAction::ApplyPatch { files, .. } => Some(if files.len() == 1 {
	- line 65: GuardianAssessmentAction::NetworkAccess { target, .. } => {
	- line 68: GuardianAssessmentAction::McpToolCall {
	- line 77: GuardianAssessmentAction::RequestPermissions { reason, .. } => {
	- line 81: let guardian_command = |action: &GuardianAssessmentAction| match action {
	- line 82: GuardianAssessmentAction::Command { command, .. } => shlex::split(command)
	- line 85: GuardianAssessmentAction::Execve { program, argv, .. } => Some(if argv.is_empty() {
	- line 91: GuardianAssessmentAction::WriteStdin { .. }
	- line 92: | GuardianAssessmentAction::ApplyPatch { .. }
	- line 93: | GuardianAssessmentAction::NetworkAccess { .. }
	- line 94: | GuardianAssessmentAction::McpToolCall { .. }
	- line 95: | GuardianAssessmentAction::RequestPermissions { .. } => None,
	- line 98: if ev.status == GuardianAssessmentStatus::InProgress
	- line 99: && let Some(detail) = guardian_action_summary(&ev.action)
	- line 103: // footer summary by `PendingGuardianReviewStatus`.
	- line 108: .pending_guardian_review_status
	- line 112: .pending_guardian_review_status
	- line 130: .pending_guardian_review_status
	- line 135: .pending_guardian_review_status
	- line 144: } else if self.status_state.current_status.is_guardian_review() {
	- line 147: } else if self.status_state.pending_guardian_review_status.is_empty()
	- line 148: && self.status_state.current_status.is_guardian_review()
	- line 153: if ev.status == GuardianAssessmentStatus::Approved {
	- line 158: if ev.status == GuardianAssessmentStatus::TimedOut {
	- line 159: let cell = if let Some(command) = guardian_command(&ev.action) {
	- line 162: crate::history_cell::ReviewDecision::TimedOut,
	- line 163: history_cell::ApprovalDecisionActor::Guardian,
	- line 167: GuardianAssessmentAction::WriteStdin { .. } => {
	- line 168: history_cell::new_guardian_timed_out_action_request(format!(
	- line 173: GuardianAssessmentAction::ApplyPatch { files, .. } => {
	- line 178: history_cell::new_guardian_timed_out_patch_request(files)
	- line 180: GuardianAssessmentAction::McpToolCall {
	- line 182: } => history_cell::new_guardian_timed_out_action_request(format!(
	- line 185: GuardianAssessmentAction::NetworkAccess { target, .. } => {
	- line 186: history_cell::new_guardian_timed_out_action_request(format!(
	- line 190: GuardianAssessmentAction::RequestPermissions { reason, .. } => {
	- line 191: history_cell::new_guardian_timed_out_action_request(
	- line 195: GuardianAssessmentAction::Command { .. } => unreachable!(),
	- line 196: GuardianAssessmentAction::Execve { .. } => unreachable!(),
	- line 205: if ev.status != GuardianAssessmentStatus::Denied {
	- line 209: let cell = if let Some(command) = guardian_command(&ev.action) {
	- line 212: crate::history_cell::ReviewDecision::Denied,
	- line 213: history_cell::ApprovalDecisionActor::Guardian,
	- line 217: GuardianAssessmentAction::WriteStdin { .. } => {
	- line 218: history_cell::new_guardian_denied_action_request(format!(
	- line 223: GuardianAssessmentAction::ApplyPatch { files, .. } => {
	- line 228: history_cell::new_guardian_denied_patch_request(files)
	- line 230: GuardianAssessmentAction::McpToolCall {
	- line 232: } => history_cell::new_guardian_denied_action_request(format!(
	- line 235: GuardianAssessmentAction::NetworkAccess { target, .. } => {
	- line 236: history_cell::new_guardian_denied_action_request(format!(
	- line 240: GuardianAssessmentAction::RequestPermissions { reason, .. } => {
	- line 241: history_cell::new_guardian_denied_action_request(permission_request_summary(
	- line 246: GuardianAssessmentAction::Command { .. } => unreachable!(),
	- line 247: GuardianAssessmentAction::Execve { .. } => unreachable!(),


codex-rs/protocol/src/protocol.rs (51 lines):
	- line 85: pub use crate::approvals::ExecPolicyAmendment;
	- line 86: pub use crate::approvals::GuardianAssessmentAction;
	- line 87: pub use crate::approvals::GuardianAssessmentDecisionSource;
	- line 88: pub use crate::approvals::GuardianAssessmentEvent;
	- line 89: pub use crate::approvals::GuardianAssessmentOutcome;
	- line 90: pub use crate::approvals::GuardianAssessmentStatus;
	- line 91: pub use crate::approvals::GuardianCommandSource;
	- line 92: pub use crate::approvals::GuardianRiskLevel;
	- line 93: pub use crate::approvals::GuardianUserAuthorization;
	- line 511: pub approval_policy: Option<AskForApproval>,
	- line 650: decision: ReviewDecision,
	- line 658: decision: ReviewDecision,
	- line 728: /// Record that the user approved one retry of a concrete Guardian-denied action.
	- line 729: ApproveGuardianDeniedAction { event: GuardianAssessmentEvent },
	- line 940: Self::ApproveGuardianDeniedAction { .. } => "approve_guardian_denied_action",
	- line 965: pub enum AskForApproval {
	- line 1351: /// Warning issued by the guardian automatic approval reviewer.
	- line 1352: GuardianWarning(WarningEvent),
	- line 1478: /// Structured lifecycle event for a guardian-reviewed approval request.
	- line 1479: GuardianAssessment(GuardianAssessmentEvent),
	- line 2175: pub approval_policy: AskForApproval,
	- line 2720: GuardianReview,
	- line 2730: ThreadSource::GuardianReview => "guardian_review",
	- line 2764: "guardian_review" => Ok(ThreadSource::GuardianReview),
	- line 2776: Guardian,
	- line 2949: InternalSessionSource::Guardian => f.write_str("guardian"),
	- line 3170: pub approval_policy: AskForApproval,
	- line 3834: pub approval_policy: AskForApproval,
	- line 3893: approval_policy: AskForApproval,
	- line 3932: approval_policy: wire.approval_policy,
	- line 4008: pub enum ReviewDecision {
	- line 4015: proposed_execpolicy_amendment: ExecPolicyAmendment,
	- line 4045: impl Default for ReviewDecision {
	- line 4053: impl ReviewDecision {
	- line 4064: ReviewDecision::Approved => "approved",
	- line 4065: ReviewDecision::ApprovedExecpolicyAmendment { .. } => "approved_with_amendment",
	- line 4066: ReviewDecision::ApprovedForSession => "approved_for_session",
	- line 4067: ReviewDecision::ApprovedMcpPolicyAmendment => "approved_mcp_policy_amendment",
	- line 4068: ReviewDecision::NetworkPolicyAmendment {
	- line 4074: ReviewDecision::Denied { .. } => "denied",
	- line 4075: ReviewDecision::TimedOut => "timed_out",
	- line 4076: ReviewDecision::Abort => "abort",
	- line 4396: let decision = ReviewDecision::Denied {
	- line 4402: assert_eq!(serde_json::from_value::<ReviewDecision>(value)?, decision);
	- line 5930: "approval_policy": "never",
	- line 5946: "approval_policy": "on-failure",
	- line 5952: assert_eq!(item.approval_policy, AskForApproval::OnRequest);
	- line 5964: approval_policy: AskForApproval::Never,
	- line 6041: approval_policy: AskForApproval::Never,
	- line 6061: "approval_policy": "never",
	- line 6080: "approval_policy": "never",


codex-rs/core/src/tools/runtimes/zsh_fork/unix_escalation.rs (50 lines):
	- line 3: use crate::guardian::GuardianReviewContext;
	- line 23: use codex_protocol::protocol::AskForApproval;
	- line 24: use codex_protocol::protocol::GuardianCommandSource;
	- line 26: use codex_protocol::protocol::ReviewDecision;
	- line 64: "approval required by policy, but AskForApproval is set to Never";
	- line 66: "approval required by policy, but AskForApproval::Granular.sandbox_approval is false";
	- line 68: "approval required by policy rule, but AskForApproval::Granular.rules is false";
	- line 109: let exec_policy = Arc::new(RwLock::new(
	- line 112: .exec_policy
	- line 114: req.turn_environment.config().exec_policy.as_ref(),
	- line 146: policy: Arc::clone(&exec_policy),
	- line 148: review_context: GuardianReviewContext::from(&ctx.step_context),
	- line 151: source: GuardianCommandSource::UnifiedExec,
	- line 153: approval_policy: ctx.step_context.settings.approval_policy(),
	- line 183: review_context: GuardianReviewContext,
	- line 186: source: GuardianCommandSource,
	- line 188: approval_policy: AskForApproval,
	- line 204: approval_policy: AskForApproval,
	- line 207: match (approval_policy, decision_source) {
	- line 208: (AskForApproval::Never, _) => Some(PROMPT_CONFLICT_REASON),
	- line 209: (AskForApproval::Granular(granular_config), DecisionSource::PrefixRule)
	- line 214: (AskForApproval::Granular(granular_config), DecisionSource::UnmatchedCommandFallback)
	- line 268: ) -> anyhow::Result<ReviewDecision> {
	- line 294: review_context: GuardianReviewContext::from_resolved_settings(
	- line 312: Err(ToolError::Rejected(rejection)) => Ok(ReviewDecision::denied(rejection)),
	- line 334: if execve_prompt_is_rejected_by_policy(self.approval_policy, &decision_source)
	- line 343: ReviewDecision::Approved
	- line 344: | ReviewDecision::ApprovedForSession
	- line 345: | ReviewDecision::ApprovedExecpolicyAmendment { .. } => {
	- line 352: ReviewDecision::NetworkPolicyAmendment {
	- line 366: ReviewDecision::Denied { rejection } => {
	- line 369: ReviewDecision::TimedOut => EscalationDecision::deny(Some(
	- line 370: crate::guardian::guardian_timeout_message(
	- line 374: ReviewDecision::ApprovedMcpPolicyAmendment => {
	- line 381: ReviewDecision::Abort => {
	- line 421: evaluate_intercepted_exec_policy(
	- line 425: InterceptedExecPolicyContext {
	- line 426: approval_policy: self.approval_policy,
	- line 488: fn evaluate_intercepted_exec_policy(
	- line 492: context: InterceptedExecPolicyContext,
	- line 494: let InterceptedExecPolicyContext {
	- line 495: approval_policy,
	- line 505: commands_for_intercepted_exec_policy(program, argv)
	- line 513: crate::exec_policy::render_decision_for_unmatched_command(
	- line 515: crate::exec_policy::UnmatchedCommandContext {
	- line 516: approval_policy,
	- line 520: command_origin: crate::exec_policy::ExecPolicyCommandOrigin::Generic,
	- line 535: struct InterceptedExecPolicyContext {
	- line 536: approval_policy: AskForApproval,
	- line 545: fn commands_for_intercepted_exec_policy(


codex-rs/core/src/config/mod.rs (50 lines):
	- line 4: use crate::guardian::BUNDLED_GUARDIAN_POLICY;
	- line 124: use codex_protocol::protocol::AskForApproval;
	- line 205: #[error("approval_policy = \"untrusted\" is no longer supported; remove this setting")]
	- line 304: pub approval_policy: Constrained<AskForApproval>,
	- line 337: approval_policy: Constrained<AskForApproval>,
	- line 341: approval_policy,
	- line 681: /// Guardian-specific policy config override from requirements.toml or config.toml.
	- line 682: /// This is inserted into the fixed guardian prompt template under the
	- line 684: /// guardian developer prompt.
	- line 685: pub guardian_policy_config: Option<String>,
	- line 1503: /// Whether Guardian may use the unmetered Codex inference endpoints.
	- line 1504: pub fn free_guardian_enabled(&self) -> bool {
	- line 1508: .and_then(|features| features.get("guardianv2"))
	- line 1509: .and_then(|guardian| guardian.get("free_guardian"))
	- line 1514: /// Resolves the configured, reviewer-catalog, or bundled Guardian policy.
	- line 1515: pub fn resolve_guardian_policy<'a>(
	- line 1519: self.guardian_policy_config
	- line 1746: approval_policy: self.permissions.approval_policy.clone(),
	- line 1823: .with_user_and_project_exec_policy_rules_ignored(
	- line 1826: .ignore_user_and_project_exec_policy_rules(),
	- line 1902: /// designed to use [AskForApproval::Never] exclusively.
	- line 2559: pub approval_policy: Option<AskForApproval>,
	- line 3192: approval_policy: mut constrained_approval_policy,
	- line 3208: exec_policy: _,
	- line 3213: guardian_policy_config_source: _,
	- line 3221: approval_policy: approval_policy_override,
	- line 3623: if cfg.approval_policy == Some(AskForApproval::UnlessTrusted) {
	- line 3629: let approval_policy_was_explicit =
	- line 3630: approval_policy_override.is_some() || cfg.approval_policy.is_some();
	- line 3631: let mut approval_policy = approval_policy_override
	- line 3632: .or(cfg.approval_policy)
	- line 3635: AskForApproval::OnRequest
	- line 3637: AskForApproval::UnlessTrusted
	- line 3639: AskForApproval::default()
	- line 3642: if !approval_policy_was_explicit
	- line 3643: && let Err(err) = constrained_approval_policy.can_set(&approval_policy)
	- line 3649: approval_policy = constrained_approval_policy.value();
	- line 3905: let guardian_policy_config =
	- line 3906: guardian_policy_config_from_requirements(config_layer_stack.requirements_toml())
	- line 3910: .and_then(|auto_review| normalize_guardian_policy_config(
	- line 3959: "approval_policy",
	- line 3960: approval_policy,
	- line 3961: &mut constrained_approval_policy,
	- line 3997: && constrained_approval_policy.value() == AskForApproval::Never
	- line 4001: "`approval_policy = \"never\"` cannot be used because requirements do not allow `sandbox_mode = \"danger-full-access\"`; Codex would fall back to read-only permissions with approvals disabled. Choose an `approval_policy` based on what you need, such as `on-request`, or choose an allowed sandbox mode.",
	- line 4139: approval_policy: constrained_approval_policy.value,
	- line 4246: guardian_policy_config,
	- line 4537: fn guardian_policy_config_from_requirements(
	- line 4540: normalize_guardian_policy_config(requirements_toml.guardian_policy_config.as_deref())
	- line 4725: fn normalize_guardian_policy_config(value: Option<&str>) -> Option<String> {


codex-rs/tui/src/app/config_persistence.rs (49 lines):
	- line 124: approval_policy,
	- line 150: if let Some(policy) = approval_policy
	- line 151: && !self.try_set_approval_policy_on_config(
	- line 185: if let Some(policy) = approval_policy {
	- line 186: self.runtime_approval_policy_override = Some(policy);
	- line 187: self.chat_widget.set_approval_policy(policy);
	- line 214: approval_policy,
	- line 301: if let Some(policy) = self.runtime_approval_policy_override.as_ref()
	- line 302: && let Err(err) = config.permissions.approval_policy.set(policy.to_core())
	- line 336: pub(super) fn try_set_approval_policy_on_config(
	- line 339: policy: AskForApproval,
	- line 343: if let Err(err) = config.permissions.approval_policy.set(policy.to_core()) {
	- line 407: let mut approval_policy_override = None;
	- line 431: if feature == Feature::GuardianApproval {
	- line 456: if feature == Feature::GuardianApproval && effective_enabled {
	- line 460: // makes guardian review observable in the current thread.
	- line 461: if !self.try_set_approval_policy_on_config(
	- line 463: auto_review_preset.approval_policy,
	- line 481: "approval_policy",
	- line 489: approval_policy_override = Some(auto_review_preset.approval_policy);
	- line 569: if approval_policy_override.is_some() {
	- line 570: self.chat_widget.set_approval_policy(AskForApproval::from(
	- line 571: self.config.permissions.approval_policy.value(),
	- line 599: if approval_policy_override.is_some()
	- line 612: approval_policy_override,
	- line 917: .any(|(feature, _)| *feature == Feature::GuardianApproval)
	- line 918: && !self.config.features.enabled(Feature::GuardianApproval)
	- line 927: if let Some(policy) = approval_policy_from_effective_config(effective_config) {
	- line 931: .approval_policy
	- line 942: self.chat_widget.set_approval_policy(policy);
	- line 954: .any(|(feature, _)| *feature == Feature::GuardianApproval)
	- line 955: || !self.config.features.enabled(Feature::GuardianApproval)
	- line 995: let approval_policy = AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 998: Some(approval_policy),
	- line 1077: /*approval_policy*/ None,
	- line 1125: fn approval_policy_from_effective_config(
	- line 1127: ) -> Option<AskForApproval> {
	- line 1128: effective_config.config.approval_policy
	- line 1491: let required_policy = codex_protocol::protocol::AskForApproval::Never;
	- line 1526: assert_eq!(config.permissions.approval_policy.value(), required_policy);
	- line 1576: approval_policy: AskForApproval::Never,
	- line 1623: async fn overridden_disabled_guardian_does_not_apply_auto_review_companions() -> Result<()> {
	- line 1625: let original_policy = app.config.permissions.approval_policy.value();
	- line 1628: "approval_policy": AskForApproval::OnRequest,
	- line 1632: "guardian_approval": false,
	- line 1640: &[(Feature::GuardianApproval, /*enabled*/ true)],
	- line 1643: assert!(!app.config.features.enabled(Feature::GuardianApproval));
	- line 1648: .enabled(Feature::GuardianApproval)
	- line 1656: app.config.permissions.approval_policy.value(),


codex-rs/protocol/src/approvals.rs (46 lines):
	- line 6: use crate::protocol::ReviewDecision;
	- line 42: pub struct ExecPolicyAmendment {
	- line 46: impl ExecPolicyAmendment {
	- line 56: impl From<Vec<String>> for ExecPolicyAmendment {
	- line 89: pub enum GuardianRiskLevel {
	- line 98: pub enum GuardianUserAuthorization {
	- line 105: /// Final allow/deny outcome returned by the guardian reviewer.
	- line 108: pub enum GuardianAssessmentOutcome {
	- line 115: pub enum GuardianAssessmentStatus {
	- line 125: pub enum GuardianAssessmentDecisionSource {
	- line 131: pub enum GuardianCommandSource {
	- line 139: pub enum GuardianAssessmentAction {
	- line 141: source: GuardianCommandSource,
	- line 146: source: GuardianCommandSource,
	- line 189: pub struct GuardianAssessmentEvent {
	- line 190: /// Stable identifier for this guardian review lifecycle.
	- line 214: pub status: GuardianAssessmentStatus,
	- line 218: pub risk_level: Option<GuardianRiskLevel>,
	- line 222: pub user_authorization: Option<GuardianUserAuthorization>,
	- line 230: pub decision_source: Option<GuardianAssessmentDecisionSource>,
	- line 232: pub action: GuardianAssessmentAction,
	- line 296: pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 311: pub available_decisions: Option<Vec<ReviewDecision>>,
	- line 322: pub fn effective_available_decisions(&self) -> Vec<ReviewDecision> {
	- line 338: proposed_execpolicy_amendment: Option<&ExecPolicyAmendment>,
	- line 341: ) -> Vec<ReviewDecision> {
	- line 343: let mut decisions = vec![ReviewDecision::Approved, ReviewDecision::ApprovedForSession];
	- line 349: decisions.push(ReviewDecision::NetworkPolicyAmendment {
	- line 353: decisions.push(ReviewDecision::Abort);
	- line 358: return vec![ReviewDecision::Approved, ReviewDecision::Abort];
	- line 361: let mut decisions = vec![ReviewDecision::Approved];
	- line 363: decisions.push(ReviewDecision::ApprovedExecpolicyAmendment {
	- line 367: decisions.push(ReviewDecision::Abort);
	- line 458: fn guardian_assessment_action_deserializes_command_shape() {
	- line 459: let action: GuardianAssessmentAction = serde_json::from_value(serde_json::json!({
	- line 462: "command": "rm -rf /tmp/guardian",
	- line 465: .expect("guardian action");
	- line 469: GuardianAssessmentAction::Command {
	- line 470: source: GuardianCommandSource::Shell,
	- line 471: command: "rm -rf /tmp/guardian".to_string(),
	- line 479: fn guardian_assessment_action_round_trips_execve_shape() {
	- line 487: let action: GuardianAssessmentAction =
	- line 488: serde_json::from_value(value.clone()).expect("guardian action");
	- line 491: serde_json::to_value(&action).expect("serialize guardian action"),
	- line 497: GuardianAssessmentAction::Execve {
	- line 498: source: GuardianCommandSource::Shell,


codex-rs/app-server-protocol/src/protocol/item_builders.rs (42 lines):
	- line 13: use crate::protocol::v2::AutoReviewDecisionSource;
	- line 18: use crate::protocol::v2::GuardianApprovalReview;
	- line 19: use crate::protocol::v2::GuardianApprovalReviewStatus;
	- line 20: use crate::protocol::v2::ItemGuardianApprovalReviewCompletedNotification;
	- line 21: use crate::protocol::v2::ItemGuardianApprovalReviewStartedNotification;
	- line 31: use codex_protocol::protocol::GuardianAssessmentAction;
	- line 32: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 184: /// Build a guardian-derived [`ThreadItem`].
	- line 187: /// [`GuardianAssessmentAction::Command`] and [`GuardianAssessmentAction::Execve`].
	- line 189: pub fn build_item_from_guardian_event(
	- line 190: assessment: &GuardianAssessmentEvent,
	- line 194: GuardianAssessmentAction::Command { command, cwd, .. } => {
	- line 215: GuardianAssessmentAction::Execve {
	- line 253: GuardianAssessmentAction::WriteStdin { .. }
	- line 254: | GuardianAssessmentAction::ApplyPatch { .. }
	- line 255: | GuardianAssessmentAction::NetworkAccess { .. }
	- line 256: | GuardianAssessmentAction::McpToolCall { .. }
	- line 257: | GuardianAssessmentAction::RequestPermissions { .. } => None,
	- line 261: pub fn guardian_auto_approval_review_notification(
	- line 264: assessment: &GuardianAssessmentEvent,
	- line 271: let review = GuardianApprovalReview {
	- line 273: codex_protocol::protocol::GuardianAssessmentStatus::InProgress => {
	- line 274: GuardianApprovalReviewStatus::InProgress
	- line 276: codex_protocol::protocol::GuardianAssessmentStatus::Approved => {
	- line 277: GuardianApprovalReviewStatus::Approved
	- line 279: codex_protocol::protocol::GuardianAssessmentStatus::Denied => {
	- line 280: GuardianApprovalReviewStatus::Denied
	- line 282: codex_protocol::protocol::GuardianAssessmentStatus::TimedOut => {
	- line 283: GuardianApprovalReviewStatus::TimedOut
	- line 285: codex_protocol::protocol::GuardianAssessmentStatus::Aborted => {
	- line 286: GuardianApprovalReviewStatus::Aborted
	- line 295: codex_protocol::protocol::GuardianAssessmentStatus::InProgress => {
	- line 296: ServerNotification::ItemGuardianApprovalReviewStarted(
	- line 297: ItemGuardianApprovalReviewStartedNotification {
	- line 308: codex_protocol::protocol::GuardianAssessmentStatus::Approved
	- line 309: | codex_protocol::protocol::GuardianAssessmentStatus::Denied
	- line 310: | codex_protocol::protocol::GuardianAssessmentStatus::TimedOut
	- line 311: | codex_protocol::protocol::GuardianAssessmentStatus::Aborted => {
	- line 312: ServerNotification::ItemGuardianApprovalReviewCompleted(
	- line 313: ItemGuardianApprovalReviewCompletedNotification {
	- line 324: .map(AutoReviewDecisionSource::from)
	- line 325: .unwrap_or(AutoReviewDecisionSource::Agent),


codex-rs/app-server-protocol/src/protocol/v2/tests.rs (42 lines):
	- line 4: use codex_protocol::approvals::GuardianAssessmentAction as CoreGuardianAssessmentAction;
	- line 40: use codex_protocol::protocol::AskForApproval as CoreAskForApproval;
	- line 173: (ThreadSource::GuardianReview, "guardian_review"),
	- line 194: fn approvals_reviewer_serializes_auto_review_and_accepts_legacy_guardian_subagent() {
	- line 204: for value in ["user", "auto_review", "guardian_subagent"] {
	- line 313: approval_policy: AskForApproval::OnRequest,
	- line 1950: let v2_policy = AskForApproval::Granular {
	- line 1961: CoreAskForApproval::Granular(CoreGranularApprovalConfig {
	- line 1970: let back_to_v2 = AskForApproval::from(core_policy);
	- line 1976: let decoded = serde_json::from_value::<AskForApproval>(serde_json::json!({
	- line 1987: AskForApproval::Granular {
	- line 2000: crate::experimental_api::ExperimentalApi::experimental_reason(&AskForApproval::Granular {
	- line 2010: crate::experimental_api::ExperimentalApi::experimental_reason(&AskForApproval::OnRequest,),
	- line 2016: fn config_granular_approval_policy_is_marked_experimental() {
	- line 2024: approval_policy: Some(AskForApproval::Granular {
	- line 2065: approval_policy: None,
	- line 2092: fn config_requirements_granular_allowed_approval_policy_is_marked_experimental() {
	- line 2098: allowed_approval_policies: Some(vec![AskForApproval::Granular {
	- line 2165: fn client_request_thread_start_granular_approval_policy_is_marked_experimental() {
	- line 2170: approval_policy: Some(AskForApproval::Granular {
	- line 2186: fn client_request_thread_resume_granular_approval_policy_is_marked_experimental() {
	- line 2192: approval_policy: Some(AskForApproval::Granular {
	- line 2208: fn client_request_thread_fork_granular_approval_policy_is_marked_experimental() {
	- line 2214: approval_policy: Some(AskForApproval::Granular {
	- line 2230: fn client_request_turn_start_granular_approval_policy_is_marked_experimental() {
	- line 2238: approval_policy: Some(AskForApproval::Granular {
	- line 2817: let review: GuardianApprovalReview = serde_json::from_value(json!({
	- line 2826: GuardianApprovalReview {
	- line 2827: status: GuardianApprovalReviewStatus::Aborted,
	- line 2836: fn guardian_approval_review_action_round_trips_command_shape() {
	- line 2843: let action: GuardianApprovalReviewAction =
	- line 2844: serde_json::from_value(value.clone()).expect("guardian review action");
	- line 2848: GuardianApprovalReviewAction::Command {
	- line 2849: source: GuardianCommandSource::Shell,
	- line 2855: serde_json::to_value(&action).expect("serialize guardian review action"),
	- line 2861: fn guardian_stdin_review_action_round_trips_native_and_foreign_paths() {
	- line 2870: let core_action = CoreGuardianAssessmentAction::WriteStdin {
	- line 2876: let action = GuardianApprovalReviewAction::from(core_action.clone());
	- line 2889: let deserialized: GuardianApprovalReviewAction =
	- line 2893: CoreGuardianAssessmentAction::try_from(deserialized)
	- line 4754: approval_policy: None,
	- line 4886: approval_policy: Some(AskForApproval::Granular {


codex-rs/app-server/src/request_processors/thread_processor.rs (40 lines):
	- line 143: if let Some(requested_approval) = request.approval_policy.as_ref() {
	- line 144: let active_approval: AskForApproval = config_snapshot.approval_policy.into();
	- line 147: "approval_policy requested={requested_approval:?} active={active_approval:?}"
	- line 932: pub(crate) async fn thread_approve_guardian_denied_action(
	- line 935: params: ThreadApproveGuardianDeniedActionParams,
	- line 937: self.thread_approve_guardian_denied_action_inner(request_id, params)
	- line 1123: approval_policy,
	- line 1185: approval_policy,
	- line 1390: let notification = crate::exec_policy_config_warning(&err);
	- line 1570: approval_policy: config_snapshot.approval_policy.into(),
	- line 1611: approval_policy: Option<codex_app_server_protocol::AskForApproval>,
	- line 1626: approval_policy: approval_policy
	- line 1627: .map(codex_app_server_protocol::AskForApproval::to_core),
	- line 2476: async fn thread_approve_guardian_denied_action_inner(
	- line 2479: params: ThreadApproveGuardianDeniedActionParams,
	- line 2480: ) -> Result<ThreadApproveGuardianDeniedActionResponse, JSONRPCErrorError> {
	- line 2481: let ThreadApproveGuardianDeniedActionParams { thread_id, event } = params;
	- line 2483: .map_err(|err| invalid_request(format!("invalid Guardian denial event: {err}")))?;
	- line 2490: Op::ApproveGuardianDeniedAction { event },
	- line 2493: .map_err(|err| internal_error(format!("failed to approve Guardian denial: {err}")))?;
	- line 2494: Ok(ThreadApproveGuardianDeniedActionResponse {})
	- line 3641: approval_policy,
	- line 3764: approval_policy,
	- line 3772: if typesafe_overrides.approval_policy.is_none()
	- line 3775: .and_then(|overrides| overrides.remove("approval_policy"))
	- line 3777: let approval_policy = match serde_json::from_value(value) {
	- line 3778: Ok(approval_policy) => approval_policy,
	- line 3784: "invalid `approval_policy` config override: {err}"
	- line 3791: typesafe_overrides.approval_policy = Some(approval_policy);
	- line 4011: approval_policy: session_configured.approval_policy.into(),
	- line 4070: if typesafe_overrides.approval_policy.is_none() {
	- line 4071: typesafe_overrides.approval_policy = Some(persisted_settings.approval_policy);
	- line 4700: approval_policy,
	- line 4838: approval_policy,
	- line 4847: let restore_approval_policy = typesafe_overrides.approval_policy.is_none();
	- line 4855: restore_approval_policy || restore_approvals_reviewer || restore_permission_profile;
	- line 4860: approval_policy: snapshot.approval_policy,
	- line 4896: if restore_approval_policy {
	- line 4897: typesafe_overrides.approval_policy = Some(persisted_settings.approval_policy);
	- line 5169: approval_policy: session_configured.approval_policy.into(),


codex-rs/app-server-protocol/src/protocol/thread_history.rs (36 lines):
	- line 6: use crate::protocol::item_builders::build_item_from_guardian_event;
	- line 42: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 43: use codex_protocol::protocol::GuardianAssessmentStatus;
	- line 339: EventMsg::GuardianAssessment(payload) => self.handle_guardian_assessment(payload),
	- line 667: fn handle_guardian_assessment(&mut self, payload: &GuardianAssessmentEvent) {
	- line 669: GuardianAssessmentStatus::InProgress => CommandExecutionStatus::InProgress,
	- line 670: GuardianAssessmentStatus::Denied | GuardianAssessmentStatus::Aborted => {
	- line 673: GuardianAssessmentStatus::TimedOut => CommandExecutionStatus::Failed,
	- line 674: GuardianAssessmentStatus::Approved => return,
	- line 676: let Some(item) = build_item_from_guardian_event(payload, status) else {
	- line 3292: fn reconstructs_declined_guardian_command_item() {
	- line 3309: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 3310: id: "review-guardian-exec".into(),
	- line 3311: target_item_id: Some("guardian-exec".into()),
	- line 3317: status: GuardianAssessmentStatus::InProgress,
	- line 3325: "command": "rm -rf /tmp/guardian",
	- line 3328: .expect("guardian action"),
	- line 3330: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 3331: id: "review-guardian-exec".into(),
	- line 3332: target_item_id: Some("guardian-exec".into()),
	- line 3338: status: GuardianAssessmentStatus::Denied,
	- line 3339: risk_level: Some(codex_protocol::protocol::GuardianRiskLevel::High),
	- line 3340: user_authorization: Some(codex_protocol::protocol::GuardianUserAuthorization::Low),
	- line 3343: codex_protocol::protocol::GuardianAssessmentDecisionSource::Agent,
	- line 3348: "command": "rm -rf /tmp/guardian",
	- line 3351: .expect("guardian action"),
	- line 3365: id: "guardian-exec".into(),
	- line 3368: command: "rm -rf /tmp/guardian".into(),
	- line 3374: command: "rm -rf /tmp/guardian".into(),
	- line 3384: fn reconstructs_in_progress_guardian_execve_item() {
	- line 3401: EventMsg::GuardianAssessment(GuardianAssessmentEvent {
	- line 3402: id: "review-guardian-execve".into(),
	- line 3403: target_item_id: Some("guardian-execve".into()),
	- line 3409: status: GuardianAssessmentStatus::InProgress,
	- line 3421: .expect("guardian action"),
	- line 3435: id: "guardian-execve".into(),


codex-rs/core/src/tools/network_approval.rs (36 lines):
	- line 2: use crate::guardian::GuardianNetworkAccessTrigger;
	- line 3: use crate::guardian::GuardianReviewContext;
	- line 25: use codex_protocol::protocol::AskForApproval;
	- line 28: use codex_protocol::protocol::ReviewDecision;
	- line 54: pub trigger: GuardianNetworkAccessTrigger,
	- line 55: /// Preserve the typed identity independently of Guardian's display-name payload.
	- line 187: fn allows_network_approval_flow(policy: AskForApproval) -> bool {
	- line 188: !matches!(policy, AskForApproval::Never)
	- line 237: trigger: GuardianNetworkAccessTrigger,
	- line 697: let review_context = GuardianReviewContext::from_resolved_settings(
	- line 701: if !allows_network_approval_flow(review_context.approval_policy) {
	- line 713: let guardian_approval_id = Self::approval_id_for_key(&key);
	- line 715: || guardian_approval_id.clone(),
	- line 716: |call| format!("{guardian_approval_id}#{}", call.registration_id),
	- line 738: let approval_call_id = format!("{guardian_approval_id}#{}", Uuid::new_v4());
	- line 748: id: guardian_approval_id,
	- line 780: &ReviewDecision::denied("network approval was rejected"),
	- line 791: ReviewDecision::Abort
	- line 793: ReviewDecision::denied("network approval failed")
	- line 819: ReviewDecision::Approved
	- line 820: | ReviewDecision::ApprovedExecpolicyAmendment { .. }
	- line 821: | ReviewDecision::ApprovedForSession
	- line 822: | ReviewDecision::NetworkPolicyAmendment { .. }
	- line 831: ReviewDecision::Approved | ReviewDecision::ApprovedExecpolicyAmendment { .. } => {
	- line 844: ReviewDecision::ApprovedForSession => {
	- line 858: ReviewDecision::NetworkPolicyAmendment {
	- line 957: ReviewDecision::ApprovedMcpPolicyAmendment
	- line 958: | ReviewDecision::Denied { .. }
	- line 959: | ReviewDecision::TimedOut
	- line 960: | ReviewDecision::Abort => {
	- line 975: ReviewDecision::NetworkPolicyAmendment { .. }
	- line 979: PendingApprovalDecision::AllowOnce => ReviewDecision::Approved,
	- line 980: PendingApprovalDecision::AllowForSession => ReviewDecision::ApprovedForSession,
	- line 982: ReviewDecision::denied("network approval was not applied")
	- line 988: telemetry_decision = ReviewDecision::denied("network approval was not applied");
	- line 1063: session.services.exec_policy.current().as_ref(),


codex-rs/tui/src/chatwidget/protocol_requests.rs (35 lines):
	- line 4: //! that render approvals, permissions, tool input, and guardian reviews.
	- line 70: pub(super) fn on_guardian_review_notification(
	- line 75: review: codex_app_server_protocol::GuardianApprovalReview,
	- line 76: completion: Option<(i64, codex_app_server_protocol::AutoReviewDecisionSource)>,
	- line 77: action: GuardianApprovalReviewAction,
	- line 85: "failed to localize guardian filesystem paths: {err}"
	- line 97: self.on_guardian_assessment(GuardianAssessmentEvent {
	- line 106: codex_app_server_protocol::GuardianApprovalReviewStatus::InProgress => {
	- line 107: GuardianAssessmentStatus::InProgress
	- line 109: codex_app_server_protocol::GuardianApprovalReviewStatus::Approved => {
	- line 110: GuardianAssessmentStatus::Approved
	- line 112: codex_app_server_protocol::GuardianApprovalReviewStatus::Denied => {
	- line 113: GuardianAssessmentStatus::Denied
	- line 115: codex_app_server_protocol::GuardianApprovalReviewStatus::TimedOut => {
	- line 116: GuardianAssessmentStatus::TimedOut
	- line 118: codex_app_server_protocol::GuardianApprovalReviewStatus::Aborted => {
	- line 119: GuardianAssessmentStatus::Aborted
	- line 123: codex_app_server_protocol::GuardianRiskLevel::Low => {
	- line 124: codex_protocol::approvals::GuardianRiskLevel::Low
	- line 126: codex_app_server_protocol::GuardianRiskLevel::Medium => {
	- line 127: codex_protocol::approvals::GuardianRiskLevel::Medium
	- line 129: codex_app_server_protocol::GuardianRiskLevel::High => {
	- line 130: codex_protocol::approvals::GuardianRiskLevel::High
	- line 132: codex_app_server_protocol::GuardianRiskLevel::Critical => {
	- line 133: codex_protocol::approvals::GuardianRiskLevel::Critical
	- line 138: codex_app_server_protocol::GuardianUserAuthorization::Unknown => {
	- line 139: codex_protocol::approvals::GuardianUserAuthorization::Unknown
	- line 141: codex_app_server_protocol::GuardianUserAuthorization::Low => {
	- line 142: codex_protocol::approvals::GuardianUserAuthorization::Low
	- line 144: codex_app_server_protocol::GuardianUserAuthorization::Medium => {
	- line 145: codex_protocol::approvals::GuardianUserAuthorization::Medium
	- line 147: codex_app_server_protocol::GuardianUserAuthorization::High => {
	- line 148: codex_protocol::approvals::GuardianUserAuthorization::High
	- line 154: codex_app_server_protocol::AutoReviewDecisionSource::Agent => {
	- line 155: GuardianAssessmentDecisionSource::Agent


codex-rs/prompts/src/permissions_instructions.rs (32 lines):
	- line 12: use codex_protocol::protocol::AskForApproval;
	- line 21: include_str!("../templates/permissions/approval_policy/never.md");
	- line 23: include_str!("../templates/permissions/approval_policy/unless_trusted.md");
	- line 25: include_str!("../templates/permissions/approval_policy/on_request.md");
	- line 27: include_str!("../templates/permissions/approval_policy/on_request_rule_request_permission.md");
	- line 52: approval_policy: AskForApproval,
	- line 56: exec_policy: &'a Policy,
	- line 92: approval_policy: AskForApproval,
	- line 94: exec_policy: &Policy,
	- line 107: approval_policy,
	- line 111: exec_policy,
	- line 155: config.approval_policy,
	- line 158: config.exec_policy,
	- line 230: approval_policy: AskForApproval,
	- line 233: exec_policy: &Policy,
	- line 238: let selected = match &approval_policy {
	- line 239: AskForApproval::OnRequest => match approvals_reviewer {
	- line 243: AskForApproval::Never => approval_messages.never.as_ref(),
	- line 244: AskForApproval::UnlessTrusted => approval_messages.unless_trusted.as_ref(),
	- line 245: AskForApproval::Granular(_) => None,
	- line 269: if let Some(prefixes) = approved_command_prefixes_text(exec_policy) {
	- line 276: let text = match approval_policy {
	- line 277: AskForApproval::Never => APPROVAL_POLICY_NEVER.to_string(),
	- line 278: AskForApproval::UnlessTrusted => {
	- line 281: AskForApproval::OnRequest => on_request_instructions(),
	- line 282: AskForApproval::Granular(granular_config) => granular_instructions(
	- line 284: exec_policy,
	- line 291: && approval_policy != AskForApproval::Never
	- line 368: fn approved_command_prefixes_text(exec_policy: &Policy) -> Option<String> {
	- line 369: format_allow_prefixes(exec_policy.get_allowed_prefixes())
	- line 383: exec_policy: &Policy,
	- line 444: if let Some(prefixes) = approved_command_prefixes_text(exec_policy) {


codex-rs/features/src/lib.rs (31 lines):
	- line 24: pub use feature_configs::GuardianV2ConfigToml;
	- line 25: pub use feature_configs::GuardianV2ReviewScopeConfigToml;
	- line 26: pub use feature_configs::GuardianV2TranscriptConfigToml;
	- line 27: pub use feature_configs::GuardianV2TranscriptSource;
	- line 297: GuardianApproval,
	- line 298: /// Reuse encrypted parent compaction when restarting Guardian review sessions.
	- line 299: GuardianReuseParentCompaction,
	- line 300: /// Include completed node_repl or cua_repl Code Mode responses in Guardian reviews.
	- line 301: GuardianEnhancedNodeReplTranscripts,
	- line 302: /// Include completed node_repl or cua_repl Code Mode response images in Guardian reviews.
	- line 303: GuardianNodeReplTranscriptImages,
	- line 304: /// Enable Guardian V2 automatic approval reviews.
	- line 305: GuardianV2,
	- line 306: /// Enable the extension-owned synchronous Guardian reviewer.
	- line 307: GuardianExt,
	- line 753: deserialize_with = "feature_configs::deserialize_guardian_v2_feature"
	- line 755: pub guardianv2: Option<FeatureToml<GuardianV2ConfigToml>>,
	- line 798: if let Some(enabled) = self.guardianv2.as_ref().and_then(FeatureToml::enabled) {
	- line 799: entries.insert(Feature::GuardianV2.key().to_string(), enabled);
	- line 1488: id: Feature::GuardianApproval,
	- line 1489: key: "guardian_approval",
	- line 1494: id: Feature::GuardianReuseParentCompaction,
	- line 1495: key: "guardian_reuse_parent_compaction",
	- line 1500: id: Feature::GuardianEnhancedNodeReplTranscripts,
	- line 1501: key: "guardian_enhanced_node_repl_transcripts",
	- line 1506: id: Feature::GuardianNodeReplTranscriptImages,
	- line 1507: key: "guardian_node_repl_transcript_images",
	- line 1512: id: Feature::GuardianV2,
	- line 1513: key: "guardianv2",
	- line 1518: id: Feature::GuardianExt,
	- line 1519: key: "guardian_ext",


codex-rs/core/src/session/step_activation.rs (31 lines):
	- line 11: use crate::exec_policy::AllowPrefixRules;
	- line 12: use crate::guardian::BUNDLED_GUARDIAN_POLICY_TEMPLATE;
	- line 14: use codex_protocol::openai_models::GuardianV2ModelConfig;
	- line 15: use codex_protocol::openai_models::GuardianV2TranscriptModelConfig;
	- line 22: /// Temporary restrictions while approvals and Guardian still read the admitted
	- line 50: // tools::approvals and guardian::review still route approvals using the
	- line 52: if destination.constrained_approval_policy() != current.constrained_approval_policy()
	- line 53: || destination.approval_policy() != turn_context.approval_policy()
	- line 102: // guardian::review::record_guardian_denial still selects its circuit-breaker
	- line 109: return Err("the destination changes the admitted Guardian rejection policy".to_string());
	- line 111: // TurnMetadataState pins both node REPL flags. Guardian prompt/evidence
	- line 128: // guardian::review::guardian_review_session_config and Guardian V2 still
	- line 134: return Err("the destination changes the explicit Guardian reviewer model".to_string());
	- line 137: if admitted_config.features.enabled(Feature::GuardianV2)
	- line 138: && admitted_config.features.enabled(Feature::GuardianApproval)
	- line 140: // GuardianV2Extension::on_tool_start reads the parent ModelInfo from
	- line 145: |model: &ModelInfo| -> GuardianV2ModelConfig {
	- line 149: .and_then(|messages| messages.guardian_v2.clone())
	- line 153: *transcript == GuardianV2TranscriptModelConfig::default()
	- line 165: "the destination changes the admitted Guardian V2 classification settings"
	- line 171: // guardian_review_session_config and Guardian V2 can fall back to parent
	- line 178: config.resolve_guardian_policy(destination.model_messages.as_ref());
	- line 180: config.resolve_guardian_policy(model.model_messages.as_ref()) != destination_policy
	- line 183: "the destination changes the Guardian parent-fallback policy".to_string(),
	- line 205: "the destination changes the Guardian parent-fallback policy template".to_string(),
	- line 328: let (requirements, overrides, trusted_guardian_reviewer) = {
	- line 335: configuration.trusted_guardian_reviewer,
	- line 340: guardian_approval_enabled: self.features.enabled(Feature::GuardianApproval),
	- line 341: trusted_guardian_reviewer,
	- line 374: guardian_approval_enabled: self.features.enabled(Feature::GuardianApproval),
	- line 375: trusted_guardian_reviewer: configuration.trusted_guardian_reviewer,


codex-rs/features/src/tests.rs (31 lines):
	- line 154: fn guardian_v2_feature_config_preserves_boolean_toggle() {
	- line 156: toml::from_str("guardianv2 = true").expect("Guardian v2 boolean should deserialize");
	- line 158: assert_eq!(features.guardianv2, Some(FeatureToml::Enabled(true)));
	- line 161: BTreeMap::from([("guardianv2".to_owned(), true)])
	- line 166: fn guardian_v2_feature_config_deserializes_classifier_and_transcript_settings() {
	- line 169: [guardianv2]
	- line 171: free_guardian = true
	- line 182: [guardianv2.review_scope]
	- line 186: [guardianv2.transcript]
	- line 196: .expect("Guardian v2 settings should deserialize");
	- line 199: features.guardianv2,
	- line 200: Some(FeatureToml::Config(crate::GuardianV2ConfigToml {
	- line 202: free_guardian: Some(true),
	- line 212: review_scope: Some(crate::GuardianV2ReviewScopeConfigToml {
	- line 216: transcript: Some(crate::GuardianV2TranscriptConfigToml {
	- line 218: crate::GuardianV2TranscriptSource::ToolOutputs,
	- line 219: crate::GuardianV2TranscriptSource::Reasoning,
	- line 232: BTreeMap::from([("guardianv2".to_owned(), true)])
	- line 237: fn guardian_v2_feature_config_rejects_invalid_settings() {
	- line 248: let settings = format!("[guardianv2]\n{setting} = {value}");
	- line 251: "out-of-range Guardian v2 setting should fail: {setting} = {value}"
	- line 265: toml::from_str::<FeaturesToml>(&format!("[guardianv2]\n{settings}")).is_err(),
	- line 266: "invalid Guardian v2 settings should fail: {settings}"
	- line 272: fn guardian_v2_feature_config_accepts_boundary_values() {
	- line 275: "[guardianv2]\n\
	- line 280: [guardianv2.transcript]\n\
	- line 287: .expect("Guardian v2 boundary settings should deserialize");
	- line 289: assert!(matches!(features.guardianv2, Some(FeatureToml::Config(_))));
	- line 297: toml::from_str(&format!("[guardianv2.transcript]\n{setting} = 100"))
	- line 298: .expect("partial Guardian v2 transcript settings should deserialize");
	- line 300: assert!(matches!(features.guardianv2, Some(FeatureToml::Config(_))));


codex-rs/core/src/tools/sandboxing.rs (30 lines):
	- line 17: use codex_protocol::approvals::ExecPolicyAmendment;
	- line 22: use codex_protocol::protocol::AskForApproval;
	- line 23: use codex_protocol::protocol::ReviewDecision;
	- line 42: map: HashMap<String, ReviewDecision>,
	- line 46: pub fn get<K>(&self, key: &K) -> Option<ReviewDecision>
	- line 54: pub fn put<K>(&mut self, key: K, value: ReviewDecision)
	- line 64: /// Takes a vector of approval keys and returns a ReviewDecision.
	- line 76: ) -> ReviewDecision
	- line 80: Fut: Future<Output = ReviewDecision>,
	- line 90: .all(|key| matches!(store.get(key), Some(ReviewDecision::ApprovedForSession)))
	- line 94: return ReviewDecision::ApprovedForSession;
	- line 108: if matches!(decision, ReviewDecision::ApprovedForSession) {
	- line 111: store.put(key, ReviewDecision::ApprovedForSession);
	- line 160: proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 166: /// See core/src/exec_policy.rs for more details on how proposed_execpolicy_amendment is determined.
	- line 167: proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 174: pub fn proposed_execpolicy_amendment(&self) -> Option<&ExecPolicyAmendment> {
	- line 195: policy: AskForApproval,
	- line 199: AskForApproval::Never => false,
	- line 200: AskForApproval::OnRequest | AskForApproval::Granular(_) => {
	- line 206: AskForApproval::UnlessTrusted => true,
	- line 212: AskForApproval::Granular(granular_config)
	- line 250: // ExecPolicy `Allow` can intentionally imply full trust (Skip + bypass_sandbox=true),
	- line 315: fn should_bypass_approval(&self, policy: AskForApproval, already_approved: bool) -> bool {
	- line 320: matches!(policy, AskForApproval::Never)
	- line 330: fn wants_no_sandbox_approval(&self, policy: AskForApproval) -> bool {
	- line 332: AskForApproval::UnlessTrusted => true,
	- line 333: AskForApproval::Never => false,
	- line 334: AskForApproval::OnRequest => false,
	- line 335: AskForApproval::Granular(granular_config) => granular_config.sandbox_approval,


codex-rs/config/src/requirements_exec_policy.rs (28 lines):
	- line 3: use codex_execpolicy::RequirementsExecPolicy;
	- line 15: pub struct RequirementsExecPolicyToml {
	- line 16: pub prefix_rules: Vec<RequirementsExecPolicyPrefixRuleToml>,
	- line 23: pub struct RequirementsExecPolicyPrefixRuleToml {
	- line 24: pub pattern: Vec<RequirementsExecPolicyPatternTokenToml>,
	- line 25: pub decision: Option<RequirementsExecPolicyDecisionToml>,
	- line 35: pub struct RequirementsExecPolicyPatternTokenToml {
	- line 42: pub enum RequirementsExecPolicyDecisionToml {
	- line 48: impl RequirementsExecPolicyDecisionToml {
	- line 59: pub enum RequirementsExecPolicyParseError {
	- line 87: impl RequirementsExecPolicyToml {
	- line 90: pub fn to_policy(&self) -> Result<Policy, RequirementsExecPolicyParseError> {
	- line 92: return Err(RequirementsExecPolicyParseError::EmptyPrefixRules);
	- line 101: return Err(RequirementsExecPolicyParseError::EmptyJustification { rule_index });
	- line 105: return Err(RequirementsExecPolicyParseError::EmptyPattern { rule_index });
	- line 116: Some(RequirementsExecPolicyDecisionToml::Allow) => {
	- line 117: return Err(RequirementsExecPolicyParseError::AllowDecisionNotAllowed {
	- line 123: return Err(RequirementsExecPolicyParseError::MissingDecision { rule_index });
	- line 130: .ok_or(RequirementsExecPolicyParseError::EmptyPattern { rule_index })?;
	- line 152: ) -> Result<RequirementsExecPolicy, RequirementsExecPolicyParseError> {
	- line 153: self.to_policy().map(RequirementsExecPolicy::new)
	- line 158: token: &RequirementsExecPolicyPatternTokenToml,
	- line 161: ) -> Result<PatternToken, RequirementsExecPolicyParseError> {
	- line 165: return Err(RequirementsExecPolicyParseError::InvalidPatternToken {
	- line 175: return Err(RequirementsExecPolicyParseError::InvalidPatternToken {
	- line 182: return Err(RequirementsExecPolicyParseError::InvalidPatternToken {
	- line 190: (Some(_), Some(_)) => Err(RequirementsExecPolicyParseError::InvalidPatternToken {
	- line 195: (None, None) => Err(RequirementsExecPolicyParseError::InvalidPatternToken {


codex-rs/tui/src/app_server_session.rs (26 lines):
	- line 33: use codex_app_server_protocol::AskForApproval;
	- line 64: use codex_app_server_protocol::ThreadApproveGuardianDeniedActionParams;
	- line 65: use codex_app_server_protocol::ThreadApproveGuardianDeniedActionResponse;
	- line 126: use codex_protocol::approvals::GuardianAssessmentEvent;
	- line 1189: approval_policy: AskForApproval,
	- line 1218: approval_policy: Some(approval_policy),
	- line 1457: pub(crate) async fn thread_approve_guardian_denied_action(
	- line 1460: event: &GuardianAssessmentEvent,
	- line 1463: let _: ThreadApproveGuardianDeniedActionResponse = self
	- line 1465: .request_typed(ClientRequest::ThreadApproveGuardianDeniedAction {
	- line 1467: params: ThreadApproveGuardianDeniedActionParams {
	- line 1474: .wrap_err("thread/approveGuardianDeniedAction failed in TUI")?;
	- line 1889: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 1953: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 1988: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 2095: response.approval_policy,
	- line 2136: response.approval_policy,
	- line 2168: response.approval_policy,
	- line 2218: approval_policy: AskForApproval,
	- line 2246: approval_policy,
	- line 2615: ("approval_policy".to_string(), "never".into()),
	- line 2652: started.session.approval_policy,
	- line 2658: AskForApproval::Never,
	- line 3682: approval_policy: codex_app_server_protocol::AskForApproval::Never,
	- line 3817: AskForApproval::Never,
	- line 3852: AskForApproval::Never,


codex-rs/cli/src/main.rs (24 lines):
	- line 26: use codex_execpolicy::ExecPolicyCheckCommand;
	- line 95: use codex_protocol::protocol::AskForApproval;
	- line 487: Check(ExecPolicyCheckCommand),
	- line 900: fn run_execpolicycheck(cmd: ExecPolicyCheckCommand) -> anyhow::Result<()> {
	- line 2212: let approval_policy = if shared.dangerously_bypass_approvals_and_sandbox {
	- line 2213: Some(AskForApproval::Never)
	- line 2215: interactive.approval_policy.map(Into::into)
	- line 2224: approval_policy,
	- line 2819: approval_policy,
	- line 2834: interactive.approval_policy = None;
	- line 2835: } else if let Some(approval) = approval_policy {
	- line 2836: interactive.approval_policy = Some(approval);
	- line 3250: fn dangerous_bypass_conflicts_with_approval_policy() {
	- line 3275: r#"approval_policy="on-request""#.to_string(),
	- line 3300: r#"approval_policy="on-request""#.to_string(),
	- line 3325: r#"approval_policy="on-request""#.to_string(),
	- line 3346: r#"approval_policy="on-request""#.to_string(),
	- line 3353: fn later_resume_approval_policy_partially_overrides_approve_for_me() {
	- line 3363: interactive.approval_policy,
	- line 3370: r#"approval_policy="on-request""#.to_string(),
	- line 3377: fn later_approve_for_me_overrides_root_tui_approval_policy() {
	- line 3386: assert!(interactive.approval_policy.is_none());
	- line 3391: r#"approval_policy="on-request""#.to_string(),
	- line 4032: interactive.approval_policy,


codex-rs/core/src/context/guardian_review_evidence.rs (24 lines):
	- line 10: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 14: use crate::codex_thread::GuardianAuthorizationVersion;
	- line 20: /// Trusted user answers, verified skill paths, and completed Guardian reviews.
	- line 26: pub struct GuardianReviewEvidence(Mutex<GuardianReviewEvidenceState>);
	- line 29: struct GuardianReviewEvidenceState {
	- line 30: reviews: VecDeque<Arc<GuardianReviewEvidenceRecord>>,
	- line 37: impl GuardianReviewEvidence {
	- line 86: ) -> GuardianAuthorizationVersion {
	- line 92: GuardianAuthorizationVersion {
	- line 94: ..GuardianAuthorizationVersion::from_history(history)
	- line 131: assessment: &GuardianAssessmentEvent,
	- line 133: authorization_version: GuardianAuthorizationVersion,
	- line 134: root_authorization_version: Option<GuardianAuthorizationVersion>,
	- line 139: let review = Arc::new(GuardianReviewEvidenceRecord {
	- line 169: pub fn snapshot(&self) -> Vec<Arc<GuardianReviewEvidenceRecord>> {
	- line 180: /// Structured synchronous-review evidence retained for Guardian V2 classification.
	- line 182: pub struct GuardianReviewEvidenceRecord {
	- line 183: pub authorization_version: GuardianAuthorizationVersion,
	- line 184: pub root_authorization_version: Option<GuardianAuthorizationVersion>,
	- line 194: pub struct GuardianReviewEvidenceFragment {
	- line 198: impl GuardianReviewEvidenceFragment {
	- line 205: impl ContextualUserFragment for GuardianReviewEvidenceFragment {
	- line 207: ContentItemKind("guardian.review_evidence".to_string())
	- line 219: ("<guardian_sync_review>", "</guardian_sync_review>")


codex-rs/tui/src/status/tests.rs (23 lines):
	- line 30: use codex_app_server_protocol::AskForApproval;
	- line 425: .approval_policy
	- line 426: .set(AskForApproval::OnRequest.to_core())
	- line 448: .approval_policy
	- line 449: .set(AskForApproval::OnRequest.to_core())
	- line 471: .approval_policy
	- line 472: .set(AskForApproval::OnRequest.to_core())
	- line 501: .approval_policy
	- line 502: .set(AskForApproval::OnRequest.to_core())
	- line 525: .approval_policy
	- line 526: .set(AskForApproval::OnRequest.to_core())
	- line 548: .approval_policy
	- line 549: .set(AskForApproval::OnRequest.to_core())
	- line 578: .approval_policy
	- line 579: .set(AskForApproval::OnRequest.to_core())
	- line 610: .approval_policy
	- line 611: .set(AskForApproval::OnRequest.to_core())
	- line 645: .approval_policy
	- line 646: .set(AskForApproval::OnRequest.to_core())
	- line 894: .approval_policy
	- line 895: .set(AskForApproval::OnRequest.to_core())
	- line 917: .approval_policy
	- line 918: .set(AskForApproval::OnRequest.to_core())


codex-rs/ext/guardian-v2/src/async_scorer/config.rs (23 lines):
	- line 3: use codex_features::GuardianV2ConfigToml;
	- line 4: use codex_features::GuardianV2TranscriptConfigToml;
	- line 5: use codex_protocol::openai_models::GuardianV2ModelConfig;
	- line 28: pub(crate) enum GuardianV2ReviewScope {
	- line 34: pub(crate) struct GuardianV2Config {
	- line 35: local_overrides: GuardianV2ConfigToml,
	- line 46: pub(crate) review_scope: GuardianV2ReviewScope,
	- line 50: impl GuardianV2Config {
	- line 55: .and_then(|features| features.get("guardianv2"))
	- line 59: let feature: FeatureToml<GuardianV2ConfigToml> = value
	- line 61: .map_err(|error| format!("invalid Guardian v2 configuration: {error}"))?;
	- line 63: FeatureToml::Enabled(_) => GuardianV2ConfigToml::default(),
	- line 67: None => GuardianV2ConfigToml::default(),
	- line 75: model_defaults: Option<&GuardianV2ModelConfig>,
	- line 109: .get_or_insert_with(GuardianV2TranscriptConfigToml::default);
	- line 121: Err(format!("invalid Guardian v2 transcript source: {source}"))
	- line 153: fn from_overrides(configured: GuardianV2ConfigToml) -> Result<Self, String> {
	- line 164: return Err("Guardian v2 review_threshold must be between 0.0 and 1.0".to_owned());
	- line 218: "Guardian v2 transcript {entry_setting} must not exceed {transcript_setting}"
	- line 227: "Guardian v2 transcript max_recent_non_user_entries must be positive".to_owned(),
	- line 252: GuardianV2ReviewScope::ComputerUseOnly
	- line 254: GuardianV2ReviewScope::Standard {
	- line 312: "Guardian v2 {setting} must be between {MIN_MODEL_CONTEXT_ITEM_TOKENS} and {MAX_MODEL_CONTEXT_ITEM_TOKENS} tokens"


codex-rs/exec/src/lib.rs (22 lines):
	- line 76: use codex_core::format_exec_policy_error_with_source;
	- line 97: use codex_protocol::protocol::AskForApproval;
	- line 336: ignore_user_and_project_exec_policy_rules: ignore_rules,
	- line 413: approval_policy: Some(AskForApproval::Never),
	- line 465: format_exec_policy_error_with_source(&err)
	- line 587: preserve_headless_approval_policy: bool,
	- line 594: let build_without_headless_approval_policy = || {
	- line 596: approval_policy: None,
	- line 603: && !preserve_headless_approval_policy =>
	- line 605: build_without_headless_approval_policy().await
	- line 608: Err(headless_error) if !preserve_headless_approval_policy => {
	- line 609: match build_without_headless_approval_policy().await {
	- line 707: let default_approval_policy = config.permissions.approval_policy.value();
	- line 881: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 908: response.approval_policy.to_core(),
	- line 985: approval_policy: Some(default_approval_policy.into()),
	- line 1193: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 1223: approval_policy: Some(config.permissions.approval_policy.value().into()),
	- line 1307: response.approval_policy.to_core(),
	- line 1331: response.approval_policy.to_core(),
	- line 1364: approval_policy: AskForApproval,
	- line 1394: approval_policy,


codex-rs/features/src/feature_configs.rs (22 lines):
	- line 76: /// Optional conversation sources available to the Guardian v2 classifier.
	- line 79: pub enum GuardianV2TranscriptSource {
	- line 85: /// Bounds and optional sources for the Guardian v2 conversation transcript.
	- line 88: pub struct GuardianV2TranscriptConfigToml {
	- line 90: pub sources: Option<Vec<GuardianV2TranscriptSource>>,
	- line 111: /// Optional tool-call categories available to the Guardian v2 classifier.
	- line 114: pub struct GuardianV2ReviewScopeConfigToml {
	- line 118: /// Include sandboxed shell command calls in Guardian v2 classification.
	- line 123: /// User-configurable prompt, approval, and context settings for Guardian v2.
	- line 126: pub struct GuardianV2ConfigToml {
	- line 129: /// Route Guardian review and classification through the unmetered Codex endpoints.
	- line 131: pub free_guardian: Option<bool>,
	- line 156: pub review_scope: Option<GuardianV2ReviewScopeConfigToml>,
	- line 158: pub transcript: Option<GuardianV2TranscriptConfigToml>,
	- line 161: impl FeatureConfig for GuardianV2ConfigToml {
	- line 167: pub(crate) fn deserialize_guardian_v2_feature<'de, D>(
	- line 169: ) -> Result<Option<FeatureToml<GuardianV2ConfigToml>>, D::Error>
	- line 176: let feature = Option::<FeatureToml<GuardianV2ConfigToml>>::deserialize(deserializer)?;
	- line 185: "Guardian v2 review_threshold must be between 0.0 and 1.0",
	- line 213: "Guardian v2 {field} must be between {MIN_TOKENS} and {MAX_TOKENS} tokens"
	- line 223: "Guardian v2 transcript max_recent_non_user_entries must be positive",
	- line 235: "Guardian v2 transcript max_{kind}_entry_tokens must not exceed max_{kind}_transcript_tokens"


codex-rs/tui/src/auto_review_denials.rs (22 lines):
	- line 3: use codex_protocol::approvals::GuardianAssessmentAction;
	- line 4: use codex_protocol::approvals::GuardianAssessmentEvent;
	- line 5: use codex_protocol::approvals::GuardianAssessmentStatus;
	- line 11: entries: VecDeque<GuardianAssessmentEvent>,
	- line 15: pub(crate) fn push(&mut self, event: GuardianAssessmentEvent) {
	- line 16: if event.status != GuardianAssessmentStatus::Denied {
	- line 29: pub(crate) fn entries(&self) -> impl Iterator<Item = &GuardianAssessmentEvent> {
	- line 33: pub(crate) fn take(&mut self, id: &str) -> Option<GuardianAssessmentEvent> {
	- line 39: pub(crate) fn action_summary(action: &GuardianAssessmentAction) -> String {
	- line 41: GuardianAssessmentAction::Command { command, .. } => command.clone(),
	- line 42: GuardianAssessmentAction::Execve { program, argv, .. } => {
	- line 51: GuardianAssessmentAction::WriteStdin {
	- line 60: GuardianAssessmentAction::ApplyPatch { files, .. } => {
	- line 67: GuardianAssessmentAction::NetworkAccess { target, .. } => {
	- line 70: GuardianAssessmentAction::McpToolCall {
	- line 79: GuardianAssessmentAction::RequestPermissions { reason, .. } => reason
	- line 88: use codex_protocol::approvals::GuardianCommandSource;
	- line 95: fn denied_event(id: usize) -> GuardianAssessmentEvent {
	- line 96: GuardianAssessmentEvent {
	- line 104: status: GuardianAssessmentStatus::Denied,
	- line 109: action: GuardianAssessmentAction::Command {
	- line 110: source: GuardianCommandSource::Shell,


codex-rs/core/src/session/session.rs (22 lines):
	- line 70: pub(crate) guardian_review_session: GuardianReviewSessionManager,
	- line 119: /// Guardian reviewer identity is trusted only when established during an in-memory spawn.
	- line 120: pub(super) trusted_guardian_reviewer: bool,
	- line 155: exec_policy: None,
	- line 248: approval_policy: self.step_settings.approval_policy.value(),
	- line 281: approval_policy: self.step_settings.approval_policy.value(),
	- line 308: approval_policy: Some(self.step_settings.approval_policy.value()),
	- line 340: guardian_approval_enabled: self
	- line 343: .enabled(Feature::GuardianApproval),
	- line 344: trusted_guardian_reviewer: self.trusted_guardian_reviewer,
	- line 639: exec_policy: Arc<ExecPolicyManager>,
	- line 741: Some(ThreadSource::Subagent | ThreadSource::GuardianReview)
	- line 1021: approval_policy: session_configuration.step_settings.approval_policy.value().to_string(),
	- line 1142: config.permissions.approval_policy.value(),
	- line 1289: let current_exec_policy = exec_policy.current();
	- line 1292: current_exec_policy.as_ref(),
	- line 1402: exec_policy,
	- line 1412: guardian_rejection_circuit_breaker: Mutex::new(Default::default()),
	- line 1457: .with_free_guardian_enabled(config.free_guardian_enabled())
	- line 1459: crate::guardian::prompt_cache_key_override_for_review_session(
	- line 1496: guardian_review_session: GuardianReviewSessionManager::default(),
	- line 1525: approval_policy: thread_config.approval_policy,


codex-rs/core/src/codex_thread.rs (21 lines):
	- line 4: use crate::context::GuardianReviewEvidence;
	- line 34: use codex_protocol::protocol::AskForApproval;
	- line 86: pub approval_policy: AskForApproval,
	- line 140: pub approval_policy: Option<AskForApproval>,
	- line 154: /// One root conversation message exposed only to a worker's Guardian reviewers.
	- line 156: pub enum GuardianRootMessage {
	- line 165: impl GuardianRootMessage {
	- line 181: pub struct GuardianAuthorizationVersion {
	- line 188: impl GuardianAuthorizationVersion {
	- line 200: pub struct GuardianRootSnapshot {
	- line 201: pub authorization_version: GuardianAuthorizationVersion,
	- line 202: pub messages: Vec<GuardianRootMessage>,
	- line 569: approval_policy,
	- line 590: approval_policy,
	- line 693: pub async fn guardian_trunk_rollout_path(&self) -> Option<PathBuf> {
	- line 695: .guardian_review_session
	- line 828: /// Returns the current user-authorization revision for Guardian.
	- line 829: pub async fn guardian_authorization_version(&self) -> GuardianAuthorizationVersion {
	- line 832: .get::<GuardianReviewEvidence>()
	- line 834: || GuardianAuthorizationVersion::from_history(history.as_ref()),
	- line 840: pub async fn guardian_root_snapshot(&self) -> Option<GuardianRootSnapshot> {


codex-rs/tui/src/debug_config.rs (21 lines):
	- line 222: requirements.approval_policy.source.as_ref(),
	- line 304: if requirements_toml.guardian_policy_config.is_some() {
	- line 306: "guardian_policy_config",
	- line 308: requirements.guardian_policy_config_source.as_ref(),
	- line 356: requirements.exec_policy_source(),
	- line 657: use codex_app_server_protocol::AskForApproval;
	- line 857: approval_policy: ConstrainedWithSource::new(
	- line 858: Constrained::allow_any(AskForApproval::OnRequest.to_core()),
	- line 904: entries: BTreeMap::from([("guardian_approval".to_string(), true)]),
	- line 929: guardian_policy_config_source: Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
	- line 946: allowed_approval_policies: Some(vec![AskForApproval::OnRequest.to_core()]),
	- line 965: guardian_policy_config: Some("Use the managed guardian policy.".to_string()),
	- line 967: entries: BTreeMap::from([("guardian_approval".to_string(), true)]),
	- line 1040: "guardian_policy_config: configured (source: {requirements_source})"
	- line 1043: "features: guardian_approval=true (source: {requirements_source})"
	- line 1125: Constrained::allow_any(AskForApproval::OnRequest.to_core()),
	- line 1244: approval_policy = "never"
	- line 1270: assert!(rendered.contains("approval_policy = \"never\""));
	- line 1278: approval_policy = "never"
	- line 1308: assert!(rendered.contains("approval_policy = \"never\""));
	- line 1334: guardian_policy_config: None,


codex-rs/tui/src/chatwidget/tests.rs (19 lines):
	- line 36: pub(super) use codex_app_server_protocol::AutoReviewDecisionSource as AppServerGuardianApprovalReviewDecisionSource;
	- line 50: pub(super) use codex_app_server_protocol::ExecPolicyAmendment;
	- line 52: pub(super) use codex_app_server_protocol::GuardianApprovalReview;
	- line 53: pub(super) use codex_app_server_protocol::GuardianApprovalReviewAction as AppServerGuardianApprovalReviewAction;
	- line 54: pub(super) use codex_app_server_protocol::GuardianApprovalReviewStatus;
	- line 55: pub(super) use codex_app_server_protocol::GuardianCommandSource as AppServerGuardianCommandSource;
	- line 56: pub(super) use codex_app_server_protocol::GuardianRiskLevel as AppServerGuardianRiskLevel;
	- line 57: pub(super) use codex_app_server_protocol::GuardianUserAuthorization as AppServerGuardianUserAuthorization;
	- line 58: pub(super) use codex_app_server_protocol::GuardianWarningNotification;
	- line 70: pub(super) use codex_app_server_protocol::ItemGuardianApprovalReviewCompletedNotification;
	- line 71: pub(super) use codex_app_server_protocol::ItemGuardianApprovalReviewStartedNotification;
	- line 134: pub(super) use codex_protocol::approvals::GuardianAssessmentAction;
	- line 135: pub(super) use codex_protocol::approvals::GuardianAssessmentDecisionSource;
	- line 136: pub(super) use codex_protocol::approvals::GuardianAssessmentEvent;
	- line 137: pub(super) use codex_protocol::approvals::GuardianAssessmentStatus;
	- line 138: pub(super) use codex_protocol::approvals::GuardianCommandSource;
	- line 139: pub(super) use codex_protocol::approvals::GuardianRiskLevel;
	- line 140: pub(super) use codex_protocol::approvals::GuardianUserAuthorization;
	- line 244: mod guardian;


codex-rs/app-server-protocol/src/protocol/v2/shared.rs (19 lines):
	- line 6: use codex_protocol::protocol::AskForApproval as CoreAskForApproval;
	- line 176: pub enum AskForApproval {
	- line 194: impl AskForApproval {
	- line 195: pub fn to_core(self) -> CoreAskForApproval {
	- line 197: AskForApproval::UnlessTrusted => CoreAskForApproval::UnlessTrusted,
	- line 198: AskForApproval::OnRequest => CoreAskForApproval::OnRequest,
	- line 199: AskForApproval::Granular {
	- line 205: } => CoreAskForApproval::Granular(CoreGranularApprovalConfig {
	- line 212: AskForApproval::Never => CoreAskForApproval::Never,
	- line 217: impl From<CoreAskForApproval> for AskForApproval {
	- line 218: fn from(value: CoreAskForApproval) -> Self {
	- line 220: CoreAskForApproval::UnlessTrusted => AskForApproval::UnlessTrusted,
	- line 221: CoreAskForApproval::OnRequest => AskForApproval::OnRequest,
	- line 222: CoreAskForApproval::Granular(granular_config) => AskForApproval::Granular {
	- line 229: CoreAskForApproval::Never => AskForApproval::Never,
	- line 236: type = r#""user" | "auto_review" | "guardian_subagent""#,
	- line 247: #[serde(rename = "auto_review", alias = "guardian_subagent")]
	- line 259: &["user", "auto_review", "guardian_subagent"],
	- line 260: "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.",


codex-rs/core/src/agent/control/spawn.rs (18 lines):
	- line 26: exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
	- line 383: let runtime_approval_policy = config.permissions.approval_policy.value();
	- line 404: .approval_policy
	- line 405: .set(runtime_approval_policy)
	- line 407: CodexErr::InvalidRequest(format!("approval_policy is invalid: {err}"))
	- line 437: let (inherited_environments, inherited_exec_policy, client_mcp_extensions) = if let Some(
	- line 443: if !crate::exec_policy::child_uses_parent_exec_policy(&parent_config, &config) {
	- line 529: Some(Arc::clone(&parent.session.services.exec_policy)),
	- line 536: self.inherited_exec_policy_for_source(&state, Some(&session_source), &config)
	- line 555: inherited_exec_policy,
	- line 627: exec_policy: self
	- line 628: .inherited_exec_policy_for_source(&state, session_source.as_ref(), &config)
	- line 689: inheritance.exec_policy,
	- line 801: exec_policy: inherited_exec_policy,
	- line 1074: inherited_exec_policy,
	- line 1221: let inherited_exec_policy = self
	- line 1222: .inherited_exec_policy_for_source(&state, Some(&session_source), &config)
	- line 1234: inherited_exec_policy,


codex-rs/protocol/src/openai_models.rs (18 lines):
	- line 36: #[path = "openai_models/guardian_v2.rs"]
	- line 37: mod guardian_v2;
	- line 39: pub use guardian_v2::GuardianV2ModelConfig;
	- line 40: pub use guardian_v2::GuardianV2TranscriptModelConfig;
	- line 561: pub guardian_v2: Option<GuardianV2ModelConfig>,
	- line 828: guardian_v2: None,
	- line 1038: guardian_v2: None,
	- line 1245: guardian_v2: None,
	- line 1336: guardian_v2: None,
	- line 1362: guardian_v2: None,
	- line 1389: guardian_v2: None,
	- line 1427: guardian_v2: None,
	- line 1471: guardian_v2: None,
	- line 1526: guardian_v2: None,
	- line 1580: guardian_v2: Some(GuardianV2ModelConfig {
	- line 1581: classifier_instructions: Some("Guardian classification".to_string()),
	- line 1584: transcript: Some(GuardianV2TranscriptModelConfig {
	- line 1627: guardian_v2: None,


codex-rs/core/src/session/handlers.rs (18 lines):
	- line 19: use crate::context::GuardianApprovedAction;
	- line 32: use codex_protocol::protocol::GuardianAssessmentEvent;
	- line 33: use codex_protocol::protocol::GuardianAssessmentStatus;
	- line 38: use codex_protocol::protocol::ReviewDecision;
	- line 180: decision: ReviewDecision,
	- line 183: if let ReviewDecision::ApprovedExecpolicyAmendment {
	- line 200: ReviewDecision::Abort => {
	- line 207: pub async fn patch_approval(sess: &Arc<Session>, id: String, decision: ReviewDecision) {
	- line 209: ReviewDecision::Abort => {
	- line 341: sess.guardian_review_session.invalidate().await;
	- line 424: sess.guardian_review_session.shutdown().await;
	- line 705: Op::ApproveGuardianDeniedAction { event } => {
	- line 706: approve_guardian_denied_action(&sess, event).await;
	- line 733: async fn approve_guardian_denied_action(sess: &Arc<Session>, event: GuardianAssessmentEvent) {
	- line 734: if event.status != GuardianAssessmentStatus::Denied {
	- line 737: "ignoring approval for non-denied Guardian assessment"
	- line 749: warn!(%error, review_id = event.id.as_str(), "failed to serialize approved Guardian action");
	- line 753: let items = vec![ContextualUserFragment::into(GuardianApprovedAction::new(


codex-rs/ext/guardian-v2/src/sync_reviewer/prompt.rs (17 lines):
	- line 3: use codex_core::GuardianRootSnapshot;
	- line 5: use codex_core::context::GuardianReviewEvidence;
	- line 21: use super::GuardianThreadContext;
	- line 23: use crate::async_scorer::GuardianV2Config;
	- line 37: root_authorization: Option<GuardianRootSnapshot>,
	- line 43: .get::<GuardianThreadContext>()
	- line 55: .and_then(|messages| messages.guardian_v2.as_ref());
	- line 56: let guardian_config = input
	- line 58: .get::<GuardianV2Config>()
	- line 62: ApprovalReviewError::Failed(format!("invalid Guardian config: {error}"))
	- line 64: let transcript_config = guardian_config
	- line 79: .get::<GuardianReviewEvidence>()
	- line 105: let action_tokens = guardian_config
	- line 179: root_authorization: Option<GuardianRootSnapshot>,
	- line 303: // Legacy Guardian omitted environment identity and cwd. Include them here so the
	- line 337: "parent denied-read restrictions exceed the Guardian evidence limit".to_string(),
	- line 347: // interleaved with their bounded tool response and provenance. Guardian V2


codex-rs/tui/src/chatwidget/permissions_menu.rs (17 lines):
	- line 11: .approval_policy
	- line 12: .can_set(&AskForApproval::OnRequest.to_core())
	- line 18: let reviewer = if config.features.enabled(Feature::GuardianApproval)
	- line 39: approval_policy: AskForApproval,
	- line 43: .approval_policy
	- line 44: .can_set(&approval_policy.to_core())
	- line 93: AskForApproval::from(default.approval),
	- line 97: if self.config.features.enabled(Feature::GuardianApproval) {
	- line 102: AskForApproval::OnRequest,
	- line 110: AskForApproval::from(full_access.approval),
	- line 117: AskForApproval::from(read_only.approval),
	- line 152: approval_policy: AskForApproval,
	- line 166: AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 171: approval_policy: Some(approval_policy),
	- line 179: && current_approval == approval_policy
	- line 189: disabled_reason: self.permission_mode_disabled_reason(preset, approval_policy),
	- line 204: approval_policy: None,


codex-rs/ext/guardian-v2/src/async_scorer/sampler.rs (17 lines):
	- line 49: use super::trusted_skills::GuardianTrustedSkillsFragment;
	- line 50: use super::trusted_tools::GuardianTrustedToolFragment;
	- line 54: "codex.guardian_v2.classification.token_usage";
	- line 81: /// Whether this thread may use the unmetered Guardian classifier endpoint.
	- line 82: pub free_guardian: bool,
	- line 95: /// Host-supplied Guardian reviews isolated from untrusted transcript entries.
	- line 98: pub trusted_tool_context: Option<GuardianTrustedToolFragment>,
	- line 238: if self.config.free_guardian
	- line 253: ResponsesEndpoint::GuardianClassifier
	- line 284: headers.insert("x-openai-subagent", HeaderValue::from_static("guardian"));
	- line 471: text: "Trusted synchronous Guardian reviews supplied by Codex. Decisions \
	- line 492: GuardianTrustedSkillsFragment {
	- line 539: prompt_cache_key: Some(format!("guardian-v2:{}", self.config.thread_id)),
	- line 590: if lease.connection.endpoint == ResponsesEndpoint::GuardianClassifier {
	- line 599: "guardian_classifier_source_thread_id": self.config.thread_id,
	- line 602: "thread_source": "guardian_classifier",
	- line 609: ("x-openai-subagent".to_owned(), "guardian".to_owned()),


codex-rs/tui/src/chatwidget/permission_popups.rs (16 lines):
	- line 25: AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 27: let guardian_approval_enabled = self.config.features.enabled(Feature::GuardianApproval);
	- line 43: let guardian_disabled_reason = |enabled: bool| {
	- line 45: next_features.set_enabled(Feature::GuardianApproval, enabled);
	- line 69: .approval_policy
	- line 77: .or_else(|| guardian_disabled_reason(false));
	- line 102: if guardian_approval_enabled {
	- line 112: ) || (current_approval == AskForApproval::OnRequest
	- line 127: .or_else(|| guardian_disabled_reason(true)),
	- line 236: op: AppCommand::approve_guardian_denied_action(event),
	- line 248: approval: AskForApproval,
	- line 269: tx.send(AppEvent::UpdateAskForApprovalPolicy(approval));
	- line 303: AskForApproval::from(preset.approval),
	- line 370: current_approval: AskForApproval,
	- line 375: let preset_approval = AskForApproval::from(preset.approval);
	- line 413: let approval = AskForApproval::from(preset.approval);


sdk/python/src/openai_codex/api.py (16 lines):
	- line 151: approval_policy, approvals_reviewer = _approval_mode_settings(approval_mode)
	- line 153: approval_policy=approval_policy,
	- line 219: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 222: approval_policy=approval_policy,
	- line 254: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 257: approval_policy=approval_policy,
	- line 394: approval_policy, approvals_reviewer = _approval_mode_settings(approval_mode)
	- line 396: approval_policy=approval_policy,
	- line 464: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 467: approval_policy=approval_policy,
	- line 500: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 503: approval_policy=approval_policy,
	- line 594: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 598: approval_policy=approval_policy,
	- line 683: approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode)
	- line 687: approval_policy=approval_policy,


codex-rs/core/src/session/step_settings.rs (16 lines):
	- line 18: use codex_protocol::protocol::AskForApproval;
	- line 32: pub(crate) approval_policy: Constrained<AskForApproval>,
	- line 89: pub(crate) fn approval_policy(&self) -> AskForApproval {
	- line 90: self.selected.approval_policy.value()
	- line 110: pub(super) fn constrained_approval_policy(&self) -> &Constrained<AskForApproval> {
	- line 111: &self.selected.approval_policy
	- line 153: .approval_policy
	- line 154: .can_set(&self.approval_policy())?;
	- line 223: pub(crate) approval_policy: Option<AskForApproval>,
	- line 232: pub(crate) guardian_approval_enabled: bool,
	- line 233: pub(crate) trusted_guardian_reviewer: bool,
	- line 283: if let Some(approval_policy) = update.approval_policy {
	- line 284: next.approval_policy.set(approval_policy)?;
	- line 293: if !constraints.trusted_guardian_reviewer
	- line 315: if constraints.trusted_guardian_reviewer {
	- line 329: && constraints.guardian_approval_enabled


codex-rs/core/src/thread_manager.rs (16 lines):
	- line 274: inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
	- line 292: inherited_exec_policy: None,
	- line 336: pub(crate) inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
	- line 1733: /*inherited_exec_policy*/ None,
	- line 1751: inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
	- line 1769: request.inherited_exec_policy = inherited_exec_policy;
	- line 1785: inherited_exec_policy,
	- line 1810: request.inherited_exec_policy = inherited_exec_policy;
	- line 1826: inherited_exec_policy: Option<Arc<crate::exec_policy::ExecPolicyManager>>,
	- line 1846: request.inherited_exec_policy = inherited_exec_policy;
	- line 1873: inherited_exec_policy,
	- line 1928: inherited_exec_policy,
	- line 1932: ) = if crate::guardian::is_basic_session_source(&session_source) {
	- line 1948: inherited_exec_policy,
	- line 1984: SessionSource::Internal(InternalSessionSource::Guardian)
	- line 2015: inherited_exec_policy,


codex-rs/ext/guardian-v2/src/sync_reviewer/reviewer_config.rs (15 lines):
	- line 20: use codex_protocol::protocol::AskForApproval;
	- line 59: "guardian reviewer environment `{}` has no resolved permissions",
	- line 67: session_source: Some(SessionSource::Internal(InternalSessionSource::Guardian)),
	- line 68: thread_source: Some(ThreadSource::GuardianReview),
	- line 165: let policy = parent_config.resolve_guardian_policy(model_messages);
	- line 197: config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);
	- line 206: "guardian reviewer could not set read-only permissions: {error}"
	- line 211: "guardian reviewer could not clear MCP servers: {error}"
	- line 232: "guardian reviewer could not preserve managed network restrictions: {error}"
	- line 241: "guardian reviewer could not disable `features.{}`: {error}",
	- line 248: "managed requirements keep a Guardian reviewer feature enabled"
	- line 259: "guardian reviewer could not preserve Code Mode developer policy: {error}"
	- line 301: Feature::GuardianApproval,
	- line 302: Feature::GuardianExt,
	- line 303: Feature::GuardianV2,


codex-rs/ext/guardian-v2/src/lib.rs (15 lines):
	- line 19: pub use sync_reviewer::GuardianExtension as GuardianReviewerExtension;
	- line 20: pub use sync_reviewer::GuardianThreadContext as GuardianReviewerThreadContext;
	- line 22: /// Guardian extension dependencies supplied by the host at construction time.
	- line 24: pub struct GuardianExtension<S> {
	- line 28: impl<S> GuardianExtension<S> {
	- line 29: /// Creates a guardian extension with its host-provided agent spawn helper.
	- line 34: /// Delegates one guardian-owned subagent spawn request to the host helper.
	- line 48: /// Thread-local guardian state captured when the host starts a thread.
	- line 50: pub struct GuardianThreadContext {
	- line 54: impl GuardianThreadContext {
	- line 55: /// Returns the thread that future guardian subagents should fork from by default.
	- line 61: impl<S> ThreadLifecycleContributor<Config> for GuardianExtension<S>
	- line 74: input.thread_store.insert(GuardianThreadContext {
	- line 81: /// Installs the guardian contributors into the extension registry.
	- line 92: registry.thread_lifecycle_contributor(Arc::new(GuardianExtension::new(agent_spawner)));


codex-rs/tui/src/app/thread_session_state.rs (14 lines):
	- line 4: use codex_app_server_protocol::AskForApproval;
	- line 40: let approval_policy = AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 54: session.approval_policy = approval_policy;
	- line 98: approval_policy: AskForApproval::from(
	- line 99: self.config.permissions.approval_policy.value(),
	- line 159: use codex_app_server_protocol::AskForApproval;
	- line 182: approval_policy: AskForApproval::Never,
	- line 207: approval_policy: AskForApproval::OnRequest,
	- line 233: app.config.permissions.approval_policy =
	- line 234: codex_config::Constrained::allow_any(AskForApproval::OnRequest.to_core());
	- line 255: approval_policy: AskForApproval::OnRequest,
	- line 329: app.config.permissions.approval_policy =
	- line 330: codex_config::Constrained::allow_any(AskForApproval::OnRequest.to_core());
	- line 336: approval_policy: AskForApproval::OnRequest,


codex-rs/tui/src/bottom_pane/approval_overlay.rs (14 lines):
	- line 31: use crate::history_cell::ReviewDecision;
	- line 810: ) -> ReviewDecision {
	- line 812: CommandExecutionApprovalDecision::Accept => ReviewDecision::Approved,
	- line 813: CommandExecutionApprovalDecision::AcceptForSession => ReviewDecision::ApprovedForSession,
	- line 816: } => ReviewDecision::ApprovedExecpolicyAmendment {
	- line 821: } => ReviewDecision::NetworkPolicyAmendment {
	- line 824: CommandExecutionApprovalDecision::Decline => ReviewDecision::Denied,
	- line 825: CommandExecutionApprovalDecision::Cancel => ReviewDecision::Abort,
	- line 1114: use codex_app_server_protocol::ExecPolicyAmendment;
	- line 1650: execpolicy_amendment: ExecPolicyAmendment {
	- line 1673: execpolicy_amendment: ExecPolicyAmendment {
	- line 2308: ReviewDecision::Approved,
	- line 2334: ReviewDecision::Approved,
	- line 2344: ReviewDecision::ApprovedForSession,


codex-rs/core/src/tools/orchestrator.rs (14 lines):
	- line 10: use crate::guardian::GuardianReviewContext;
	- line 32: use codex_protocol::protocol::AskForApproval;
	- line 33: use codex_protocol::protocol::ReviewDecision;
	- line 135: let approval_policy = tool_ctx.step_context.settings.approval_policy();
	- line 171: default_exec_approval_requirement(approval_policy, &file_system_sandbox_policy)
	- line 182: review_context: GuardianReviewContext::from(&tool_ctx.step_context),
	- line 200: &ReviewDecision::Approved,
	- line 215: review_context: GuardianReviewContext::from(&tool_ctx.step_context),
	- line 365: if !tool.wants_no_sandbox_approval(approval_policy) {
	- line 367: matches!(approval_policy, AskForApproval::OnRequest)
	- line 371: approval_policy,
	- line 408: // retrying without the sandbox requires a fresh guardian review.
	- line 410: && tool.should_bypass_approval(approval_policy, already_approved)
	- line 424: review_context: GuardianReviewContext::from(&tool_ctx.step_context),


codex-rs/core/src/agent/control/user_authorization.rs (14 lines):
	- line 2: use crate::codex_thread::GuardianAuthorizationVersion;
	- line 3: use crate::codex_thread::GuardianRootMessage;
	- line 4: use crate::codex_thread::GuardianRootSnapshot;
	- line 6: use crate::context::GuardianReviewEvidence;
	- line 8: use crate::guardian::guardian_truncate_text;
	- line 25: ) -> Option<GuardianRootSnapshot> {
	- line 41: .get::<GuardianReviewEvidence>();
	- line 52: GuardianRootMessage::User(
	- line 53: guardian_truncate_text(&message, MAX_ROOT_MESSAGE_TOKENS).0,
	- line 67: Some(GuardianRootMessage::Assistant(
	- line 68: guardian_truncate_text(&text, MAX_ROOT_MESSAGE_TOKENS).0,
	- line 74: .map(GuardianRootMessage::UserInput),
	- line 81: || GuardianAuthorizationVersion::from_history(history.as_ref()),
	- line 89: Some(GuardianRootSnapshot {


codex-rs/app-server-protocol/src/protocol/common.rs (14 lines):
	- line 667: ThreadApproveGuardianDeniedAction => "thread/approveGuardianDeniedAction" {
	- line 668: params: v2::ThreadApproveGuardianDeniedActionParams,
	- line 670: response: v2::ThreadApproveGuardianDeniedActionResponse,
	- line 1870: ItemGuardianApprovalReviewStarted => "item/autoApprovalReview/started" (v2::ItemGuardianApprovalReviewStartedNotification),
	- line 1871: ItemGuardianApprovalReviewCompleted => "item/autoApprovalReview/completed" (v2::ItemGuardianApprovalReviewCompletedNotification),
	- line 1921: GuardianWarning => "guardianWarning" (v2::GuardianWarningNotification),
	- line 2447: let guardian_approval = ClientRequest::ThreadApproveGuardianDeniedAction {
	- line 2449: params: v2::ThreadApproveGuardianDeniedActionParams {
	- line 2450: thread_id: "guardian-thread".to_string(),
	- line 2451: event: json!({ "type": "guardian" }),
	- line 2455: guardian_approval.serialization_scope(),
	- line 2457: thread_id: "guardian-thread".to_string()
	- line 3154: approval_policy: v2::AskForApproval::OnRequest,
	- line 4399: approval_policy: v2::AskForApproval::Never,


codex-rs/app-server-protocol/schema/typescript/v2/index.ts (14 lines):
	- line 42: export type { AskForApproval } from "./AskForApproval";
	- line 46: export type { AutoReviewDecisionSource } from "./AutoReviewDecisionSource";
	- line 130: export type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
	- line 200: export type { GuardianApprovalReview } from "./GuardianApprovalReview";
	- line 201: export type { GuardianApprovalReviewAction } from "./GuardianApprovalReviewAction";
	- line 202: export type { GuardianApprovalReviewStatus } from "./GuardianApprovalReviewStatus";
	- line 203: export type { GuardianCommandSource } from "./GuardianCommandSource";
	- line 204: export type { GuardianRiskLevel } from "./GuardianRiskLevel";
	- line 205: export type { GuardianUserAuthorization } from "./GuardianUserAuthorization";
	- line 206: export type { GuardianWarningNotification } from "./GuardianWarningNotification";
	- line 229: export type { ItemGuardianApprovalReviewCompletedNotification } from "./ItemGuardianApprovalReviewCompletedNotification";
	- line 230: export type { ItemGuardianApprovalReviewStartedNotification } from "./ItemGuardianApprovalReviewStartedNotification";
	- line 459: export type { ThreadApproveGuardianDeniedActionParams } from "./ThreadApproveGuardianDeniedActionParams";
	- line 460: export type { ThreadApproveGuardianDeniedActionResponse } from "./ThreadApproveGuardianDeniedActionResponse";


codex-rs/ext/guardian-v2/src/sync_reviewer/mod.rs (13 lines):
	- line 29: /// Guardian extension dependencies supplied by the host at construction time.
	- line 31: pub struct GuardianExtension<S> {
	- line 36: impl<S> GuardianExtension<S> {
	- line 37: /// Creates a guardian extension with its host-owned internal-session spawner.
	- line 114: .enabled(Feature::GuardianEnhancedNodeReplTranscripts);
	- line 119: .enabled(Feature::GuardianNodeReplTranscriptImages)
	- line 127: let root_authorization = parent.guardian_root_snapshot().await;
	- line 140: /// Thread-local guardian state captured after the host registers a thread.
	- line 142: pub struct GuardianThreadContext {
	- line 146: impl<S> ThreadLifecycleContributor<Config> for GuardianExtension<S>
	- line 169: .insert(GuardianThreadContext { parent_thread_id });
	- line 174: /// Installs the guardian contributors into the extension registry.
	- line 182: registry.thread_lifecycle_contributor(Arc::new(GuardianExtension::new(


codex-rs/config/src/state.rs (13 lines):
	- line 57: pub ignore_user_and_project_exec_policy_rules: bool,
	- line 81: ignore_user_and_project_exec_policy_rules: false,
	- line 262: ignore_user_and_project_exec_policy_rules: bool,
	- line 283: ignore_user_and_project_exec_policy_rules: false,
	- line 288: pub fn with_user_and_project_exec_policy_rules_ignored(
	- line 290: ignore_user_and_project_exec_policy_rules: bool,
	- line 292: self.ignore_user_and_project_exec_policy_rules = ignore_user_and_project_exec_policy_rules;
	- line 296: pub fn ignore_user_and_project_exec_policy_rules(&self) -> bool {
	- line 297: self.ignore_user_and_project_exec_policy_rules
	- line 411: ignore_user_and_project_exec_policy_rules: self
	- line 412: .ignore_user_and_project_exec_policy_rules,
	- line 445: ignore_user_and_project_exec_policy_rules: self
	- line 446: .ignore_user_and_project_exec_policy_rules,


codex-rs/config/src/loader/mod.rs (13 lines):
	- line 47: use codex_protocol::protocol::AskForApproval;
	- line 192: let ignore_user_and_project_exec_policy_rules =
	- line 193: overrides.ignore_user_and_project_exec_policy_rules;
	- line 519: .with_user_and_project_exec_policy_rules_ignored(ignore_user_and_project_exec_policy_rules);
	- line 958: approval_policy,
	- line 963: if let Some(approval_policy) = approval_policy {
	- line 966: toml_value_from_serializable(vec![approval_policy])?,
	- line 1907: /// structure as `config.toml` where fields like `approval_policy` can specify
	- line 1916: approval_policy: Option<AskForApproval>,
	- line 1969: approval_policy: None,
	- line 1988: fn legacy_managed_config_backfill_allows_user_when_guardian_is_required() -> io::Result<()> {
	- line 1990: approval_policy: None,
	- line 2011: approval_policy: None,


codex-rs/core/src/network_policy_decision.rs (13 lines):
	- line 1: use codex_execpolicy::Decision as ExecPolicyDecision;
	- line 2: use codex_execpolicy::NetworkRuleProtocol as ExecPolicyNetworkRuleProtocol;
	- line 12: pub(crate) struct ExecPolicyNetworkRuleAmendment {
	- line 13: pub protocol: ExecPolicyNetworkRuleProtocol,
	- line 14: pub decision: ExecPolicyDecision,
	- line 78: ) -> ExecPolicyNetworkRuleAmendment {
	- line 80: NetworkApprovalProtocol::Http => ExecPolicyNetworkRuleProtocol::Http,
	- line 81: NetworkApprovalProtocol::Https => ExecPolicyNetworkRuleProtocol::Https,
	- line 82: NetworkApprovalProtocol::Socks5Tcp => ExecPolicyNetworkRuleProtocol::Socks5Tcp,
	- line 83: NetworkApprovalProtocol::Socks5Udp => ExecPolicyNetworkRuleProtocol::Socks5Udp,
	- line 86: NetworkPolicyRuleAction::Allow => (ExecPolicyDecision::Allow, "Allow"),
	- line 87: NetworkPolicyRuleAction::Deny => (ExecPolicyDecision::Forbidden, "Deny"),
	- line 97: ExecPolicyNetworkRuleAmendment {


codex-rs/tui/src/history_cell/approvals.rs (12 lines):
	- line 25: pub(crate) enum ReviewDecision {
	- line 28: proposed_execpolicy_amendment: ExecPolicyAmendment,
	- line 47: decision: ReviewDecision,
	- line 50: use ReviewDecision::*;
	- line 170: ApprovalDecisionActor::Guardian => vec![
	- line 184: ApprovalDecisionActor::Guardian => {
	- line 269: Guardian,
	- line 276: Self::Guardian => "Auto-reviewer ",
	- line 281: pub fn new_guardian_denied_patch_request(files: Vec<String>) -> Box<dyn HistoryCell> {
	- line 303: pub fn new_guardian_denied_action_request(summary: String) -> Box<dyn HistoryCell> {
	- line 313: pub fn new_guardian_timed_out_patch_request(files: Vec<String>) -> Box<dyn HistoryCell> {
	- line 335: pub fn new_guardian_timed_out_action_request(summary: String) -> Box<dyn HistoryCell> {


codex-rs/app-server-protocol/src/protocol/v2/thread.rs (12 lines):
	- line 3: use super::AskForApproval;
	- line 88: pub approval_policy: Option<AskForApproval>,
	- line 196: pub approval_policy: AskForApproval,
	- line 234: pub approval_policy: Option<AskForApproval>,
	- line 291: pub approval_policy: AskForApproval,
	- line 378: pub approval_policy: Option<AskForApproval>,
	- line 430: pub approval_policy: AskForApproval,
	- line 565: pub approval_policy: Option<AskForApproval>,
	- line 621: pub approval_policy: AskForApproval,
	- line 1148: pub struct ThreadApproveGuardianDeniedActionParams {
	- line 1150: /// Serialized `codex_protocol::protocol::GuardianAssessmentEvent`.
	- line 1157: pub struct ThreadApproveGuardianDeniedActionResponse {}


codex-rs/core/src/context/mod.rs (12 lines):
	- line 13: mod guardian_approved_action;
	- line 14: mod guardian_followup_review_reminder;
	- line 15: mod guardian_node_repl_policy;
	- line 16: mod guardian_policy;
	- line 17: mod guardian_review_evidence;
	- line 65: pub(crate) use guardian_approved_action::GuardianApprovedAction;
	- line 66: pub(crate) use guardian_followup_review_reminder::GuardianFollowupReviewReminder;
	- line 67: pub(crate) use guardian_node_repl_policy::GuardianNodeReplPolicy;
	- line 68: pub(crate) use guardian_policy::GuardianPolicy;
	- line 69: pub use guardian_review_evidence::GuardianReviewEvidence;
	- line 70: pub use guardian_review_evidence::GuardianReviewEvidenceFragment;
	- line 71: pub use guardian_review_evidence::GuardianReviewEvidenceRecord;


codex-rs/network-proxy/src/network_policy.rs (12 lines):
	- line 108: pub exec_policy_hint: Option<String>,
	- line 122: pub exec_policy_hint: Option<String>,
	- line 135: exec_policy_hint,
	- line 145: exec_policy_hint,
	- line 314: /// If `command` or `exec_policy_hint` is provided, callers can map exec-policy
	- line 696: exec_policy_hint: None,
	- line 746: exec_policy_hint: None,
	- line 811: exec_policy_hint: None,
	- line 852: exec_policy_hint: None,
	- line 898: exec_policy_hint: None,
	- line 949: exec_policy_hint: None,
	- line 1036: exec_policy_hint: None,


codex-rs/codex-mcp/src/elicitation.rs (12 lines):
	- line 29: use codex_protocol::protocol::AskForApproval;
	- line 248: let approval_policy = config.approval_policy.value();
	- line 264: approval_policy,
	- line 265: AskForApproval::Granular(config) if !config.allows_mcp_elicitations()
	- line 309: approval_policy,
	- line 343: if elicitation_is_rejected_by_policy(approval_policy) {
	- line 472: pub(crate) fn elicitation_is_rejected_by_policy(approval_policy: AskForApproval) -> bool {
	- line 473: match approval_policy {
	- line 474: AskForApproval::Never => true,
	- line 475: AskForApproval::OnRequest => false,
	- line 476: AskForApproval::UnlessTrusted => false,
	- line 477: AskForApproval::Granular(granular_config) => !granular_config.allows_mcp_elicitations(),


codex-rs/tui/src/app_command.rs (12 lines):
	- line 3: use codex_app_server_protocol::AskForApproval;
	- line 12: use codex_protocol::approvals::GuardianAssessmentEvent;
	- line 35: approval_policy: AskForApproval,
	- line 48: approval_policy: Option<AskForApproval>,
	- line 96: ApproveGuardianDeniedAction {
	- line 97: event: GuardianAssessmentEvent,
	- line 118: approval_policy: AskForApproval,
	- line 131: approval_policy,
	- line 147: approval_policy: Option<AskForApproval>,
	- line 161: approval_policy,
	- line 238: pub(crate) fn approve_guardian_denied_action(event: GuardianAssessmentEvent) -> Self {
	- line 239: Self::ApproveGuardianDeniedAction { event }


codex-rs/tui/src/chatwidget/status_state.rs (12 lines):
	- line 21: pub(super) fn is_guardian_review(&self) -> bool {
	- line 40: pub(super) struct PendingGuardianReviewStatus {
	- line 41: entries: Vec<PendingGuardianReviewStatusEntry>,
	- line 45: struct PendingGuardianReviewStatusEntry {
	- line 50: impl PendingGuardianReviewStatus {
	- line 56: .push(PendingGuardianReviewStatusEntry { id, detail });
	- line 74: // Guardian review status is derived from the full set of currently pending
	- line 76: // footer is currently rendered; this helper computes the guardian-specific
	- line 114: pub(super) pending_guardian_review_status: PendingGuardianReviewStatus,
	- line 124: pending_guardian_review_status: PendingGuardianReviewStatus::default(),
	- line 155: fn guardian_status_aggregates_parallel_reviews() {
	- line 156: let mut state = PendingGuardianReviewStatus::default();


codex-rs/core/src/codex_delegate.rs (11 lines):
	- line 7: use codex_protocol::protocol::AskForApproval;
	- line 45: pub(crate) struct GuardianReadOnlyHistoryTools(
	- line 67: if config.permissions.approval_policy.value() != AskForApproval::Never {
	- line 72: config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);
	- line 87: let is_guardian_reviewer = crate::guardian::is_basic_session_source(&session_source);
	- line 89: if is_guardian_reviewer {
	- line 106: thread_extension_init.insert(GuardianReadOnlyHistoryTools(history_tools));
	- line 109: let extensions = if is_guardian_reviewer {
	- line 136: thread_source: Some(if is_guardian_reviewer {
	- line 137: ThreadSource::GuardianReview
	- line 147: inherited_exec_policy: Some(Arc::clone(&parent_session.services.exec_policy)),


codex-rs/tui/src/app/event_dispatch.rs (11 lines):
	- line 2041: /*approval_policy*/ None,
	- line 2068: /*approval_policy*/ None,
	- line 2097: Some(AskForApproval::from(preset.approval)),
	- line 2111: self.app_event_tx.send(AppEvent::UpdateAskForApprovalPolicy(
	- line 2112: AskForApproval::from(preset.approval),
	- line 2266: AppEvent::UpdateAskForApprovalPolicy(policy) => {
	- line 2268: if !self.try_set_approval_policy_on_config(
	- line 2277: let approval_policy =
	- line 2278: AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 2279: self.runtime_approval_policy_override = Some(approval_policy);
	- line 2280: self.chat_widget.set_approval_policy(approval_policy);


codex-rs/tui/src/status/card.rs (11 lines):
	- line 14: use codex_app_server_protocol::AskForApproval;
	- line 282: let approval_policy = AskForApproval::from(config.permissions.approval_policy.value());
	- line 291: config.permissions.approval_policy.value().to_string(),
	- line 326: let approval = status_approval_label(approval_policy, config.approvals_reviewer, &approval);
	- line 330: approval_policy,
	- line 639: approval_policy: AskForApproval,
	- line 672: return if approval_policy == AskForApproval::Never {
	- line 688: if approval_policy == AskForApproval::OnRequest && sandbox == "workspace" {
	- line 694: if approval_policy == AskForApproval::Never
	- line 711: approval_policy: AskForApproval,
	- line 715: if approval_policy == AskForApproval::OnRequest {


codex-rs/core/src/context/node_repl_review_evidence.rs (10 lines):
	- line 17: use crate::guardian::GUARDIAN_MAX_NODE_REPL_TOOL_RESULT_TOKENS;
	- line 18: use crate::guardian::guardian_truncate_text;
	- line 25: /// Controls which retained REPL evidence a Guardian reviewer may receive.
	- line 36: || features.enabled(Feature::GuardianEnhancedNodeReplTranscripts)
	- line 37: && features.enabled(Feature::GuardianNodeReplTranscriptImages)
	- line 40: } else if features.enabled(Feature::GuardianEnhancedNodeReplTranscripts) {
	- line 100: /// Enables screenshot capture even when synchronous Guardian transcripts are disabled.
	- line 135: /// Returns bounded REPL evidence using the existing Guardian text and image layout.
	- line 187: let (text, _) = guardian_truncate_text(
	- line 374: ContentItemKind("guardian.node_repl_review_evidence".to_string())


codex-rs/analytics/src/lib.rs (10 lines):
	- line 15: pub use events::GuardianApprovalRequestSource;
	- line 16: pub use events::GuardianReviewAnalyticsResult;
	- line 17: pub use events::GuardianReviewDecision;
	- line 18: pub use events::GuardianReviewEventParams;
	- line 19: pub use events::GuardianReviewFailureReason;
	- line 20: pub use events::GuardianReviewSessionAnalyticsParams;
	- line 21: pub use events::GuardianReviewSessionKind;
	- line 22: pub use events::GuardianReviewTerminalStatus;
	- line 23: pub use events::GuardianReviewTrackContext;
	- line 24: pub use events::GuardianReviewedAction;


codex-rs/analytics/src/client.rs (10 lines):
	- line 2: use crate::events::GuardianReviewAnalyticsResult;
	- line 3: use crate::events::GuardianReviewTrackContext;
	- line 349: /// Logs Guardian turn and tool events that bypass the app-server listener.
	- line 350: pub fn track_guardian_session_event(&self, thread_id: ThreadId, event: &Event) {
	- line 395: pub fn track_guardian_review(
	- line 397: tracking: &GuardianReviewTrackContext,
	- line 398: result: GuardianReviewAnalyticsResult,
	- line 401: self.record_fact(AnalyticsFact::Custom(CustomAnalyticsFact::GuardianReview(
	- line 722: | ServerNotification::ItemGuardianApprovalReviewStarted(_)
	- line 723: | ServerNotification::ItemGuardianApprovalReviewCompleted(_)


codex-rs/app-server/src/request_processors/turn_processor.rs (9 lines):
	- line 118: approval_policy: Option<codex_app_server_protocol::AskForApproval>,
	- line 609: approval_policy: params.approval_policy,
	- line 761: approval_policy,
	- line 792: || approval_policy.is_some()
	- line 803: let approval_policy =
	- line 804: approval_policy.map(codex_app_server_protocol::AskForApproval::to_core);
	- line 857: approval_policy,
	- line 880: approval_policy,
	- line 918: approval_policy: params.approval_policy,


codex-rs/core/src/lib.rs (9 lines):
	- line 46: pub use codex_thread::GuardianAuthorizationVersion;
	- line 47: pub use codex_thread::GuardianRootMessage;
	- line 48: pub use codex_thread::GuardianRootSnapshot;
	- line 66: mod exec_policy;
	- line 69: mod guardian;
	- line 205: pub use exec_policy::ExecPolicyError;
	- line 206: pub use exec_policy::check_execpolicy_for_warnings;
	- line 207: pub use exec_policy::format_exec_policy_error_with_source;
	- line 208: pub use exec_policy::load_exec_policy;


codex-rs/core/src/client.rs (9 lines):
	- line 297: free_guardian_enabled: bool,
	- line 519: free_guardian_enabled: false,
	- line 525: pub(crate) fn with_free_guardian_enabled(mut self, free_guardian_enabled: bool) -> Self {
	- line 526: self.free_guardian_enabled = free_guardian_enabled;
	- line 1084: if self.free_guardian_enabled
	- line 1085: && crate::guardian::is_basic_session_source(&self.state.session_source)
	- line 1090: ResponsesEndpoint::Guardian
	- line 1618: if endpoint == ResponsesEndpoint::Guardian {
	- line 1761: if endpoint == ResponsesEndpoint::Guardian {


codex-rs/core/src/exec_policy/executable_identity.rs (9 lines):
	- line 3: use super::ExecPolicyCommandOrigin;
	- line 5: use super::ExecPolicyCommands;
	- line 6: use super::ExecPolicyManager;
	- line 7: use super::commands_for_exec_policy;
	- line 17: impl ExecPolicyManager {
	- line 34: Some((_, script)) => ExecPolicyCommands {
	- line 37: command_origin: ExecPolicyCommandOrigin::PowerShell,
	- line 39: None => commands_for_exec_policy(command),
	- line 43: let mut policy_commands = commands_for_exec_policy(command);


codex-rs/guardian-context/src/lib.rs (9 lines):
	- line 1: //! Shared context sections for synchronous Guardian review and asynchronous scoring.
	- line 35: /// Consumer for which a Guardian context is composed.
	- line 38: /// The reusable synchronous Guardian reviewer.
	- line 40: /// The asynchronous Guardian action scorer.
	- line 66: /// Borrowed host inputs available while one Guardian context section is built.
	- line 99: /// Supplies one independently scoped section to Guardian context assembly.
	- line 108: /// Guardian consumers that should receive this contribution.
	- line 138: /// Ordered collection of independently scoped Guardian section contributors.
	- line 144: /// Shared, process-lifetime registry of built-in Guardian sections.


codex-rs/tui/src/app/thread_settings.rs (9 lines):
	- line 10: use codex_app_server_protocol::AskForApproval as AppServerAskForApproval;
	- line 34: || AppServerAskForApproval::from(
	- line 38: .approval_policy
	- line 40: ) != AppServerAskForApproval::OnRequest);
	- line 81: params.approval_policy = Some(AppServerAskForApproval::OnRequest);
	- line 152: approval_policy,
	- line 173: approval_policy: *approval_policy,
	- line 235: session.approval_policy = settings.approval_policy;
	- line 255: || params.approval_policy.is_some()


codex-rs/app-server/src/lib.rs (9 lines):
	- line 59: use codex_core::ExecPolicyError;
	- line 84: fn is_unsupported_untrusted_approval_policy_error(err: &std::io::Error) -> bool {
	- line 315: fn exec_policy_warning_location(err: &ExecPolicyError) -> (Option<String>, Option<AppTextRange>) {
	- line 317: ExecPolicyError::ParsePolicy { path, source } => {
	- line 337: fn exec_policy_config_warning(err: &ExecPolicyError) -> ConfigWarningNotification {
	- line 338: let (path, range) = exec_policy_warning_location(err);
	- line 519: Err(err) if is_unsupported_untrusted_approval_policy_error(&err) => {
	- line 534: Err(err) if is_unsupported_untrusted_approval_policy_error(&err) => {
	- line 627: config_warnings.push(exec_policy_config_warning(&err));


codex-rs/core/src/context/world_state/permissions.rs (8 lines):
	- line 11: use codex_protocol::protocol::AskForApproval;
	- line 37: approval_policy: AskForApproval,
	- line 39: exec_policy: &Policy,
	- line 44: let build_instructions = |exec_policy| {
	- line 47: approval_policy,
	- line 49: exec_policy,
	- line 55: let instructions = build_instructions(exec_policy);
	- line 59: approved_command_prefixes: exec_policy.get_allowed_prefixes().into_iter().collect(),


codex-rs/core/src/unified_exec/process_manager.rs (8 lines):
	- line 24: use crate::exec_policy::ExecApprovalRequest;
	- line 25: use crate::guardian::GuardianReviewContext;
	- line 834: let reviewed = crate::guardian::format_guardian_action_pretty(
	- line 835: &approval.clone().into_guardian_request().map_err(|err| {
	- line 866: review_context: GuardianReviewContext::from(&context.step_context),
	- line 1375: .exec_policy
	- line 1379: approval_policy: context.step_context.settings.approval_policy(),
	- line 1381: environment_policy: request.turn_environment.config().exec_policy.as_ref(),


codex-rs/core/src/tools/runtimes/unified_exec.rs (8 lines):
	- line 9: use crate::guardian::GUARDIAN_REVIEW_TIMEOUT;
	- line 10: use crate::guardian::GuardianNetworkAccessTrigger;
	- line 11: use crate::guardian::routes_approval_policy_to_guardian;
	- line 60: // Allow 5s for Guardian cleanup and 5s for controller processing after review.
	- line 238: trigger: GuardianNetworkAccessTrigger {
	- line 295: if routes_approval_policy_to_guardian(
	- line 296: ctx.step_context.settings.approval_policy(),
	- line 586: exec_policy: None,


codex-rs/mcp-server/src/codex_tool_config.rs (8 lines):
	- line 9: use codex_protocol::protocol::AskForApproval;
	- line 41: pub approval_policy: Option<CodexToolCallApprovalPolicy>,
	- line 65: /// Custom enum mirroring [`AskForApproval`], but has an extra dependency on
	- line 74: impl From<CodexToolCallApprovalPolicy> for AskForApproval {
	- line 77: CodexToolCallApprovalPolicy::OnRequest => AskForApproval::OnRequest,
	- line 78: CodexToolCallApprovalPolicy::Never => AskForApproval::Never,
	- line 150: approval_policy,
	- line 162: approval_policy: approval_policy.map(Into::into),


codex-rs/core/src/tools/handlers/request_user_input.rs (8 lines):
	- line 1: use crate::codex_thread::GuardianRootMessage;
	- line 2: use crate::context::GuardianReviewEvidence;
	- line 4: use crate::guardian::guardian_truncate_text;
	- line 130: GuardianRootMessage::Assistant(question_text).render(),
	- line 131: GuardianRootMessage::User(answers.join("\n")).render()
	- line 136: if !user_input.is_empty() && turn.config.features.enabled(Feature::GuardianApproval) {
	- line 137: let fragment = guardian_truncate_text(&user_input, MAX_GUARDIAN_USER_INPUT_TOKENS).0;
	- line 141: .get_or_init(GuardianReviewEvidence::default)


codex-rs/core/src/session_startup_prewarm.rs (8 lines):
	- line 15: use crate::guardian::routes_approval_to_guardian;
	- line 275: if routes_approval_to_guardian(&startup_turn_context) {
	- line 276: let guardian_session = Arc::clone(&session);
	- line 277: let guardian_parent_turn = Arc::clone(&startup_turn_context);
	- line 279: if let Err(err) = guardian_session
	- line 280: .guardian_review_session
	- line 281: .initialize(Arc::clone(&guardian_session), guardian_parent_turn)
	- line 284: warn!("failed to initialize guardian review session: {err:#}");


codex-rs/core/src/session/turn.rs (8 lines):
	- line 678: if crate::guardian::is_basic_session_source(&turn_context.session_source) {
	- line 782: // Guardian input embeds the parent transcript as untrusted evidence. Do not interpret skill or
	- line 784: if crate::guardian::is_basic_session_source(&turn_context.session_source) {
	- line 1022: approval_policy: turn_context.approval_policy(),
	- line 1345: output_schema_strict: !crate::guardian::is_basic_session_source(
	- line 1805: | EventMsg::GuardianWarning(_)
	- line 1847: | EventMsg::GuardianAssessment(_)
	- line 2221: approval_policy = turn_context.approval_policy(),


codex-rs/core/src/session/turn_context.rs (8 lines):
	- line 8: use crate::exec_policy::AllowPrefixRules;
	- line 338: pub(crate) fn approval_policy(&self) -> AskForApproval {
	- line 339: self.config.permissions.approval_policy.value()
	- line 585: approval_policy: self.approval_policy(),
	- line 651: per_turn_config.permissions.approval_policy =
	- line 652: session_configuration.step_settings.approval_policy.clone();
	- line 757: let auto_review_enabled = crate::guardian::routes_approval_policy_to_guardian(
	- line 758: per_turn_config.permissions.approval_policy.value(),


codex-rs/state/src/extract.rs (8 lines):
	- line 100: metadata.approval_mode = enum_to_string(&turn_ctx.approval_policy);
	- line 132: metadata.approval_mode = enum_to_string(&settings.approval_policy);
	- line 188: use codex_protocol::protocol::AskForApproval;
	- line 436: approval_policy: AskForApproval::Never,
	- line 484: approval_policy: AskForApproval::OnRequest,
	- line 528: approval_policy: AskForApproval::OnRequest,
	- line 569: approval_policy: AskForApproval::OnRequest,
	- line 608: approval_policy: AskForApproval::Never,


codex-rs/core/src/config/network_proxy_spec.rs (7 lines):
	- line 186: exec_policy: &Policy,
	- line 234: let (allowed_domains, denied_domains) = exec_policy.compiled_network_domains();
	- line 251: pub(crate) fn with_exec_policy_network_rules(
	- line 253: exec_policy: &Policy,
	- line 256: apply_exec_policy_network_rules(&mut spec.config, exec_policy);
	- line 434: fn apply_exec_policy_network_rules(config: &mut NetworkProxyConfig, exec_policy: &Policy) {
	- line 435: let (allowed_domains, denied_domains) = exec_policy.compiled_network_domains();


codex-rs/core/src/tools/handlers/mod.rs (7 lines):
	- line 57: use codex_protocol::protocol::AskForApproval;
	- line 180: approval_policy: AskForApproval,
	- line 202: if !permissions_preapproved && !matches!(approval_policy, AskForApproval::OnRequest) {
	- line 204: "approval policy is {approval_policy:?}; reject command — you cannot request additional permissions unless the approval policy is OnRequest"
	- line 356: use codex_protocol::protocol::AskForApproval;
	- line 392: AskForApproval::Granular(GranularApprovalConfig {
	- line 415: AskForApproval::OnRequest,


codex-rs/tui/src/lib.rs (7 lines):
	- line 36: use codex_app_server_protocol::AskForApproval;
	- line 908: && !loader_overrides.ignore_user_and_project_exec_policy_rules
	- line 1969: use codex_app_server_protocol::AskForApproval;
	- line 3454: AskForApproval::from(trusted_config.permissions.approval_policy.value()),
	- line 3455: AskForApproval::OnRequest
	- line 3469: AskForApproval::from(untrusted_config.permissions.approval_policy.value()),
	- line 3470: AskForApproval::UnlessTrusted


codex-rs/app-server-protocol/src/protocol/v2/permissions.rs (7 lines):
	- line 4: use codex_protocol::approvals::ExecPolicyAmendment as CoreExecPolicyAmendment;
	- line 720: pub struct ExecPolicyAmendment {
	- line 724: impl ExecPolicyAmendment {
	- line 725: pub fn into_core(self) -> CoreExecPolicyAmendment {
	- line 726: CoreExecPolicyAmendment::new(self.command)
	- line 730: impl From<CoreExecPolicyAmendment> for ExecPolicyAmendment {
	- line 731: fn from(value: CoreExecPolicyAmendment) -> Self {


codex-rs/core/src/session/world_state.rs (7 lines):
	- line 159: let exec_policy = self
	- line 161: .exec_policy
	- line 175: step_context.settings.approval_policy(),
	- line 181: exec_policy.as_ref(),
	- line 193: world_state.add_section(CompactPermissionsState::new(exec_policy.as_ref()));
	- line 207: if !crate::guardian::is_basic_session_source(&turn_context.session_source) {
	- line 324: if !crate::guardian::is_basic_session_source(&turn_context.session_source) {


codex-rs/tui/src/app/app_server_event_targets.rs (7 lines):
	- line 87: ServerNotification::ItemGuardianApprovalReviewStarted(notification) => {
	- line 90: ServerNotification::ItemGuardianApprovalReviewCompleted(notification) => {
	- line 183: ServerNotification::GuardianWarning(notification) => Some(notification.thread_id.as_str()),
	- line 230: use codex_app_server_protocol::GuardianWarningNotification;
	- line 247: approval_policy: codex_app_server_protocol::AskForApproval::Never,
	- line 297: fn guardian_warning_notifications_route_to_threads() {
	- line 299: let notification = ServerNotification::GuardianWarning(GuardianWarningNotification {


codex-rs/ext/guardian-v2/src/async_scorer/metrics.rs (7 lines):
	- line 1: //! Low-cardinality metrics for Guardian V2 classification and approval decisions.
	- line 7: pub(super) const CLASSIFICATION_METRIC: &str = "codex.guardian_v2.classification";
	- line 9: "codex.guardian_v2.classification.duration_ms";
	- line 10: pub(super) const CLASSIFICATION_RISK_METRIC: &str = "codex.guardian_v2.classification.risk";
	- line 11: pub(super) const FAST_DECISION_METRIC: &str = "codex.guardian_v2.fast_decision";
	- line 12: pub(super) const REVIEW_FALLBACK_METRIC: &str = "codex.guardian_v2.review_fallback";
	- line 13: pub(super) const TOOL_CALL_LAG_METRIC: &str = "codex.guardian_v2.tool_call_lag";


codex-rs/config/src/lib.rs (7 lines):
	- line 28: mod requirements_exec_policy;
	- line 65: pub use codex_execpolicy::RequirementsExecPolicy;
	- line 167: pub use requirements_exec_policy::RequirementsExecPolicyDecisionToml;
	- line 168: pub use requirements_exec_policy::RequirementsExecPolicyParseError;
	- line 169: pub use requirements_exec_policy::RequirementsExecPolicyPatternTokenToml;
	- line 170: pub use requirements_exec_policy::RequirementsExecPolicyPrefixRuleToml;
	- line 171: pub use requirements_exec_policy::RequirementsExecPolicyToml;


sdk/python/src/openai_codex/_approval_mode.py (6 lines):
	- line 8: AskForApproval,
	- line 9: AskForApprovalValue,
	- line 22: ) -> tuple[AskForApproval, ApprovalsReviewer | None]:
	- line 31: AskForApproval(root=AskForApprovalValue.on_request),
	- line 35: return AskForApproval(root=AskForApprovalValue.never), None
	- line 47: ) -> tuple[AskForApproval | None, ApprovalsReviewer | None]:


codex-rs/tui/src/app/thread_routing.rs (6 lines):
	- line 658: approval_policy,
	- line 750: *approval_policy,
	- line 824: AppCommand::ApproveGuardianDeniedAction { event } => {
	- line 826: .thread_approve_guardian_denied_action(thread_id, event)
	- line 1283: .approval_policy
	- line 1284: .set(session.approval_policy.to_core())


codex-rs/mcp-server/src/outgoing_message.rs (6 lines):
	- line 244: use codex_protocol::protocol::AskForApproval;
	- line 333: approval_policy: AskForApproval::Never,
	- line 377: approval_policy: AskForApproval::Never,
	- line 414: "approval_policy": "never",
	- line 443: approval_policy: AskForApproval::Never,
	- line 481: "approval_policy": "never",


codex-rs/rmcp-client/src/stdio_server_launcher.rs (6 lines):
	- line 727: let exec_policy =
	- line 730: inherit: exec_policy.inherit,
	- line 731: ignore_default_excludes: exec_policy.ignore_default_excludes,
	- line 732: exclude: exec_policy
	- line 737: r#set: exec_policy.r#set,
	- line 738: include_only: exec_policy


codex-rs/core/src/tools/spec_plan.rs (6 lines):
	- line 155: let hosted_specs = if crate::guardian::is_basic_session_source(&turn_context.session_source) {
	- line 159: .get::<crate::codex_delegate::GuardianReadOnlyHistoryTools>()
	- line 322: if crate::guardian::is_basic_session_source(&turn_context.session_source) {
	- line 614: || crate::guardian::is_basic_session_source(&turn_context.session_source)
	- line 986: // Guardian reviewers receive only `exec_command`, `write_stdin`, and `view_image`
	- line 989: if crate::guardian::is_basic_session_source(&context.turn_context.session_source) {


codex-rs/app-server/src/request_processors/feedback_processor.rs (6 lines):
	- line 189: // descendants (oldest to newest within the retained recent set), guardian rollout,
	- line 208: && let Some(guardian_rollout_path) =
	- line 209: conversation.guardian_trunk_rollout_path().await
	- line 210: && seen_attachment_paths.insert(guardian_rollout_path.clone())
	- line 213: path: guardian_rollout_path,
	- line 712: approval_policy: codex_protocol::protocol::AskForApproval::Never,


codex-rs/core/src/safety.rs (6 lines):
	- line 10: use codex_protocol::protocol::AskForApproval;
	- line 28: policy: AskForApproval,
	- line 41: AskForApproval::Never | AskForApproval::OnRequest | AskForApproval::Granular(_) => {
	- line 46: AskForApproval::UnlessTrusted => {
	- line 51: let rejects_sandbox_approval = matches!(policy, AskForApproval::Never)
	- line 54: AskForApproval::Granular(granular_config) if !granular_config.sandbox_approval


codex-rs/config/src/requirements_layers/stack.rs (6 lines):
	- line 252: guardian_policy_config,
	- line 306: if let Some(guardian_policy_config) =
	- line 307: guardian_policy_config.filter(|value| !value.trim().is_empty())
	- line 309: output.guardian_policy_config = Some(Sourced::new(
	- line 310: guardian_policy_config,
	- line 311: source_for_top_level_keys(layers, &["guardian_policy_config"]),


codex-rs/core/src/tools/runtimes/apply_patch.rs (6 lines):
	- line 26: use codex_protocol::protocol::AskForApproval;
	- line 134: fn wants_no_sandbox_approval(&self, policy: AskForApproval) -> bool {
	- line 136: AskForApproval::Never => false,
	- line 137: AskForApproval::Granular(granular_config) => granular_config.allows_sandbox_approval(),
	- line 138: AskForApproval::OnRequest => true,
	- line 139: AskForApproval::UnlessTrusted => true,


codex-rs/protocol/src/config_types.rs (6 lines):
	- line 177: #[ts(type = r#""user" | "auto_review" | "guardian_subagent""#)]
	- line 187: #[serde(rename = "auto_review", alias = "guardian_subagent")]
	- line 199: &["user", "auto_review", "guardian_subagent"],
	- line 200: "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.",
	- line 866: fn approvals_reviewer_serializes_auto_review_and_accepts_legacy_guardian_subagent() {
	- line 877: for value in ["user", "auto_review", "guardian_subagent"] {


codex-rs/cli/src/doctor.rs (6 lines):
	- line 61: use codex_protocol::protocol::AskForApproval;
	- line 605: let approval_policy = if interactive.dangerously_bypass_approvals_and_sandbox {
	- line 606: Some(AskForApproval::Never)
	- line 608: interactive.approval_policy.map(Into::into)
	- line 617: approval_policy,
	- line 3324: assert_eq!(overrides.approval_policy, Some(AskForApproval::Never));


codex-rs/tui/src/chatwidget.rs (6 lines):
	- line 92: use codex_app_server_protocol::GuardianApprovalReviewAction;
	- line 138: use codex_protocol::approvals::GuardianAssessmentAction;
	- line 139: use codex_protocol::approvals::GuardianAssessmentDecisionSource;
	- line 140: use codex_protocol::approvals::GuardianAssessmentEvent;
	- line 141: use codex_protocol::approvals::GuardianAssessmentStatus;
	- line 481: use codex_app_server_protocol::AskForApproval;


codex-rs/ext/guardian-v2/src/async_scorer/trusted_tools.rs (6 lines):
	- line 1: //! Attests home-owned MCP tools and renders their bounded Guardian context.
	- line 24: pub(crate) struct GuardianTrustedToolFragment {
	- line 28: impl ContextualUserFragment for GuardianTrustedToolFragment {
	- line 34: ContentItemKind("guardian.trusted_tool".to_owned())
	- line 68: ) -> Option<GuardianTrustedToolFragment> {
	- line 118: Some(GuardianTrustedToolFragment {


codex-rs/codex-api/src/endpoint/responses.rs (6 lines):
	- line 32: /// Full Guardian approval-review agent inference.
	- line 33: Guardian,
	- line 34: /// Lightweight asynchronous Guardian risk classification.
	- line 35: GuardianClassifier,
	- line 43: Self::Guardian => "/guardian",
	- line 44: Self::GuardianClassifier => "/guardian-classifier",


codex-rs/ext/extension-api/src/contributors/approval_review.rs (6 lines):
	- line 5: use codex_protocol::approvals::GuardianAssessmentOutcome;
	- line 6: use codex_protocol::approvals::GuardianRiskLevel;
	- line 7: use codex_protocol::approvals::GuardianUserAuthorization;
	- line 17: pub outcome: GuardianAssessmentOutcome,
	- line 19: pub risk_level: GuardianRiskLevel,
	- line 21: pub user_authorization: GuardianUserAuthorization,


codex-rs/tui/src/app/agents_overview.rs (5 lines):
	- line 402: let baseline_approval = resume_config.permissions.approval_policy.value();
	- line 448: self.runtime_approval_policy_override = None;
	- line 481: if self.config.permissions.approval_policy.value() != baseline_approval {
	- line 482: self.runtime_approval_policy_override =
	- line 483: Some(self.config.permissions.approval_policy.value().into());


codex-rs/protocol/src/openai_models/guardian_v2.rs (5 lines):
	- line 8: /// Optional model-owned defaults for Guardian v2 classification experiments.
	- line 10: pub struct GuardianV2ModelConfig {
	- line 20: pub transcript: Option<GuardianV2TranscriptModelConfig>,
	- line 31: /// Optional model-owned defaults for selecting and bounding Guardian v2 history.
	- line 33: pub struct GuardianV2TranscriptModelConfig {


codex-rs/thread-store/src/local/mod.rs (5 lines):
	- line 692: use codex_protocol::protocol::AskForApproval;
	- line 933: let turn_context = |model: &str, approval_policy| {
	- line 940: approval_policy,
	- line 963: &[turn_context("parent-model", AskForApproval::Never)],
	- line 979: .append_items(&[turn_context("child-model", AskForApproval::OnRequest)])


codex-rs/execpolicy/src/policy.rs (5 lines):
	- line 36: pub struct RequirementsExecPolicy {
	- line 40: impl RequirementsExecPolicy {
	- line 57: impl PartialEq for RequirementsExecPolicy {
	- line 63: impl Eq for RequirementsExecPolicy {}
	- line 65: impl AsRef<Policy> for RequirementsExecPolicy {


codex-rs/tui/src/chatwidget/turn_runtime.rs (5 lines):
	- line 19: fn clear_guardian_review_status(&mut self) {
	- line 20: self.status_state.pending_guardian_review_status.clear();
	- line 21: if self.status_state.current_status.is_guardian_review() {
	- line 182: self.clear_guardian_review_status();
	- line 328: self.clear_guardian_review_status();


codex-rs/config/src/config_toml.rs (5 lines):
	- line 55: use codex_protocol::protocol::AskForApproval;
	- line 175: #[schemars(with = "Option<crate::schema::ConfigAskForApproval>")]
	- line 176: pub approval_policy: Option<AskForApproval>,
	- line 183: /// Optional policy instructions for the guardian auto-reviewer.
	- line 540: /// Additional policy instructions inserted into the guardian prompt.


codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs (5 lines):
	- line 6: use crate::exec_policy::prompt_is_rejected_by_policy;
	- line 320: let approval_policy = context.step_context.settings.approval_policy();
	- line 325: && prompt_is_rejected_by_policy(approval_policy, /*prompt_is_rule*/ false).is_some()
	- line 329: "approval policy is {approval_policy:?}; reject command — you cannot ask for escalated permissions if the approval policy is {approval_policy:?}"
	- line 342: approval_policy,


codex-rs/tui/src/chatwidget/settings.rs (5 lines):
	- line 9: pub(crate) fn set_approval_policy(&mut self, policy: AskForApproval) {
	- line 13: .approval_policy
	- line 16: tracing::warn!(%err, "failed to set approval_policy on chat config");
	- line 462: self.set_approval_policy(settings.approval_policy);
	- line 701: /*approval_policy*/ None,


codex-rs/core/src/context/guardian_policy.rs (5 lines):
	- line 4: /// The isolated developer policy provided to a Guardian reviewer.
	- line 6: pub(crate) struct GuardianPolicy {
	- line 10: impl GuardianPolicy {
	- line 18: impl ContextualUserFragment for GuardianPolicy {
	- line 20: ContentItemKind("guardian.policy".to_string())


codex-rs/tui/src/startup_orchestration.rs (5 lines):
	- line 15: let (sandbox_mode, approval_policy) = if cli.dangerously_bypass_approvals_and_sandbox {
	- line 18: Some(AskForApproval::Never.to_core()),
	- line 23: cli.approval_policy.map(Into::into),
	- line 115: approval_policy,
	- line 327: approval_policy,


codex-rs/thread-store/src/thread_metadata_sync.rs (5 lines):
	- line 263: update.approval_mode = Some(turn_ctx.approval_policy);
	- line 298: update.approval_mode = Some(settings.approval_policy);
	- line 416: use codex_protocol::protocol::AskForApproval;
	- line 646: approval_policy: AskForApproval::Never,
	- line 680: assert_eq!(update.patch.approval_mode, Some(AskForApproval::Never));


codex-rs/app-server-protocol/src/protocol/v1.rs (5 lines):
	- line 13: use codex_protocol::protocol::AskForApproval;
	- line 16: use codex_protocol::protocol::ReviewDecision;
	- line 155: pub decision: ReviewDecision,
	- line 175: pub decision: ReviewDecision,
	- line 211: pub approval_policy: Option<AskForApproval>,


codex-rs/core/src/state/turn.rs (5 lines):
	- line 29: use codex_protocol::protocol::ReviewDecision;
	- line 91: pending_approvals: HashMap<String, oneshot::Sender<ReviewDecision>>,
	- line 119: tx: oneshot::Sender<ReviewDecision>,
	- line 120: ) -> Option<oneshot::Sender<ReviewDecision>> {
	- line 127: ) -> Option<oneshot::Sender<ReviewDecision>> {


codex-rs/core/src/environment_selection.rs (5 lines):
	- line 959: exec_policy: None,
	- line 1143: exec_policy: None,
	- line 1397: exec_policy: None,
	- line 1766: exec_policy: None,
	- line 1832: exec_policy: None,


codex-rs/tui/src/app/permission_shortcuts.rs (5 lines):
	- line 25: if let Some(policy) = selection.approval_policy {
	- line 26: config.permissions.approval_policy.set(policy.to_core())?;
	- line 39: approval_policy: selection.approval_policy,
	- line 51: self.chat_widget.set_approval_policy(AskForApproval::from(config.permissions.approval_policy.value()));
	- line 54: self.runtime_approval_policy_override = selection.approval_policy;


codex-rs/core/src/context/guardian_approved_action.rs (5 lines):
	- line 2: use crate::guardian::AUTO_REVIEW_DENIED_ACTION_APPROVAL_DEVELOPER_PREFIX;
	- line 6: pub(crate) struct GuardianApprovedAction {
	- line 10: impl GuardianApprovedAction {
	- line 18: impl ContextualUserFragment for GuardianApprovedAction {
	- line 20: ContentItemKind("guardian.approved_action".to_string())


codex-rs/ext/guardian-v2/src/async_scorer/review_evidence.rs (5 lines):
	- line 2: use codex_core::context::GuardianReviewEvidenceFragment;
	- line 3: use codex_core::context::GuardianReviewEvidenceRecord;
	- line 21: review: &GuardianReviewEvidenceRecord,
	- line 55: "\nCompleted synchronous Guardian review. This decision applies only to the \
	- line 66: text: GuardianReviewEvidenceFragment::new(body).render(),


codex-rs/tui/src/app.rs (5 lines):
	- line 95: use codex_app_server_protocol::AskForApproval;
	- line 330: proposed_execpolicy_amendment: Option<&codex_app_server_protocol::ExecPolicyAmendment>,
	- line 380: approval_policy: AskForApproval,
	- line 391: approval_policy: AskForApproval::OnRequest,
	- line 551: runtime_approval_policy_override: Option<AskForApproval>,


codex-rs/tui/src/chatwidget/protocol.rs (5 lines):
	- line 164: ServerNotification::GuardianWarning(notification) => {
	- line 193: ServerNotification::ItemGuardianApprovalReviewStarted(notification) => {
	- line 194: self.on_guardian_review_notification(
	- line 203: ServerNotification::ItemGuardianApprovalReviewCompleted(notification) => {
	- line 204: self.on_guardian_review_notification(


codex-rs/ext/guardian-v2/src/async_scorer/authorization.rs (5 lines):
	- line 4: use codex_core::GuardianAuthorizationVersion;
	- line 8: pub(super) local: GuardianAuthorizationVersion,
	- line 9: pub(super) root: Option<GuardianAuthorizationVersion>,
	- line 15: .guardian_root_snapshot()
	- line 19: local: thread.guardian_authorization_version().await,


codex-rs/otel/src/events/session_telemetry.rs (5 lines):
	- line 48: use codex_protocol::protocol::AskForApproval;
	- line 49: use codex_protocol::protocol::ReviewDecision;
	- line 566: approval_policy: AskForApproval,
	- line 585: approval_policy = %approval_policy,
	- line 1079: decision: &ReviewDecision,


codex-rs/utils/approval-presets/src/lib.rs (5 lines):
	- line 6: use codex_protocol::protocol::AskForApproval;
	- line 18: pub approval: AskForApproval,
	- line 34: approval: AskForApproval::OnRequest,
	- line 44: approval: AskForApproval::OnRequest,
	- line 54: approval: AskForApproval::Never,


codex-rs/tui/src/chatwidget/session_flow.rs (5 lines):
	- line 55: .approval_policy
	- line 56: .set(session.approval_policy.to_core())
	- line 58: tracing::warn!(%err, "failed to sync approval_policy from SessionConfigured");
	- line 59: self.config.permissions.approval_policy =
	- line 60: Constrained::allow_only(session.approval_policy.to_core());


codex-rs/tui/src/history_cell/session.rs (4 lines):
	- line 143: session.approval_policy,
	- line 206: AskForApproval::from(config.permissions.approval_policy.value()),
	- line 212: approval_policy: AskForApproval,
	- line 215: approval_policy == AskForApproval::Never


codex-rs/config/src/schema.rs (4 lines):
	- line 23: #[schemars(rename = "AskForApproval")]
	- line 25: pub(crate) enum ConfigAskForApproval {
	- line 80: if feature.id == codex_features::Feature::GuardianV2 {
	- line 84: codex_features::GuardianV2ConfigToml,


codex-rs/ext/guardian-v2/src/async_scorer/trusted_skills.rs (4 lines):
	- line 20: /// Host-verified user-owned skill paths for the current Guardian classification.
	- line 22: pub(crate) struct GuardianTrustedSkillsFragment {
	- line 26: impl ContextualUserFragment for GuardianTrustedSkillsFragment {
	- line 28: ContentItemKind("guardian.trusted_skills".to_owned())


codex-rs/core/src/hook_runtime.rs (4 lines):
	- line 36: use codex_protocol::protocol::AskForApproval;
	- line 1010: match turn_context.approval_policy() {
	- line 1011: AskForApproval::Never => "bypassPermissions",
	- line 1012: AskForApproval::UnlessTrusted | AskForApproval::OnRequest | AskForApproval::Granular(_) => {


codex-rs/core/src/agent/control.rs (4 lines):
	- line 751: async fn inherited_exec_policy_for_source(
	- line 756: ) -> Option<Arc<crate::exec_policy::ExecPolicyManager>> {
	- line 766: if !crate::exec_policy::child_uses_parent_exec_policy(&parent_config, child_config) {
	- line 770: Some(Arc::clone(&parent_thread.session.services.exec_policy))


codex-rs/core/src/session/mcp_runtime.rs (4 lines):
	- line 41: || current.step_settings.approval_policy.value()
	- line 42: != next.step_settings.approval_policy.value()
	- line 152: if crate::guardian::is_basic_session_source(session_source) {
	- line 339: config.approval_policy = desired.config.permissions.approval_policy.clone();


codex-rs/core/src/context/guardian_node_repl_policy.rs (4 lines):
	- line 5: pub(crate) struct GuardianNodeReplPolicy;
	- line 7: impl ContextualUserFragment for GuardianNodeReplPolicy {
	- line 9: ContentItemKind("guardian.node_repl_policy".to_string())
	- line 25: include_str!("../../assets/guardian/node_repl_policy.md").to_string()


codex-rs/tui/src/history_cell/tests.rs (4 lines):
	- line 13: use codex_app_server_protocol::AskForApproval;
	- line 788: approval_policy: AskForApproval::Never,
	- line 2060: AskForApproval::Never,
	- line 2072: AskForApproval::Never,


codex-rs/mcp-server/src/patch_approval.rs (4 lines):
	- line 9: use codex_protocol::protocol::ReviewDecision;
	- line 40: pub decision: ReviewDecision,
	- line 114: decision: ReviewDecision::denied("approval request failed"),
	- line 127: decision: ReviewDecision::denied("approval request failed"),


codex-rs/app-server/src/message_processor.rs (4 lines):
	- line 16: use crate::extensions::guardian_agent_spawner;
	- line 329: guardian_agent_spawner(thread_manager.clone()),
	- line 1345: ClientRequest::ThreadApproveGuardianDeniedAction { params, .. } => {
	- line 1347: .thread_approve_guardian_denied_action(&request_id, params)


codex-rs/config/src/requirements_layers/rules.rs (4 lines):
	- line 5: use crate::RequirementsExecPolicyToml;
	- line 11: target: &mut Option<Sourced<RequirementsExecPolicyToml>>,
	- line 12: incoming: Option<RequirementsExecPolicyToml>,
	- line 23: let RequirementsExecPolicyToml { prefix_rules } = incoming;


codex-rs/rollout-trace/src/protocol_event.rs (4 lines):
	- line 368: | EventMsg::GuardianWarning(_)
	- line 411: | EventMsg::GuardianAssessment(_)
	- line 449: | EventMsg::GuardianWarning(_)
	- line 490: | EventMsg::GuardianAssessment(_)


codex-rs/tui/src/chatwidget/status_surfaces.rs (4 lines):
	- line 15: use codex_app_server_protocol::AskForApproval;
	- line 1171: let approval_policy = AskForApproval::from(config.permissions.approval_policy.value());
	- line 1172: if approval_policy == AskForApproval::OnRequest {
	- line 1179: config.permissions.approval_policy.value().to_string()


codex-rs/ext/guardian-v2/src/async_scorer/action.rs (4 lines):
	- line 11: pub(super) struct GuardianAction {
	- line 21: impl GuardianAction {
	- line 61: let mut omission_key = "_guardian_omitted_fields".to_owned();
	- line 100: "Guardian action identity exceeds the {max_action_tokens}-token limit"


codex-rs/otel/src/metrics/names.rs (4 lines):
	- line 37: pub const GUARDIAN_REVIEW_COUNT_METRIC: &str = "codex.guardian.review";
	- line 38: pub const GUARDIAN_REVIEW_DURATION_METRIC: &str = "codex.guardian.review.duration_ms";
	- line 39: pub const GUARDIAN_REVIEW_TTFT_DURATION_METRIC: &str = "codex.guardian.review.ttft.duration_ms";
	- line 40: pub const GUARDIAN_REVIEW_TOKEN_USAGE_METRIC: &str = "codex.guardian.review.token_usage";


codex-rs/app-server/src/request_processors/persisted_resume_settings.rs (4 lines):
	- line 3: use codex_protocol::protocol::AskForApproval;
	- line 9: pub(super) approval_policy: AskForApproval,
	- line 23: approval_policy: turn_context.approval_policy,
	- line 37: approval_policy: event.thread_settings.approval_policy,


codex-rs/tui/src/chatwidget/permission_shortcuts.rs (4 lines):
	- line 33: AskForApproval::from(self.config.permissions.approval_policy.value());
	- line 43: || !self.config.features.enabled(Feature::GuardianApproval))
	- line 47: let approval = AskForApproval::from(preset.approval);
	- line 90: approval_policy: Some(approval),


codex-rs/app-server/src/outgoing_message.rs (4 lines):
	- line 755: use codex_app_server_protocol::GuardianWarningNotification;
	- line 925: fn verify_guardian_warning_notification_serialization() {
	- line 926: let notification = ServerNotification::GuardianWarning(GuardianWarningNotification {
	- line 933: "method": "guardianWarning",


codex-rs/analytics/src/facts.rs (4 lines):
	- line 3: use crate::events::GuardianReviewEventParams;
	- line 22: use codex_protocol::protocol::AskForApproval;
	- line 200: pub approval_policy: AskForApproval,
	- line 563: GuardianReview(Box<GuardianReviewEventParams>),


codex-rs/core/src/state/service.rs (4 lines):
	- line 13: use crate::exec_policy::ExecPolicyManager;
	- line 14: use crate::guardian::GuardianRejectionCircuitBreaker;
	- line 62: pub(crate) exec_policy: Arc<ExecPolicyManager>,
	- line 69: pub(crate) guardian_rejection_circuit_breaker: Mutex<GuardianRejectionCircuitBreaker>,


codex-rs/execpolicy/src/execpolicycheck.rs (4 lines):
	- line 17: pub struct ExecPolicyCheckCommand {
	- line 41: impl ExecPolicyCheckCommand {
	- line 61: let output = ExecPolicyCheckOutput {
	- line 90: struct ExecPolicyCheckOutput<'a> {


codex-rs/core/src/exec_policy/model_policy.rs (4 lines):
	- line 1: use super::ExecPolicyManager;
	- line 5: use codex_execpolicy::RequirementsExecPolicy;
	- line 14: impl ExecPolicyManager {
	- line 17: environment_policy: Option<&RequirementsExecPolicy>,


codex-rs/utils/cli/src/approval_mode_cli_arg.rs (4 lines):
	- line 5: use codex_protocol::protocol::AskForApproval;
	- line 18: impl From<ApprovalModeCliArg> for AskForApproval {
	- line 21: ApprovalModeCliArg::OnRequest => AskForApproval::OnRequest,
	- line 22: ApprovalModeCliArg::Never => AskForApproval::Never,


codex-rs/codex-mcp/src/mcp/mod.rs (4 lines):
	- line 42: use codex_protocol::protocol::AskForApproval;
	- line 90: approval_policy: AskForApproval,
	- line 98: if approval_policy != AskForApproval::Never {
	- line 145: pub approval_policy: Constrained<AskForApproval>,


codex-rs/app-server/src/extensions.rs (4 lines):
	- line 56: guardian_agent_spawner: S,
	- line 100: codex_guardian_v2::install(
	- line 102: guardian_agent_spawner,
	- line 309: pub(crate) fn guardian_agent_spawner(


codex-rs/core/src/mcp_skill_dependencies.rs (3 lines):
	- line 11: use codex_protocol::protocol::AskForApproval;
	- line 263: turn_context.approval_policy(),
	- line 270: if turn_context.approval_policy() == AskForApproval::Never {


codex-rs/config/src/profile_toml.rs (3 lines):
	- line 18: use codex_protocol::protocol::AskForApproval;
	- line 32: #[schemars(with = "Option<crate::schema::ConfigAskForApproval>")]
	- line 33: pub approval_policy: Option<AskForApproval>,


codex-rs/app-server-protocol/src/protocol/v2/notification.rs (3 lines):
	- line 41: pub struct GuardianWarningNotification {
	- line 42: /// Thread target for the guardian warning.
	- line 44: /// Concise guardian warning message for the user.


codex-rs/protocol/src/environment.rs (3 lines):
	- line 6: use codex_execpolicy::RequirementsExecPolicy;
	- line 42: pub exec_policy: Option<RequirementsExecPolicy>,
	- line 65: .field("exec_policy", &self.exec_policy)


codex-rs/state/src/model/thread_metadata.rs (3 lines):
	- line 7: use codex_protocol::protocol::AskForApproval;
	- line 224: pub approval_mode: AskForApproval,
	- line 259: approval_mode: AskForApproval::OnRequest,


codex-rs/thread-manager-sample/src/main.rs (3 lines):
	- line 15: use codex_core_api::AskForApproval;
	- line 201: Constrained::allow_any(AskForApproval::Never),
	- line 213: guardian_policy_config: None,


codex-rs/app-server/src/request_processors.rs (3 lines):
	- line 41: use codex_app_server_protocol::AskForApproval;
	- line 193: use codex_app_server_protocol::ThreadApproveGuardianDeniedActionParams;
	- line 194: use codex_app_server_protocol::ThreadApproveGuardianDeniedActionResponse;


codex-rs/thread-store/src/local/read_thread.rs (3 lines):
	- line 4: use codex_protocol::protocol::AskForApproval;
	- line 399: approval_mode: parse_or_default(&metadata.approval_mode, AskForApproval::OnRequest),
	- line 494: approval_mode: AskForApproval::OnRequest,


codex-rs/tui/src/app/working_directory.rs (3 lines):
	- line 85: let actual = config.permissions.approval_policy.value();
	- line 86: let approval = self.runtime_approval_policy_override;
	- line 167: || session.approval_policy.to_core() != config.permissions.approval_policy.value()


codex-rs/core/src/context/guardian_followup_review_reminder.rs (3 lines):
	- line 5: pub(crate) struct GuardianFollowupReviewReminder;
	- line 7: impl ContextualUserFragment for GuardianFollowupReviewReminder {
	- line 9: ContentItemKind("guardian.followup_review_reminder".to_string())


codex-rs/tui/src/app_event.rs (3 lines):
	- line 58: use codex_app_server_protocol::AskForApproval;
	- line 1109: UpdateAskForApprovalPolicy(AskForApproval),
	- line 1384: pub approval_policy: Option<AskForApproval>,


sdk/python/scripts/update_sdk_artifacts.py (3 lines):
	- line 993: return f"{indent}approval_policy, approvals_reviewer = {helper_name}(approval_mode)"
	- line 999: f"{indent}approval_policy=approval_policy,",
	- line 1285: approval_fields = {"approval_policy", "approvals_reviewer"}


codex-rs/tui/src/cli.rs (3 lines):
	- line 66: pub approval_policy: Option<ApprovalModeCliArg>,
	- line 141: arg.conflicts_with("approval_policy")
	- line 143: .mut_arg("auto_review", |arg| arg.conflicts_with("approval_policy"))


codex-rs/app-server-protocol/src/protocol/v2/thread_data.rs (3 lines):
	- line 107: GuardianReview,
	- line 142: CoreThreadSource::GuardianReview => ThreadSource::GuardianReview,
	- line 154: ThreadSource::GuardianReview => CoreThreadSource::GuardianReview,


codex-rs/thread-store/src/types.rs (3 lines):
	- line 16: use codex_protocol::protocol::AskForApproval;
	- line 630: pub approval_mode: AskForApproval,
	- line 760: pub approval_mode: Option<AskForApproval>,


codex-rs/app-server-protocol/src/protocol/v2/config.rs (3 lines):
	- line 2: use super::AskForApproval;
	- line 265: pub approval_policy: Option<AskForApproval>,
	- line 394: pub allowed_approval_policies: Option<Vec<AskForApproval>>,


codex-rs/core/src/tasks/mod.rs (3 lines):
	- line 305: .guardian_rejection_circuit_breaker
	- line 843: .guardian_rejection_circuit_breaker
	- line 998: .guardian_rejection_circuit_breaker


codex-rs/models-manager/src/model_info.rs (3 lines):
	- line 65: guardian_v2: None,
	- line 212: guardian_v2: None,
	- line 226: guardian_v2: None,


codex-rs/guardian-context/src/entry.rs (3 lines):
	- line 1: //! Structured transcript evidence shared by synchronous and asynchronous Guardian.
	- line 29: /// Returns the role label currently used in Guardian transcript prompts.
	- line 43: /// Structured text evidence shared by sync Guardian and async scoring.


codex-rs/mcp-server/src/exec_approval.rs (3 lines):
	- line 8: use codex_protocol::protocol::ReviewDecision;
	- line 47: pub decision: ReviewDecision,
	- line 131: decision: ReviewDecision::denied("approval request failed"),


codex-rs/core/src/tools/handlers/multi_agents_common.rs (3 lines):
	- line 241: .approval_policy
	- line 242: .set(turn.approval_policy())
	- line 244: FunctionCallError::RespondToModel(format!("approval_policy is invalid: {err}"))


codex-rs/app-server/src/config_manager_service.rs (3 lines):
	- line 34: use codex_protocol::protocol::AskForApproval;
	- line 752: if config.approval_policy == Some(AskForApproval::UnlessTrusted) {
	- line 754: "approval_policy = \"untrusted\" is no longer supported; remove this setting"


codex-rs/app-server/src/notification_media.rs (3 lines):
	- line 81: | ServerNotification::ItemGuardianApprovalReviewStarted(_)
	- line 82: | ServerNotification::ItemGuardianApprovalReviewCompleted(_)
	- line 117: | ServerNotification::GuardianWarning(_)


codex-rs/tui/src/approval_events.rs (3 lines):
	- line 15: use codex_app_server_protocol::ExecPolicyAmendment;
	- line 38: pub(crate) proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
	- line 70: proposed_execpolicy_amendment: Option<&ExecPolicyAmendment>,


codex-rs/protocol/src/models.rs (3 lines):
	- line 3252: let mut exec_policy = Policy::empty();
	- line 3254: exec_policy
	- line 3263: format_allow_prefixes(exec_policy.get_allowed_prefixes()).expect("formatted prefixes");


codex-rs/app-server-protocol/src/protocol/v2/turn.rs (2 lines):
	- line 2: use super::AskForApproval;
	- line 196: pub approval_policy: Option<AskForApproval>,


codex-rs/config/src/requirements_layers/layer.rs (2 lines):
	- line 4: use crate::RequirementsExecPolicyToml;
	- line 131: pub(super) rules: Option<RequirementsExecPolicyToml>,


codex-rs/ext/guardian-v2/src/async_scorer/truncation.rs (2 lines):
	- line 6: "codex.guardian_v2.classification.truncation";
	- line 8: "codex.guardian_v2.classification.truncation.bytes";


codex-rs/rollout/src/policy.rs (2 lines):
	- line 140: | EventMsg::GuardianAssessment(_)
	- line 153: | EventMsg::GuardianWarning(_)


codex-rs/mcp-server/src/codex_tool_runner.rs (2 lines):
	- line 252: | EventMsg::GuardianWarning(_)
	- line 258: EventMsg::GuardianAssessment(_) => {


codex-rs/config/src/loader/tests.rs (2 lines):
	- line 565: approval_policy = "never"
	- line 905: "approval_policy = \"never\"\nsandbox_mode = \"workspace-write\"\nmodel_instructions_file = \"./managed.md\"",


codex-rs/app-server/src/thread_state.rs (2 lines):
	- line 249: use codex_app_server_protocol::AskForApproval;
	- line 276: approval_policy: AskForApproval::OnRequest,


codex-rs/network-proxy/src/http_proxy.rs (2 lines):
	- line 232: exec_policy_hint: None,
	- line 732: exec_policy_hint: None,


codex-rs/execpolicy/src/main.rs (2 lines):
	- line 3: use codex_execpolicy::ExecPolicyCheckCommand;
	- line 10: Check(ExecPolicyCheckCommand),


codex-rs/guardian-context/src/truncation.rs (2 lines):
	- line 1: //! Guardian's shared UTF-8-safe, prefix/suffix text truncation primitive.
	- line 8: /// Truncates text using Guardian's approximate token budget and omission marker.


codex-rs/network-proxy/src/socks5.rs (2 lines):
	- line 313: exec_policy_hint: None,
	- line 741: exec_policy_hint: None,


codex-rs/ext/extension-api/src/registry.rs (2 lines):
	- line 3: use codex_protocol::protocol::ReviewDecision;
	- line 226: ) -> Option<ReviewDecision> {


codex-rs/tui/src/session_state.rs (2 lines):
	- line 8: use codex_app_server_protocol::AskForApproval;
	- line 38: pub(crate) approval_policy: AskForApproval,


codex-rs/core/src/agent/role.rs (2 lines):
	- line 258: .with_user_and_project_exec_policy_rules_ignored(
	- line 261: .ignore_user_and_project_exec_policy_rules(),


codex-rs/ext/extension-api/src/contributors.rs (2 lines):
	- line 7: use codex_protocol::protocol::ReviewDecision;
	- line 361: ) -> ExtensionFuture<'a, Option<ReviewDecision>> {


codex-rs/app-server/src/request_processors/thread_lifecycle.rs (2 lines):
	- line 782: approval_policy,
	- line 804: approval_policy: approval_policy.into(),


codex-rs/rollout/src/metadata.rs (2 lines):
	- line 13: use codex_protocol::protocol::AskForApproval;
	- line 58: builder.approval_mode = AskForApproval::OnRequest;


sdk/python/src/openai_codex/types.py (2 lines):
	- line 9: AskForApproval,
	- line 47: "AskForApproval",


codex-rs/execpolicy/src/lib.rs (2 lines):
	- line 20: pub use execpolicycheck::ExecPolicyCheckCommand;
	- line 25: pub use policy::RequirementsExecPolicy;


codex-rs/thread-store/src/in_memory.rs (2 lines):
	- line 15: use codex_protocol::protocol::AskForApproval;
	- line 1099: .unwrap_or(AskForApproval::Never),


codex-rs/core/src/context/world_state/compact_permissions.rs (2 lines):
	- line 17: pub(crate) fn new(exec_policy: &Policy) -> Self {
	- line 19: prefixes: exec_policy.get_allowed_prefixes().into_iter().collect(),


codex-rs/core/src/session/environment.rs (2 lines):
	- line 55: .exec_policy
	- line 80: .exec_policy


codex-rs/app-server/src/mcp_refresh.rs (2 lines):
	- line 68: use crate::extensions::guardian_agent_spawner;
	- line 330: guardian_agent_spawner(thread_manager.clone()),


codex-rs/memories/write/src/phase2.rs (2 lines):
	- line 25: use codex_protocol::protocol::AskForApproval;
	- line 330: agent_config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);


codex-rs/thread-store/src/local/helpers.rs (2 lines):
	- line 16: use codex_protocol::protocol::AskForApproval;
	- line 186: approval_mode: AskForApproval::OnRequest,


codex-rs/core/src/session/thread_settings.rs (2 lines):
	- line 45: approval_policy,
	- line 66: approval_policy,


codex-rs/tui/src/pager_overlay.rs (2 lines):
	- line 1021: use crate::history_cell::ReviewDecision;
	- line 1411: ReviewDecision::Approved,


codex-rs/tui/src/app/thread_events.rs (2 lines):
	- line 380: use codex_app_server_protocol::AskForApproval;
	- line 412: approval_policy: AskForApproval::Never,


codex-rs/core/src/session/review.rs (2 lines):
	- line 96: let auto_review_enabled = crate::guardian::routes_approval_policy_to_guardian(
	- line 97: per_turn_config.permissions.approval_policy.value(),


codex-rs/app-server-protocol/schema/typescript/index.ts (2 lines):
	- line 21: export type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
	- line 76: export type { ReviewDecision } from "./ReviewDecision";


codex-rs/tui/src/history_cell/mod.rs (2 lines):
	- line 53: use codex_app_server_protocol::AskForApproval;
	- line 66: use codex_protocol::approvals::ExecPolicyAmendment;


codex-rs/core/src/context_manager/history.rs (2 lines):
	- line 20: use codex_guardian_context::SectionHistory;
	- line 21: use codex_guardian_context::TranscriptHistory;


codex-rs/core/src/tasks/review.rs (2 lines):
	- line 13: use codex_protocol::protocol::AskForApproval;
	- line 121: sub_agent_config.permissions.approval_policy = Constrained::allow_only(AskForApproval::Never);


sdk/typescript/src/exec.ts (2 lines):
	- line 41: // --config approval_policy
	- line 163: commandArgs.push("--config", `approval_policy="${args.approvalPolicy}"`);


codex-rs/tui/src/temporary_structured_request.rs (2 lines):
	- line 5: use codex_app_server_protocol::AskForApproval;
	- line 136: approval_policy: Some(AskForApproval::Never),


codex-rs/tui/src/chatwidget/windows_sandbox_prompts.rs (1 line):
	- line 82: Some(AskForApproval::from(p.approval)),


codex-rs/guardian-context/src/transcript.rs (1 line):
	- line 3: //! Both Guardian consumers receive the same role and tool-source attribution,


codex-rs/tui/src/chatwidget/slash_dispatch.rs (1 line):
	- line 370: .approval_policy


codex-rs/config/src/constraint.rs (1 line):
	- line 26: ExecPolicyParse {


codex-rs/ext/guardian-v2/src/async_scorer/mod.rs (1 line):
	- line 14: pub(crate) use config::GuardianV2Config;


codex-rs/exec-server/src/client_recovery.rs (1 line):
	- line 710: exec_policy_hint: None,


codex-rs/ext/guardian-v2/src/async_scorer/transcript.rs (1 line):
	- line 5: pub(crate) use codex_features::GuardianV2TranscriptSource as TranscriptSource;


codex-rs/core/src/config/requirements.rs (1 line):
	- line 45: config.features.get_or_insert_default().guardianv2 = Some(FeatureToml::Enabled(false));


codex-rs/cli/src/doctor/sandbox.rs (1 line):
	- line 48: config.permissions.approval_policy.value()


codex-rs/core-api/src/lib.rs (1 line):
	- line 125: pub use codex_protocol::protocol::AskForApproval;


scripts/codex_package/smoke_tests/fixtures.py (1 line):
	- line 82: """approval_policy = "never"


codex-rs/network-proxy/src/proxy.rs (1 line):
	- line 1647: exec_policy_hint: None,


codex-rs/utils/cli/src/shared_options.rs (1 line):
	- line 83: .push(r#"approval_policy="on-request""#.to_string());


codex-rs/cli/src/doctor/thread_inventory.rs (1 line):
	- line 677: SessionSource::Internal(InternalSessionSource::Guardian) => "internal:guardian",


codex-rs/app-server/src/request_processors/config_processor.rs (1 line):
	- line 404: .map(codex_app_server_protocol::AskForApproval::from)


codex-rs/hooks/src/events/permission_request.rs (1 line):
	- line 3: //! This event runs in the approval path, before guardian or user approval UI is


codex-rs/tui/src/app/startup.rs (1 line):
	- line 491: runtime_approval_policy_override: None,


codex-rs/tui/src/chatwidget/rate_limits.rs (1 line):
	- line 407: /*approval_policy*/ None,


codex-rs/tui/src/chatwidget/input_submission.rs (1 line):
	- line 369: AskForApproval::from(self.config.permissions.approval_policy.value()),


codex-rs/tui/src/app/replay_filter.rs (1 line):
	- line 33: | ServerNotification::GuardianWarning(_)


codex-rs/core/src/config/managed_features.rs (1 line):
	- line 220: pinned_features.insert(Feature::GuardianApproval, enabled);


codex-rs/tui/src/dynamic_tools.rs (1 line):
	- line 612: thread_start_params.approval_policy = Some(source.approval_policy);


codex-rs/app-server/src/request_processors/thread_summary.rs (1 line):
	- line 180: approval_policy: config_snapshot.approval_policy.into(),


codex-rs/core/src/turn_metadata.rs (1 line):
	- line 332: | ThreadSource::GuardianReview


codex-rs/tui/src/chatwidget/settings_popups.rs (1 line):
	- line 50: /*approval_policy*/ None,


codex-rs/tui/src/chatwidget/service_tiers.rs (1 line):
	- line 111: /*approval_policy*/ None,


codex-rs/core/src/apply_patch.rs (1 line):
	- line 30: step_context.settings.approval_policy(),


codex-rs/rollout-trace/src/thread.rs (1 line):
	- line 62: pub approval_policy: String,


codex-rs/execpolicy/src/decision.rs (1 line):
	- line 12: /// Request explicit user approval; rejected outright when running with `approval_policy="never"`.


codex-rs/thread-store/src/local/rollout_migration/line_parser.rs (1 line):
	- line 50: Some("guardian_assessment" | "thread_name_updated" | "undo_completed")


codex-rs/history/src/tests.rs (1 line):
	- line 352: "approval_policy": "never",


codex-rs/exec/src/event_processor_with_human_output.rs (1 line):
	- line 441: config.permissions.approval_policy.value().to_string(),


codex-rs/app-server/src/in_process.rs (1 line):
	- line 368: let (path, range) = crate::exec_policy_warning_location(&err);


codex-rs/windows-sandbox-rs/src/identity.rs (1 line):
	- line 376: fn guardian_preserve_mode_does_not_churn_marker_with_empty_proxy_ports() {
