mirror of
https://github.com/openai/codex.git
synced 2026-11-02 16:20:35 +00:00
Rename approvals reviewer variant to auto-review (#19056)
## Why `approvals_reviewer` now uses `auto_review` as the canonical config/API value after #18504, but the Rust enum variant and nearby helper/test names still used `GuardianSubagent` / guardian approval wording. That made follow-up code and reviews confusing even though the external value had already moved to Auto-review. ## What changed - Renamed `ApprovalsReviewer::GuardianSubagent` to `ApprovalsReviewer::AutoReview`. - Updated protocol, app-server, config, core, TUI, exec, and analytics test callsites. - Renamed nearby helper/test names from guardian approval wording to Auto-review wording where they refer to the approvals reviewer mode. - Preserved wire compatibility: - `auto_review` remains the canonical serialized value. - `guardian_subagent` remains accepted as a legacy alias. This intentionally does not rename the `[features].guardian_approval` key, `Feature::GuardianApproval`, `core/src/guardian`, analytics event names, or app-server Guardian review event types. ## Verification - `cargo test -p codex-protocol approvals_reviewer_serializes_auto_review_and_accepts_legacy_guardian_subagent` - `cargo test -p codex-app-server-protocol approvals_reviewer_serializes_auto_review_and_accepts_legacy_guardian_subagent` - `cargo test -p codex-config approvals_reviewer` - `cargo test -p codex-tui update_feature_flags` - `cargo test -p codex-core permissions_instructions` - `cargo test -p codex-tui permissions_selection`
This commit is contained in:
1 parent
eed0e07825
commit
83ec1eb5d6
22 files changed
+114
-145
No files matched your search
@@ -324,7 +324,7 @@ fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
|
|||||||
reasoning_summary: None,
|
reasoning_summary: None,
|
||||||
service_tier: None,
|
service_tier: None,
|
||||||
approval_policy: AskForApproval::OnRequest,
|
approval_policy: AskForApproval::OnRequest,
|
||||||
approvals_reviewer: ApprovalsReviewer::GuardianSubagent,
|
approvals_reviewer: ApprovalsReviewer::AutoReview,
|
||||||
sandbox_network_access: true,
|
sandbox_network_access: true,
|
||||||
collaboration_mode: ModeKind::Plan,
|
collaboration_mode: ModeKind::Plan,
|
||||||
personality: None,
|
personality: None,
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ pub enum ApprovalsReviewer {
|
|||||||
#[serde(rename = "user")]
|
#[serde(rename = "user")]
|
||||||
User,
|
User,
|
||||||
#[serde(rename = "auto_review", alias = "guardian_subagent")]
|
#[serde(rename = "auto_review", alias = "guardian_subagent")]
|
||||||
GuardianSubagent,
|
AutoReview,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonSchema for ApprovalsReviewer {
|
impl JsonSchema for ApprovalsReviewer {
|
||||||
@@ -361,7 +361,7 @@ impl ApprovalsReviewer {
|
|||||||
pub fn to_core(self) -> CoreApprovalsReviewer {
|
pub fn to_core(self) -> CoreApprovalsReviewer {
|
||||||
match self {
|
match self {
|
||||||
ApprovalsReviewer::User => CoreApprovalsReviewer::User,
|
ApprovalsReviewer::User => CoreApprovalsReviewer::User,
|
||||||
ApprovalsReviewer::GuardianSubagent => CoreApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview => CoreApprovalsReviewer::AutoReview,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ impl From<CoreApprovalsReviewer> for ApprovalsReviewer {
|
|||||||
fn from(value: CoreApprovalsReviewer) -> Self {
|
fn from(value: CoreApprovalsReviewer) -> Self {
|
||||||
match value {
|
match value {
|
||||||
CoreApprovalsReviewer::User => ApprovalsReviewer::User,
|
CoreApprovalsReviewer::User => ApprovalsReviewer::User,
|
||||||
CoreApprovalsReviewer::GuardianSubagent => ApprovalsReviewer::GuardianSubagent,
|
CoreApprovalsReviewer::AutoReview => ApprovalsReviewer::AutoReview,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7393,8 +7393,7 @@ mod tests {
|
|||||||
"\"user\""
|
"\"user\""
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serde_json::to_string(&ApprovalsReviewer::GuardianSubagent)
|
serde_json::to_string(&ApprovalsReviewer::AutoReview).expect("serialize reviewer"),
|
||||||
.expect("serialize reviewer"),
|
|
||||||
"\"auto_review\""
|
"\"auto_review\""
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -7405,7 +7404,7 @@ mod tests {
|
|||||||
let expected = if value == "user" {
|
let expected = if value == "user" {
|
||||||
ApprovalsReviewer::User
|
ApprovalsReviewer::User
|
||||||
} else {
|
} else {
|
||||||
ApprovalsReviewer::GuardianSubagent
|
ApprovalsReviewer::AutoReview
|
||||||
};
|
};
|
||||||
assert_eq!(expected, reviewer);
|
assert_eq!(expected, reviewer);
|
||||||
}
|
}
|
||||||
@@ -8679,7 +8678,7 @@ mod tests {
|
|||||||
model_auto_compact_token_limit: None,
|
model_auto_compact_token_limit: None,
|
||||||
model_provider: None,
|
model_provider: None,
|
||||||
approval_policy: None,
|
approval_policy: None,
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
sandbox_mode: None,
|
sandbox_mode: None,
|
||||||
sandbox_workspace_write: None,
|
sandbox_workspace_write: None,
|
||||||
forced_chatgpt_workspace_id: None,
|
forced_chatgpt_workspace_id: None,
|
||||||
@@ -8781,7 +8780,7 @@ mod tests {
|
|||||||
model: None,
|
model: None,
|
||||||
model_provider: None,
|
model_provider: None,
|
||||||
approval_policy: None,
|
approval_policy: None,
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
service_tier: None,
|
service_tier: None,
|
||||||
model_reasoning_effort: None,
|
model_reasoning_effort: None,
|
||||||
model_reasoning_summary: None,
|
model_reasoning_summary: None,
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ mod tests {
|
|||||||
]),
|
]),
|
||||||
allowed_approvals_reviewers: Some(vec![
|
allowed_approvals_reviewers: Some(vec![
|
||||||
CoreApprovalsReviewer::User,
|
CoreApprovalsReviewer::User,
|
||||||
CoreApprovalsReviewer::GuardianSubagent,
|
CoreApprovalsReviewer::AutoReview,
|
||||||
]),
|
]),
|
||||||
allowed_sandbox_modes: Some(vec![
|
allowed_sandbox_modes: Some(vec![
|
||||||
CoreSandboxModeRequirement::ReadOnly,
|
CoreSandboxModeRequirement::ReadOnly,
|
||||||
@@ -524,7 +524,7 @@ mod tests {
|
|||||||
mapped.allowed_approvals_reviewers,
|
mapped.allowed_approvals_reviewers,
|
||||||
Some(vec![
|
Some(vec![
|
||||||
codex_app_server_protocol::ApprovalsReviewer::User,
|
codex_app_server_protocol::ApprovalsReviewer::User,
|
||||||
codex_app_server_protocol::ApprovalsReviewer::GuardianSubagent,
|
codex_app_server_protocol::ApprovalsReviewer::AutoReview,
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -1185,7 +1185,7 @@ mod tests {
|
|||||||
|
|
||||||
let allowed_approval_policies = vec![AskForApproval::UnlessTrusted, AskForApproval::Never];
|
let allowed_approval_policies = vec![AskForApproval::UnlessTrusted, AskForApproval::Never];
|
||||||
let allowed_approvals_reviewers =
|
let allowed_approvals_reviewers =
|
||||||
vec![ApprovalsReviewer::GuardianSubagent, ApprovalsReviewer::User];
|
vec![ApprovalsReviewer::AutoReview, ApprovalsReviewer::User];
|
||||||
let allowed_sandbox_modes = vec![
|
let allowed_sandbox_modes = vec![
|
||||||
SandboxModeRequirement::WorkspaceWrite,
|
SandboxModeRequirement::WorkspaceWrite,
|
||||||
SandboxModeRequirement::DangerFullAccess,
|
SandboxModeRequirement::DangerFullAccess,
|
||||||
@@ -1690,7 +1690,7 @@ allowed_approvals_reviewers = ["user"]
|
|||||||
Err(ConstraintError::InvalidValue {
|
Err(ConstraintError::InvalidValue {
|
||||||
field_name: "approvals_reviewer",
|
field_name: "approvals_reviewer",
|
||||||
candidate: "User".into(),
|
candidate: "User".into(),
|
||||||
allowed: "[GuardianSubagent]".into(),
|
allowed: "[AutoReview]".into(),
|
||||||
requirement_source: source_location,
|
requirement_source: source_location,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -1837,13 +1837,13 @@ allowed_approvals_reviewers = ["user"]
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
requirements.approvals_reviewer.value(),
|
requirements.approvals_reviewer.value(),
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview,
|
||||||
"currently, there is no way to specify the default value for approvals reviewer in the toml, so it picks the first allowed value"
|
"currently, there is no way to specify the default value for approvals reviewer in the toml, so it picks the first allowed value"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
requirements
|
requirements
|
||||||
.approvals_reviewer
|
.approvals_reviewer
|
||||||
.can_set(&ApprovalsReviewer::GuardianSubagent)
|
.can_set(&ApprovalsReviewer::AutoReview)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
@@ -1866,7 +1866,7 @@ allowed_approvals_reviewers = ["user"]
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
requirements.approvals_reviewer.value(),
|
requirements.approvals_reviewer.value(),
|
||||||
ApprovalsReviewer::GuardianSubagent
|
ApprovalsReviewer::AutoReview
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ async fn handle_exec_approval_uses_call_id_for_guardian_review_and_approval_id_f
|
|||||||
crate::session::tests::make_session_and_context_with_rx().await;
|
crate::session::tests::make_session_and_context_with_rx().await;
|
||||||
let mut parent_ctx = Arc::try_unwrap(parent_ctx).expect("single turn context ref");
|
let mut parent_ctx = Arc::try_unwrap(parent_ctx).expect("single turn context ref");
|
||||||
let mut config = (*parent_ctx.config).clone();
|
let mut config = (*parent_ctx.config).clone();
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
parent_ctx.config = Arc::new(config);
|
parent_ctx.config = Arc::new(config);
|
||||||
parent_ctx
|
parent_ctx
|
||||||
.approval_policy
|
.approval_policy
|
||||||
@@ -363,7 +363,7 @@ async fn delegated_mcp_guardian_abort_returns_synthetic_decline_answer() {
|
|||||||
crate::session::tests::make_session_and_context_with_rx().await;
|
crate::session::tests::make_session_and_context_with_rx().await;
|
||||||
let mut parent_ctx = Arc::try_unwrap(parent_ctx).expect("single turn context ref");
|
let mut parent_ctx = Arc::try_unwrap(parent_ctx).expect("single turn context ref");
|
||||||
let mut config = (*parent_ctx.config).clone();
|
let mut config = (*parent_ctx.config).clone();
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
parent_ctx.config = Arc::new(config);
|
parent_ctx.config = Arc::new(config);
|
||||||
parent_ctx
|
parent_ctx
|
||||||
.approval_policy
|
.approval_policy
|
||||||
|
|||||||
@@ -6741,10 +6741,7 @@ approvals_reviewer = "guardian_subagent"
|
|||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6757,17 +6754,14 @@ async fn requirements_disallowing_default_approvals_reviewer_falls_back_to_requi
|
|||||||
.codex_home(codex_home.path().to_path_buf())
|
.codex_home(codex_home.path().to_path_buf())
|
||||||
.cloud_requirements(CloudRequirementsLoader::new(async {
|
.cloud_requirements(CloudRequirementsLoader::new(async {
|
||||||
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
||||||
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::GuardianSubagent]),
|
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::AutoReview]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6786,17 +6780,14 @@ async fn root_approvals_reviewer_falls_back_when_disallowed_by_requirements() ->
|
|||||||
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
||||||
.cloud_requirements(CloudRequirementsLoader::new(async {
|
.cloud_requirements(CloudRequirementsLoader::new(async {
|
||||||
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
||||||
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::GuardianSubagent]),
|
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::AutoReview]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
assert!(
|
assert!(
|
||||||
config.startup_warnings.iter().any(|warning| {
|
config.startup_warnings.iter().any(|warning| {
|
||||||
warning
|
warning
|
||||||
@@ -6826,17 +6817,14 @@ approvals_reviewer = "user"
|
|||||||
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
.fallback_cwd(Some(codex_home.path().to_path_buf()))
|
||||||
.cloud_requirements(CloudRequirementsLoader::new(async {
|
.cloud_requirements(CloudRequirementsLoader::new(async {
|
||||||
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
||||||
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::GuardianSubagent]),
|
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::AutoReview]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6857,7 +6845,7 @@ async fn approvals_reviewer_preserves_valid_user_choice_when_allowed_by_requirem
|
|||||||
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
Ok(Some(crate::config_loader::ConfigRequirementsToml {
|
||||||
allowed_approvals_reviewers: Some(vec![
|
allowed_approvals_reviewers: Some(vec![
|
||||||
ApprovalsReviewer::User,
|
ApprovalsReviewer::User,
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview,
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
@@ -6865,10 +6853,7 @@ async fn approvals_reviewer_preserves_valid_user_choice_when_allowed_by_requirem
|
|||||||
.build()
|
.build()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
assert!(
|
assert!(
|
||||||
config
|
config
|
||||||
.startup_warnings
|
.startup_warnings
|
||||||
|
|||||||
@@ -1048,7 +1048,7 @@ impl From<LegacyManagedConfigToml> for ConfigRequirementsToml {
|
|||||||
}
|
}
|
||||||
if let Some(approvals_reviewer) = approvals_reviewer {
|
if let Some(approvals_reviewer) = approvals_reviewer {
|
||||||
let mut allowed_reviewers = vec![approvals_reviewer];
|
let mut allowed_reviewers = vec![approvals_reviewer];
|
||||||
if approvals_reviewer == ApprovalsReviewer::GuardianSubagent {
|
if approvals_reviewer == ApprovalsReviewer::AutoReview {
|
||||||
allowed_reviewers.push(ApprovalsReviewer::User);
|
allowed_reviewers.push(ApprovalsReviewer::User);
|
||||||
}
|
}
|
||||||
config_requirements_toml.allowed_approvals_reviewers = Some(allowed_reviewers);
|
config_requirements_toml.allowed_approvals_reviewers = Some(allowed_reviewers);
|
||||||
@@ -1135,7 +1135,7 @@ foo = "xyzzy"
|
|||||||
fn legacy_managed_config_backfill_allows_user_when_guardian_is_required() {
|
fn legacy_managed_config_backfill_allows_user_when_guardian_is_required() {
|
||||||
let legacy = LegacyManagedConfigToml {
|
let legacy = LegacyManagedConfigToml {
|
||||||
approval_policy: None,
|
approval_policy: None,
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
sandbox_mode: None,
|
sandbox_mode: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1143,10 +1143,7 @@ foo = "xyzzy"
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
requirements.allowed_approvals_reviewers,
|
requirements.allowed_approvals_reviewers,
|
||||||
Some(vec![
|
Some(vec![ApprovalsReviewer::AutoReview, ApprovalsReviewer::User,])
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
|
||||||
ApprovalsReviewer::User,
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ fn approval_text(
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
if approvals_reviewer == ApprovalsReviewer::GuardianSubagent
|
if approvals_reviewer == ApprovalsReviewer::AutoReview
|
||||||
&& approval_policy != AskForApproval::Never
|
&& approval_policy != AskForApproval::Never
|
||||||
{
|
{
|
||||||
format!("{text}\n\n{AUTO_REVIEW_APPROVAL_SUFFIX}")
|
format!("{text}\n\n{AUTO_REVIEW_APPROVAL_SUFFIX}")
|
||||||
|
|||||||
@@ -197,10 +197,10 @@ fn on_request_includes_tool_guidance_alongside_inline_permission_guidance_when_b
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn guardian_subagent_approvals_append_guardian_specific_guidance() {
|
fn auto_review_approvals_append_auto_review_specific_guidance() {
|
||||||
let text = approval_text(
|
let text = approval_text(
|
||||||
AskForApproval::OnRequest,
|
AskForApproval::OnRequest,
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview,
|
||||||
&Policy::empty(),
|
&Policy::empty(),
|
||||||
/*exec_permission_approvals_enabled*/ false,
|
/*exec_permission_approvals_enabled*/ false,
|
||||||
/*request_permissions_tool_enabled*/ false,
|
/*request_permissions_tool_enabled*/ false,
|
||||||
@@ -212,10 +212,10 @@ fn guardian_subagent_approvals_append_guardian_specific_guidance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn guardian_subagent_approvals_omit_guardian_specific_guidance_when_approval_is_never() {
|
fn auto_review_approvals_omit_auto_review_specific_guidance_when_approval_is_never() {
|
||||||
let text = approval_text(
|
let text = approval_text(
|
||||||
AskForApproval::Never,
|
AskForApproval::Never,
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview,
|
||||||
&Policy::empty(),
|
&Policy::empty(),
|
||||||
/*exec_permission_approvals_enabled*/ false,
|
/*exec_permission_approvals_enabled*/ false,
|
||||||
/*request_permissions_tool_enabled*/ false,
|
/*request_permissions_tool_enabled*/ false,
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ pub(crate) fn routes_approval_to_guardian(turn: &TurnContext) -> bool {
|
|||||||
matches!(
|
matches!(
|
||||||
turn.approval_policy.value(),
|
turn.approval_policy.value(),
|
||||||
AskForApproval::OnRequest | AskForApproval::Granular(_)
|
AskForApproval::OnRequest | AskForApproval::Granular(_)
|
||||||
) && turn.config.approvals_reviewer == ApprovalsReviewer::GuardianSubagent
|
) && turn.config.approvals_reviewer == ApprovalsReviewer::AutoReview
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_guardian_reviewer_source(
|
pub(crate) fn is_guardian_reviewer_source(
|
||||||
|
|||||||
@@ -909,7 +909,7 @@ async fn routes_approval_to_guardian_requires_guardian_reviewer() {
|
|||||||
|
|
||||||
assert!(!routes_approval_to_guardian(&turn));
|
assert!(!routes_approval_to_guardian(&turn));
|
||||||
|
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
turn.config = Arc::new(config);
|
turn.config = Arc::new(config);
|
||||||
|
|
||||||
assert!(routes_approval_to_guardian(&turn));
|
assert!(routes_approval_to_guardian(&turn));
|
||||||
@@ -919,7 +919,7 @@ async fn routes_approval_to_guardian_requires_guardian_reviewer() {
|
|||||||
async fn routes_approval_to_guardian_allows_granular_review_policy() {
|
async fn routes_approval_to_guardian_allows_granular_review_policy() {
|
||||||
let (_session, mut turn) = crate::session::tests::make_session_and_context().await;
|
let (_session, mut turn) = crate::session::tests::make_session_and_context().await;
|
||||||
let mut config = (*turn.config).clone();
|
let mut config = (*turn.config).clone();
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
turn.config = Arc::new(config);
|
turn.config = Arc::new(config);
|
||||||
turn.approval_policy
|
turn.approval_policy
|
||||||
.set(AskForApproval::Granular(GranularApprovalConfig {
|
.set(AskForApproval::Granular(GranularApprovalConfig {
|
||||||
|
|||||||
@@ -1411,7 +1411,7 @@ async fn guardian_mode_skips_auto_when_annotations_do_not_require_approval() {
|
|||||||
.expect("test setup should allow updating approval policy");
|
.expect("test setup should allow updating approval policy");
|
||||||
let mut config = (*turn_context.config).clone();
|
let mut config = (*turn_context.config).clone();
|
||||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
let config = Arc::new(config);
|
let config = Arc::new(config);
|
||||||
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
||||||
config.codex_home.to_path_buf(),
|
config.codex_home.to_path_buf(),
|
||||||
@@ -1490,7 +1490,7 @@ async fn guardian_mode_mcp_denial_returns_rationale_message() {
|
|||||||
.expect("test setup should allow updating approval policy");
|
.expect("test setup should allow updating approval policy");
|
||||||
let mut config = (*turn_context.config).clone();
|
let mut config = (*turn_context.config).clone();
|
||||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
let config = Arc::new(config);
|
let config = Arc::new(config);
|
||||||
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
||||||
config.codex_home.to_path_buf(),
|
config.codex_home.to_path_buf(),
|
||||||
@@ -1947,7 +1947,7 @@ async fn approve_mode_routes_arc_ask_user_to_guardian_when_guardian_reviewer_is_
|
|||||||
let mut config = (*turn_context.config).clone();
|
let mut config = (*turn_context.config).clone();
|
||||||
config.chatgpt_base_url = server.uri();
|
config.chatgpt_base_url = server.uri();
|
||||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
let config = Arc::new(config);
|
let config = Arc::new(config);
|
||||||
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
||||||
config.codex_home.to_path_buf(),
|
config.codex_home.to_path_buf(),
|
||||||
|
|||||||
@@ -3827,7 +3827,7 @@ async fn user_turn_updates_approvals_reviewer() {
|
|||||||
}],
|
}],
|
||||||
cwd: config.cwd.to_path_buf(),
|
cwd: config.cwd.to_path_buf(),
|
||||||
approval_policy: config.permissions.approval_policy.value(),
|
approval_policy: config.permissions.approval_policy.value(),
|
||||||
approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview),
|
||||||
sandbox_policy: config.permissions.sandbox_policy.get().clone(),
|
sandbox_policy: config.permissions.sandbox_policy.get().clone(),
|
||||||
model: turn_context.model_info.slug.clone(),
|
model: turn_context.model_info.slug.clone(),
|
||||||
effort: config.model_reasoning_effort,
|
effort: config.model_reasoning_effort,
|
||||||
@@ -3843,7 +3843,7 @@ async fn user_turn_updates_approvals_reviewer() {
|
|||||||
let state = session.state.lock().await;
|
let state = session.state.lock().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
state.session_configuration.approvals_reviewer,
|
state.session_configuration.approvals_reviewer,
|
||||||
codex_config::types::ApprovalsReviewer::GuardianSubagent
|
codex_config::types::ApprovalsReviewer::AutoReview
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ async fn request_permissions_routes_to_guardian_when_reviewer_is_enabled() {
|
|||||||
.enable(Feature::GuardianApproval)
|
.enable(Feature::GuardianApproval)
|
||||||
.expect("test setup should allow enabling guardian approvals");
|
.expect("test setup should allow enabling guardian approvals");
|
||||||
let mut config = (*turn_context_raw.config).clone();
|
let mut config = (*turn_context_raw.config).clone();
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||||
let config = Arc::new(config);
|
let config = Arc::new(config);
|
||||||
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
||||||
@@ -166,7 +166,7 @@ async fn request_permissions_guardian_review_stops_when_cancelled() {
|
|||||||
.enable(Feature::GuardianApproval)
|
.enable(Feature::GuardianApproval)
|
||||||
.expect("test setup should allow enabling guardian approvals");
|
.expect("test setup should allow enabling guardian approvals");
|
||||||
let mut config = (*turn_context_raw.config).clone();
|
let mut config = (*turn_context_raw.config).clone();
|
||||||
config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||||
let config = Arc::new(config);
|
let config = Arc::new(config);
|
||||||
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
let models_manager = Arc::new(crate::test_support::models_manager_with_provider(
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ async fn thread_start_params_include_review_policy_when_auto_review_is_enabled()
|
|||||||
let config = ConfigBuilder::default()
|
let config = ConfigBuilder::default()
|
||||||
.codex_home(codex_home.path().to_path_buf())
|
.codex_home(codex_home.path().to_path_buf())
|
||||||
.harness_overrides(ConfigOverrides {
|
.harness_overrides(ConfigOverrides {
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.fallback_cwd(Some(cwd.path().to_path_buf()))
|
.fallback_cwd(Some(cwd.path().to_path_buf()))
|
||||||
@@ -387,7 +387,7 @@ async fn thread_start_params_include_review_policy_when_auto_review_is_enabled()
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
params.approvals_reviewer,
|
params.approvals_reviewer,
|
||||||
Some(codex_app_server_protocol::ApprovalsReviewer::GuardianSubagent)
|
Some(codex_app_server_protocol::ApprovalsReviewer::AutoReview)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ fn session_configured_from_thread_response_uses_review_policy_from_response() {
|
|||||||
cwd: test_path_buf("/tmp").abs(),
|
cwd: test_path_buf("/tmp").abs(),
|
||||||
instruction_sources: Vec::new(),
|
instruction_sources: Vec::new(),
|
||||||
approval_policy: codex_app_server_protocol::AskForApproval::OnRequest,
|
approval_policy: codex_app_server_protocol::AskForApproval::OnRequest,
|
||||||
approvals_reviewer: codex_app_server_protocol::ApprovalsReviewer::GuardianSubagent,
|
approvals_reviewer: codex_app_server_protocol::ApprovalsReviewer::AutoReview,
|
||||||
sandbox: codex_app_server_protocol::SandboxPolicy::WorkspaceWrite {
|
sandbox: codex_app_server_protocol::SandboxPolicy::WorkspaceWrite {
|
||||||
writable_roots: vec![],
|
writable_roots: vec![],
|
||||||
read_only_access: codex_app_server_protocol::ReadOnlyAccess::FullAccess,
|
read_only_access: codex_app_server_protocol::ReadOnlyAccess::FullAccess,
|
||||||
@@ -440,8 +440,5 @@ fn session_configured_from_thread_response_uses_review_policy_from_response() {
|
|||||||
let event = session_configured_from_thread_start_response(&response)
|
let event = session_configured_from_thread_start_response(&response)
|
||||||
.expect("build bootstrap session configured event");
|
.expect("build bootstrap session configured event");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(event.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
event.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ pub enum ApprovalsReviewer {
|
|||||||
User,
|
User,
|
||||||
#[serde(rename = "auto_review", alias = "guardian_subagent")]
|
#[serde(rename = "auto_review", alias = "guardian_subagent")]
|
||||||
#[strum(serialize = "auto_review")]
|
#[strum(serialize = "auto_review")]
|
||||||
GuardianSubagent,
|
AutoReview,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonSchema for ApprovalsReviewer {
|
impl JsonSchema for ApprovalsReviewer {
|
||||||
@@ -608,8 +608,7 @@ mod tests {
|
|||||||
"\"user\""
|
"\"user\""
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serde_json::to_string(&ApprovalsReviewer::GuardianSubagent)
|
serde_json::to_string(&ApprovalsReviewer::AutoReview).expect("serialize reviewer"),
|
||||||
.expect("serialize reviewer"),
|
|
||||||
"\"auto_review\""
|
"\"auto_review\""
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -620,7 +619,7 @@ mod tests {
|
|||||||
let expected = if value == "user" {
|
let expected = if value == "user" {
|
||||||
ApprovalsReviewer::User
|
ApprovalsReviewer::User
|
||||||
} else {
|
} else {
|
||||||
ApprovalsReviewer::GuardianSubagent
|
ApprovalsReviewer::AutoReview
|
||||||
};
|
};
|
||||||
assert_eq!(expected, reviewer);
|
assert_eq!(expected, reviewer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ fn default_exec_approval_decisions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
struct GuardianApprovalsMode {
|
struct AutoReviewMode {
|
||||||
approval_policy: AskForApproval,
|
approval_policy: AskForApproval,
|
||||||
approvals_reviewer: ApprovalsReviewer,
|
approvals_reviewer: ApprovalsReviewer,
|
||||||
sandbox_policy: SandboxPolicy,
|
sandbox_policy: SandboxPolicy,
|
||||||
@@ -309,11 +309,11 @@ struct GuardianApprovalsMode {
|
|||||||
/// Enabling the Auto-review experiment in the TUI should also switch the
|
/// Enabling the Auto-review experiment in the TUI should also switch the
|
||||||
/// current `/approvals` settings to the matching Auto-review mode. Users
|
/// current `/approvals` settings to the matching Auto-review mode. Users
|
||||||
/// can still change `/approvals` afterward; this just assumes that opting into
|
/// can still change `/approvals` afterward; this just assumes that opting into
|
||||||
/// the experiment means they want guardian review enabled immediately.
|
/// the experiment means they want Auto-review enabled immediately.
|
||||||
fn guardian_approvals_mode() -> GuardianApprovalsMode {
|
fn auto_review_mode() -> AutoReviewMode {
|
||||||
GuardianApprovalsMode {
|
AutoReviewMode {
|
||||||
approval_policy: AskForApproval::OnRequest,
|
approval_policy: AskForApproval::OnRequest,
|
||||||
approvals_reviewer: ApprovalsReviewer::GuardianSubagent,
|
approvals_reviewer: ApprovalsReviewer::AutoReview,
|
||||||
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ impl App {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let guardian_approvals_preset = guardian_approvals_mode();
|
let auto_review_preset = auto_review_mode();
|
||||||
let mut next_config = self.config.clone();
|
let mut next_config = self.config.clone();
|
||||||
let active_profile = self.active_profile.clone();
|
let active_profile = self.active_profile.clone();
|
||||||
let scoped_segments = |key: &str| {
|
let scoped_segments = |key: &str| {
|
||||||
@@ -202,16 +202,12 @@ impl App {
|
|||||||
// Persist the reviewer setting so future sessions keep the
|
// Persist the reviewer setting so future sessions keep the
|
||||||
// experiment's matching `/approvals` mode until the user
|
// experiment's matching `/approvals` mode until the user
|
||||||
// changes it explicitly.
|
// changes it explicitly.
|
||||||
feature_config.approvals_reviewer =
|
feature_config.approvals_reviewer = auto_review_preset.approvals_reviewer;
|
||||||
guardian_approvals_preset.approvals_reviewer;
|
|
||||||
feature_edits.push(ConfigEdit::SetPath {
|
feature_edits.push(ConfigEdit::SetPath {
|
||||||
segments: scoped_segments("approvals_reviewer"),
|
segments: scoped_segments("approvals_reviewer"),
|
||||||
value: guardian_approvals_preset
|
value: auto_review_preset.approvals_reviewer.to_string().into(),
|
||||||
.approvals_reviewer
|
|
||||||
.to_string()
|
|
||||||
.into(),
|
|
||||||
});
|
});
|
||||||
if previous_approvals_reviewer != guardian_approvals_preset.approvals_reviewer {
|
if previous_approvals_reviewer != auto_review_preset.approvals_reviewer {
|
||||||
permissions_history_label = Some("Auto-review");
|
permissions_history_label = Some("Auto-review");
|
||||||
}
|
}
|
||||||
} else if !effective_enabled {
|
} else if !effective_enabled {
|
||||||
@@ -234,17 +230,17 @@ impl App {
|
|||||||
// makes guardian review observable in the current thread.
|
// makes guardian review observable in the current thread.
|
||||||
if !self.try_set_approval_policy_on_config(
|
if !self.try_set_approval_policy_on_config(
|
||||||
&mut feature_config,
|
&mut feature_config,
|
||||||
guardian_approvals_preset.approval_policy,
|
auto_review_preset.approval_policy,
|
||||||
"Failed to enable Auto-review",
|
"Failed to enable Auto-review",
|
||||||
"failed to set guardian approvals approval policy on staged config",
|
"failed to set auto-review approval policy on staged config",
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !self.try_set_sandbox_policy_on_config(
|
if !self.try_set_sandbox_policy_on_config(
|
||||||
&mut feature_config,
|
&mut feature_config,
|
||||||
guardian_approvals_preset.sandbox_policy.clone(),
|
auto_review_preset.sandbox_policy.clone(),
|
||||||
"Failed to enable Auto-review",
|
"Failed to enable Auto-review",
|
||||||
"failed to set guardian approvals sandbox policy on staged config",
|
"failed to set auto-review sandbox policy on staged config",
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -258,8 +254,8 @@ impl App {
|
|||||||
value: "workspace-write".into(),
|
value: "workspace-write".into(),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
approval_policy_override = Some(guardian_approvals_preset.approval_policy);
|
approval_policy_override = Some(auto_review_preset.approval_policy);
|
||||||
sandbox_policy_override = Some(guardian_approvals_preset.sandbox_policy.clone());
|
sandbox_policy_override = Some(auto_review_preset.sandbox_policy.clone());
|
||||||
}
|
}
|
||||||
next_config = feature_config;
|
next_config = feature_config;
|
||||||
feature_updates_to_apply.push((feature, effective_enabled));
|
feature_updates_to_apply.push((feature, effective_enabled));
|
||||||
@@ -305,7 +301,7 @@ impl App {
|
|||||||
{
|
{
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
error = %err,
|
error = %err,
|
||||||
"failed to set guardian approvals sandbox policy on chat config"
|
"failed to set auto-review sandbox policy on chat config"
|
||||||
);
|
);
|
||||||
self.chat_widget
|
self.chat_widget
|
||||||
.add_error_message(format!("Failed to enable Auto-review: {err}"));
|
.add_error_message(format!("Failed to enable Auto-review: {err}"));
|
||||||
|
|||||||
@@ -1598,11 +1598,11 @@ async fn reset_memories_clears_local_memory_directories() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn update_feature_flags_enabling_guardian_selects_guardian_approvals() -> Result<()> {
|
async fn update_feature_flags_enabling_guardian_selects_auto_review() -> Result<()> {
|
||||||
let (mut app, mut app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
let (mut app, mut app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
||||||
let codex_home = tempdir()?;
|
let codex_home = tempdir()?;
|
||||||
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
||||||
let guardian_approvals = guardian_approvals_mode();
|
let auto_review = auto_review_mode();
|
||||||
|
|
||||||
app.update_feature_flags(vec![(Feature::GuardianApproval, true)])
|
app.update_feature_flags(vec![(Feature::GuardianApproval, true)])
|
||||||
.await;
|
.await;
|
||||||
@@ -1616,11 +1616,11 @@ async fn update_feature_flags_enabling_guardian_selects_guardian_approvals() ->
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.config.approvals_reviewer,
|
app.config.approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.config.permissions.approval_policy.value(),
|
app.config.permissions.approval_policy.value(),
|
||||||
guardian_approvals.approval_policy
|
auto_review.approval_policy
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
@@ -1628,7 +1628,7 @@ async fn update_feature_flags_enabling_guardian_selects_guardian_approvals() ->
|
|||||||
.permissions
|
.permissions
|
||||||
.approval_policy
|
.approval_policy
|
||||||
.value(),
|
.value(),
|
||||||
guardian_approvals.approval_policy
|
auto_review.approval_policy
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
@@ -1636,11 +1636,11 @@ async fn update_feature_flags_enabling_guardian_selects_guardian_approvals() ->
|
|||||||
.permissions
|
.permissions
|
||||||
.sandbox_policy
|
.sandbox_policy
|
||||||
.get(),
|
.get(),
|
||||||
&guardian_approvals.sandbox_policy
|
&auto_review.sandbox_policy
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget.config_ref().approvals_reviewer,
|
app.chat_widget.config_ref().approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(app.runtime_approval_policy_override, None);
|
assert_eq!(app.runtime_approval_policy_override, None);
|
||||||
assert_eq!(app.runtime_sandbox_policy_override, None);
|
assert_eq!(app.runtime_sandbox_policy_override, None);
|
||||||
@@ -1648,9 +1648,9 @@ async fn update_feature_flags_enabling_guardian_selects_guardian_approvals() ->
|
|||||||
op_rx.try_recv(),
|
op_rx.try_recv(),
|
||||||
Ok(Op::OverrideTurnContext {
|
Ok(Op::OverrideTurnContext {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
approval_policy: Some(guardian_approvals.approval_policy),
|
approval_policy: Some(auto_review.approval_policy),
|
||||||
approvals_reviewer: Some(guardian_approvals.approvals_reviewer),
|
approvals_reviewer: Some(auto_review.approvals_reviewer),
|
||||||
sandbox_policy: Some(guardian_approvals.sandbox_policy.clone()),
|
sandbox_policy: Some(auto_review.sandbox_policy.clone()),
|
||||||
permission_profile: None,
|
permission_profile: None,
|
||||||
windows_sandbox_level: None,
|
windows_sandbox_level: None,
|
||||||
model: None,
|
model: None,
|
||||||
@@ -1700,9 +1700,9 @@ async fn update_feature_flags_disabling_guardian_clears_review_policy_and_restor
|
|||||||
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
||||||
app.config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
app.config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_approvals_reviewer(ApprovalsReviewer::GuardianSubagent);
|
.set_approvals_reviewer(ApprovalsReviewer::AutoReview);
|
||||||
app.config
|
app.config
|
||||||
.permissions
|
.permissions
|
||||||
.approval_policy
|
.approval_policy
|
||||||
@@ -1779,7 +1779,7 @@ async fn update_feature_flags_enabling_guardian_overrides_explicit_manual_review
|
|||||||
let (mut app, _app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
let (mut app, _app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
||||||
let codex_home = tempdir()?;
|
let codex_home = tempdir()?;
|
||||||
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
||||||
let guardian_approvals = guardian_approvals_mode();
|
let auto_review = auto_review_mode();
|
||||||
let config_toml_path = codex_home.path().join("config.toml").abs();
|
let config_toml_path = codex_home.path().join("config.toml").abs();
|
||||||
let config_toml = "approvals_reviewer = \"user\"\n";
|
let config_toml = "approvals_reviewer = \"user\"\n";
|
||||||
std::fs::write(config_toml_path.as_path(), config_toml)?;
|
std::fs::write(config_toml_path.as_path(), config_toml)?;
|
||||||
@@ -1798,15 +1798,15 @@ async fn update_feature_flags_enabling_guardian_overrides_explicit_manual_review
|
|||||||
assert!(app.config.features.enabled(Feature::GuardianApproval));
|
assert!(app.config.features.enabled(Feature::GuardianApproval));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.config.approvals_reviewer,
|
app.config.approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget.config_ref().approvals_reviewer,
|
app.chat_widget.config_ref().approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.config.permissions.approval_policy.value(),
|
app.config.permissions.approval_policy.value(),
|
||||||
guardian_approvals.approval_policy
|
auto_review.approval_policy
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
@@ -1814,15 +1814,15 @@ async fn update_feature_flags_enabling_guardian_overrides_explicit_manual_review
|
|||||||
.permissions
|
.permissions
|
||||||
.sandbox_policy
|
.sandbox_policy
|
||||||
.get(),
|
.get(),
|
||||||
&guardian_approvals.sandbox_policy
|
&auto_review.sandbox_policy
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
op_rx.try_recv(),
|
op_rx.try_recv(),
|
||||||
Ok(Op::OverrideTurnContext {
|
Ok(Op::OverrideTurnContext {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
approval_policy: Some(guardian_approvals.approval_policy),
|
approval_policy: Some(auto_review.approval_policy),
|
||||||
approvals_reviewer: Some(guardian_approvals.approvals_reviewer),
|
approvals_reviewer: Some(auto_review.approvals_reviewer),
|
||||||
sandbox_policy: Some(guardian_approvals.sandbox_policy.clone()),
|
sandbox_policy: Some(auto_review.sandbox_policy.clone()),
|
||||||
permission_profile: None,
|
permission_profile: None,
|
||||||
windows_sandbox_level: None,
|
windows_sandbox_level: None,
|
||||||
model: None,
|
model: None,
|
||||||
@@ -1908,7 +1908,7 @@ async fn update_feature_flags_enabling_guardian_in_profile_sets_profile_auto_rev
|
|||||||
let (mut app, _app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
let (mut app, _app_event_rx, mut op_rx) = make_test_app_with_channels().await;
|
||||||
let codex_home = tempdir()?;
|
let codex_home = tempdir()?;
|
||||||
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
app.config.codex_home = codex_home.path().to_path_buf().abs();
|
||||||
let guardian_approvals = guardian_approvals_mode();
|
let auto_review = auto_review_mode();
|
||||||
app.active_profile = Some("guardian".to_string());
|
app.active_profile = Some("guardian".to_string());
|
||||||
let config_toml_path = codex_home.path().join("config.toml").abs();
|
let config_toml_path = codex_home.path().join("config.toml").abs();
|
||||||
let config_toml = "profile = \"guardian\"\napprovals_reviewer = \"user\"\n";
|
let config_toml = "profile = \"guardian\"\napprovals_reviewer = \"user\"\n";
|
||||||
@@ -1928,19 +1928,19 @@ async fn update_feature_flags_enabling_guardian_in_profile_sets_profile_auto_rev
|
|||||||
assert!(app.config.features.enabled(Feature::GuardianApproval));
|
assert!(app.config.features.enabled(Feature::GuardianApproval));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.config.approvals_reviewer,
|
app.config.approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget.config_ref().approvals_reviewer,
|
app.chat_widget.config_ref().approvals_reviewer,
|
||||||
guardian_approvals.approvals_reviewer
|
auto_review.approvals_reviewer
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
op_rx.try_recv(),
|
op_rx.try_recv(),
|
||||||
Ok(Op::OverrideTurnContext {
|
Ok(Op::OverrideTurnContext {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
approval_policy: Some(guardian_approvals.approval_policy),
|
approval_policy: Some(auto_review.approval_policy),
|
||||||
approvals_reviewer: Some(guardian_approvals.approvals_reviewer),
|
approvals_reviewer: Some(auto_review.approvals_reviewer),
|
||||||
sandbox_policy: Some(guardian_approvals.sandbox_policy.clone()),
|
sandbox_policy: Some(auto_review.sandbox_policy.clone()),
|
||||||
permission_profile: None,
|
permission_profile: None,
|
||||||
windows_sandbox_level: None,
|
windows_sandbox_level: None,
|
||||||
model: None,
|
model: None,
|
||||||
@@ -2003,9 +2003,9 @@ guardian_approval = true
|
|||||||
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
||||||
app.config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
app.config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_approvals_reviewer(ApprovalsReviewer::GuardianSubagent);
|
.set_approvals_reviewer(ApprovalsReviewer::AutoReview);
|
||||||
|
|
||||||
app.update_feature_flags(vec![(Feature::GuardianApproval, false)])
|
app.update_feature_flags(vec![(Feature::GuardianApproval, false)])
|
||||||
.await;
|
.await;
|
||||||
@@ -2083,9 +2083,9 @@ async fn update_feature_flags_disabling_guardian_in_profile_keeps_inherited_non_
|
|||||||
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
.set_enabled(Feature::GuardianApproval, /*enabled*/ true)?;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ true);
|
||||||
app.config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
app.config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
app.chat_widget
|
app.chat_widget
|
||||||
.set_approvals_reviewer(ApprovalsReviewer::GuardianSubagent);
|
.set_approvals_reviewer(ApprovalsReviewer::AutoReview);
|
||||||
|
|
||||||
app.update_feature_flags(vec![(Feature::GuardianApproval, false)])
|
app.update_feature_flags(vec![(Feature::GuardianApproval, false)])
|
||||||
.await;
|
.await;
|
||||||
@@ -2097,13 +2097,10 @@ async fn update_feature_flags_disabling_guardian_in_profile_keeps_inherited_non_
|
|||||||
.features
|
.features
|
||||||
.enabled(Feature::GuardianApproval)
|
.enabled(Feature::GuardianApproval)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(app.config.approvals_reviewer, ApprovalsReviewer::AutoReview);
|
||||||
app.config.approvals_reviewer,
|
|
||||||
ApprovalsReviewer::GuardianSubagent
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.chat_widget.config_ref().approvals_reviewer,
|
app.chat_widget.config_ref().approvals_reviewer,
|
||||||
ApprovalsReviewer::GuardianSubagent
|
ApprovalsReviewer::AutoReview
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
op_rx.try_recv().is_err(),
|
op_rx.try_recv().is_err(),
|
||||||
|
|||||||
@@ -9042,7 +9042,7 @@ impl ChatWidget {
|
|||||||
"Same workspace-write permissions as Default, but eligible `on-request` approvals are routed through the auto-reviewer subagent."
|
"Same workspace-write permissions as Default, but eligible `on-request` approvals are routed through the auto-reviewer subagent."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
is_current: current_review_policy == ApprovalsReviewer::GuardianSubagent
|
is_current: current_review_policy == ApprovalsReviewer::AutoReview
|
||||||
&& Self::preset_matches_current(
|
&& Self::preset_matches_current(
|
||||||
current_approval,
|
current_approval,
|
||||||
current_sandbox,
|
current_sandbox,
|
||||||
@@ -9052,7 +9052,7 @@ impl ChatWidget {
|
|||||||
preset.approval,
|
preset.approval,
|
||||||
preset.sandbox.clone(),
|
preset.sandbox.clone(),
|
||||||
"Auto-review".to_string(),
|
"Auto-review".to_string(),
|
||||||
ApprovalsReviewer::GuardianSubagent,
|
ApprovalsReviewer::AutoReview,
|
||||||
),
|
),
|
||||||
dismiss_on_select: true,
|
dismiss_on_select: true,
|
||||||
disabled_reason: approval_disabled_reason
|
disabled_reason: approval_disabled_reason
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ async fn permissions_selection_emits_history_cell_when_current_is_selected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn permissions_selection_hides_guardian_approvals_when_feature_disabled() {
|
async fn permissions_selection_hides_auto_review_when_feature_disabled() {
|
||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
@@ -406,7 +406,7 @@ async fn permissions_selection_hides_guardian_approvals_when_feature_disabled()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn permissions_selection_hides_guardian_approvals_when_feature_disabled_even_if_auto_review_is_active()
|
async fn permissions_selection_hides_auto_review_when_feature_disabled_even_if_auto_review_is_active()
|
||||||
{
|
{
|
||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -416,7 +416,7 @@ async fn permissions_selection_hides_guardian_approvals_when_feature_disabled_ev
|
|||||||
}
|
}
|
||||||
chat.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ false);
|
chat.set_feature_enabled(Feature::GuardianApproval, /*enabled*/ false);
|
||||||
chat.config.notices.hide_full_access_warning = Some(true);
|
chat.config.notices.hide_full_access_warning = Some(true);
|
||||||
chat.config.approvals_reviewer = ApprovalsReviewer::GuardianSubagent;
|
chat.config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||||
chat.config
|
chat.config
|
||||||
.permissions
|
.permissions
|
||||||
.approval_policy
|
.approval_policy
|
||||||
@@ -438,7 +438,7 @@ async fn permissions_selection_hides_guardian_approvals_when_feature_disabled_ev
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn permissions_selection_marks_guardian_approvals_current_after_session_configured() {
|
async fn permissions_selection_marks_auto_review_current_after_session_configured() {
|
||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
@@ -461,7 +461,7 @@ async fn permissions_selection_marks_guardian_approvals_current_after_session_co
|
|||||||
model_provider_id: "test-provider".to_string(),
|
model_provider_id: "test-provider".to_string(),
|
||||||
service_tier: None,
|
service_tier: None,
|
||||||
approval_policy: AskForApproval::OnRequest,
|
approval_policy: AskForApproval::OnRequest,
|
||||||
approvals_reviewer: ApprovalsReviewer::GuardianSubagent,
|
approvals_reviewer: ApprovalsReviewer::AutoReview,
|
||||||
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
||||||
cwd: test_project_path().abs(),
|
cwd: test_project_path().abs(),
|
||||||
reasoning_effort: None,
|
reasoning_effort: None,
|
||||||
@@ -483,8 +483,7 @@ async fn permissions_selection_marks_guardian_approvals_current_after_session_co
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn permissions_selection_marks_guardian_approvals_current_with_custom_workspace_write_details()
|
async fn permissions_selection_marks_auto_review_current_with_custom_workspace_write_details() {
|
||||||
{
|
|
||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
@@ -509,7 +508,7 @@ async fn permissions_selection_marks_guardian_approvals_current_with_custom_work
|
|||||||
model_provider_id: "test-provider".to_string(),
|
model_provider_id: "test-provider".to_string(),
|
||||||
service_tier: None,
|
service_tier: None,
|
||||||
approval_policy: AskForApproval::OnRequest,
|
approval_policy: AskForApproval::OnRequest,
|
||||||
approvals_reviewer: ApprovalsReviewer::GuardianSubagent,
|
approvals_reviewer: ApprovalsReviewer::AutoReview,
|
||||||
sandbox_policy: SandboxPolicy::WorkspaceWrite {
|
sandbox_policy: SandboxPolicy::WorkspaceWrite {
|
||||||
writable_roots: vec![extra_root],
|
writable_roots: vec![extra_root],
|
||||||
read_only_access: ReadOnlyAccess::FullAccess,
|
read_only_access: ReadOnlyAccess::FullAccess,
|
||||||
@@ -537,7 +536,7 @@ async fn permissions_selection_marks_guardian_approvals_current_with_custom_work
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn permissions_selection_can_disable_guardian_approvals() {
|
async fn permissions_selection_can_disable_auto_review() {
|
||||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
@@ -630,7 +629,7 @@ async fn permissions_selection_sends_approvals_reviewer_in_override_turn_context
|
|||||||
Op::OverrideTurnContext {
|
Op::OverrideTurnContext {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
approval_policy: Some(AskForApproval::OnRequest),
|
approval_policy: Some(AskForApproval::OnRequest),
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::GuardianSubagent),
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
sandbox_policy: Some(SandboxPolicy::new_workspace_write_policy()),
|
sandbox_policy: Some(SandboxPolicy::new_workspace_write_policy()),
|
||||||
permission_profile: None,
|
permission_profile: None,
|
||||||
windows_sandbox_level: None,
|
windows_sandbox_level: None,
|
||||||
|
|||||||
@@ -586,7 +586,7 @@ mod tests {
|
|||||||
Some(RequirementSource::CloudRequirements),
|
Some(RequirementSource::CloudRequirements),
|
||||||
),
|
),
|
||||||
approvals_reviewer: ConstrainedWithSource::new(
|
approvals_reviewer: ConstrainedWithSource::new(
|
||||||
Constrained::allow_any(ApprovalsReviewer::GuardianSubagent),
|
Constrained::allow_any(ApprovalsReviewer::AutoReview),
|
||||||
Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
|
Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
|
||||||
),
|
),
|
||||||
sandbox_policy: ConstrainedWithSource::new(
|
sandbox_policy: ConstrainedWithSource::new(
|
||||||
@@ -647,7 +647,7 @@ mod tests {
|
|||||||
|
|
||||||
let requirements_toml = ConfigRequirementsToml {
|
let requirements_toml = ConfigRequirementsToml {
|
||||||
allowed_approval_policies: Some(vec![AskForApproval::OnRequest]),
|
allowed_approval_policies: Some(vec![AskForApproval::OnRequest]),
|
||||||
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::GuardianSubagent]),
|
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::AutoReview]),
|
||||||
allowed_sandbox_modes: Some(vec![SandboxModeRequirement::ReadOnly]),
|
allowed_sandbox_modes: Some(vec![SandboxModeRequirement::ReadOnly]),
|
||||||
remote_sandbox_config: None,
|
remote_sandbox_config: None,
|
||||||
allowed_web_search_modes: Some(vec![WebSearchModeRequirement::Cached]),
|
allowed_web_search_modes: Some(vec![WebSearchModeRequirement::Cached]),
|
||||||
@@ -731,13 +731,13 @@ mod tests {
|
|||||||
fn debug_config_output_lists_approvals_reviewer_as_requirement() {
|
fn debug_config_output_lists_approvals_reviewer_as_requirement() {
|
||||||
let requirements = ConfigRequirements {
|
let requirements = ConfigRequirements {
|
||||||
approvals_reviewer: ConstrainedWithSource::new(
|
approvals_reviewer: ConstrainedWithSource::new(
|
||||||
Constrained::allow_any(ApprovalsReviewer::GuardianSubagent),
|
Constrained::allow_any(ApprovalsReviewer::AutoReview),
|
||||||
Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
|
Some(RequirementSource::LegacyManagedConfigTomlFromMdm),
|
||||||
),
|
),
|
||||||
..ConfigRequirements::default()
|
..ConfigRequirements::default()
|
||||||
};
|
};
|
||||||
let requirements_toml = ConfigRequirementsToml {
|
let requirements_toml = ConfigRequirementsToml {
|
||||||
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::GuardianSubagent]),
|
allowed_approvals_reviewers: Some(vec![ApprovalsReviewer::AutoReview]),
|
||||||
..ConfigRequirementsToml::default()
|
..ConfigRequirementsToml::default()
|
||||||
};
|
};
|
||||||
let stack = ConfigLayerStack::new(Vec::new(), requirements, requirements_toml)
|
let stack = ConfigLayerStack::new(Vec::new(), requirements, requirements_toml)
|
||||||
|
|||||||
Reference in new issue
Block a user