app-server-protocol: remove PermissionProfile from API (#22924)

## Why

The app server API should expose permission profile identity, not the
lower-level runtime permission model. `PermissionProfile` is the
compiled sandbox/network representation that the server uses internally;
exposing it through app-server-protocol forces clients to understand
details that should remain implementation-level.

The API boundary should prefer `ActivePermissionProfile`: a stable
profile id, plus future parent-profile metadata, that clients can pass
back when they want to select the same active permissions. This also
avoids schema generation collisions between the app-server v2 API type
space and the core protocol model.

Incidentally, while PR makes a number of changes to `command/exec`, note
that we are hoping to deprecate this API in favor of `process/spawn`, so
we don't need to be too finicky about these changes.

## What Changed

- Removed `PermissionProfile` from the app-server-protocol API surface,
including generated schema and TypeScript exports.
- Changed `CommandExecParams.permissionProfile` to
`ActivePermissionProfile`.
- Resolve command exec profile ids through `ConfigManager` for the
command cwd, matching turn override selection semantics.
- Updated downstream TUI tests/helpers to use core permission types
directly instead of app-server-protocol `PermissionProfile` shims.
This commit is contained in:
Michael Bolin
2026-05-15 17:10:15 -07:00
committed by GitHub
parent bbb5c2811d
commit 9025550709
31 changed files with 436 additions and 1440 deletions
+13 -16
View File
@@ -46,14 +46,13 @@ fn format_warning(additional_dirs: &[PathBuf]) -> String {
#[cfg(test)]
mod tests {
use super::add_dir_warning_message;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
use std::path::Path;
use std::path::PathBuf;
@@ -80,10 +79,9 @@ mod tests {
#[test]
fn returns_none_for_external_sandbox() {
let profile: PermissionProfile = AppServerPermissionProfile::External {
network: PermissionProfileNetworkPermissions { enabled: true },
}
.into();
let profile: PermissionProfile = PermissionProfile::External {
network: NetworkSandboxPolicy::Enabled,
};
let dirs = vec![PathBuf::from("/tmp/example")];
assert_eq!(
add_dir_warning_message(&dirs, &profile, Path::new("/tmp/project")),
@@ -105,9 +103,9 @@ mod tests {
#[test]
fn warns_when_profile_can_write_elsewhere_but_not_cwd() {
let profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -124,8 +122,7 @@ mod tests {
],
glob_scan_max_depth: None,
},
}
.into();
};
let dirs = vec![PathBuf::from("/tmp/extra")];
assert_eq!(
+10 -12
View File
@@ -123,16 +123,15 @@ mod tests {
use crate::test_support::PathBufExt;
use crate::test_support::test_path_buf;
use codex_app_server_protocol::AskForApproval;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_config::types::ApprovalsReviewer;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
use std::path::PathBuf;
@@ -255,9 +254,9 @@ mod tests {
let mut app = make_test_app().await;
let thread_id =
ThreadId::from_string("00000000-0000-0000-0000-000000000403").expect("valid thread");
let profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -274,8 +273,7 @@ mod tests {
],
glob_scan_max_depth: None,
},
}
.into();
};
let session = ThreadSessionState {
permission_profile: profile.clone(),
..test_thread_session(thread_id, test_path_buf("/tmp/main"))
+14 -17
View File
@@ -1604,13 +1604,6 @@ mod tests {
use super::*;
use crate::legacy_core::config::ConfigBuilder;
use crate::legacy_core::config::ConfigOverrides;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_app_server_protocol::ThreadStatus;
use codex_app_server_protocol::Turn;
use codex_app_server_protocol::TurnStatus;
@@ -1621,7 +1614,13 @@ mod tests {
use codex_protocol::config_types::WebSearchMode;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_READ_ONLY;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_utils_absolute_path::test_support::PathBufExt;
use codex_utils_absolute_path::test_support::test_path_buf;
use pretty_assertions::assert_eq;
@@ -1843,9 +1842,9 @@ mod tests {
fn sandbox_mode_does_not_project_non_cwd_write_roots_for_remote_sessions() {
let cwd = test_path_buf("/workspace/project").abs();
let extra_root = test_path_buf("/workspace/cache").abs();
let permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -1860,8 +1859,7 @@ mod tests {
],
glob_scan_max_depth: None,
},
}
.into();
};
assert_eq!(
sandbox_mode_from_permission_profile(&permission_profile, cwd.as_path()),
@@ -1872,9 +1870,9 @@ mod tests {
#[test]
fn sandbox_mode_projects_cwd_write_for_remote_sessions() {
let cwd = test_path_buf("/workspace/project").abs();
let permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -1891,8 +1889,7 @@ mod tests {
],
glob_scan_max_depth: None,
},
}
.into();
};
assert_eq!(
sandbox_mode_from_permission_profile(&permission_profile, cwd.as_path()),
@@ -1,11 +1,10 @@
use super::*;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
use std::collections::VecDeque;
@@ -99,9 +98,9 @@ async fn submission_includes_configured_active_permission_profile() {
let thread_id = ThreadId::new();
let rollout_file = NamedTempFile::new().unwrap();
let expected_permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let expected_permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -118,8 +117,7 @@ async fn submission_includes_configured_active_permission_profile() {
],
glob_scan_max_depth: None,
},
}
.into();
};
let expected_active_permission_profile = ActivePermissionProfile::new("custom");
let configured = crate::session_state::ThreadSessionState {
thread_id,
@@ -170,11 +168,10 @@ async fn submission_omits_active_permission_profile_for_legacy_snapshot() {
let thread_id = ThreadId::new();
let rollout_file = NamedTempFile::new().unwrap();
let expected_permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Unrestricted,
}
.into();
let expected_permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Unrestricted,
};
let configured = crate::session_state::ThreadSessionState {
thread_id,
forked_from_id: None,
@@ -1,13 +1,12 @@
use super::*;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::NetworkAccess;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_app_server_protocol::SandboxPolicy;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
#[tokio::test]
@@ -232,9 +231,9 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
chat.config.cwd = test_path_buf("/home/user/main").abs();
let expected_cwd = test_path_buf("/home/user/sub-agent").abs();
let expected_app_server_permission_profile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let expected_app_server_permission_profile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -252,8 +251,7 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
glob_scan_max_depth: None,
},
};
let expected_permission_profile: PermissionProfile =
expected_app_server_permission_profile.clone().into();
let expected_permission_profile = expected_app_server_permission_profile.clone();
let expected_core_sandbox = expected_permission_profile
.to_legacy_sandbox_policy(expected_cwd.as_path())
.expect("permission profile should project to legacy sandbox policy");
@@ -288,9 +286,7 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
let actual_sandbox = SandboxPolicy::from(chat.config_ref().legacy_sandbox_policy());
assert_eq!(&actual_sandbox, &expected_sandbox);
assert_eq!(
AppServerPermissionProfile::from(
chat.config_ref().permissions.effective_permission_profile()
),
chat.config_ref().permissions.effective_permission_profile(),
expected_app_server_permission_profile
);
assert_eq!(&chat.config_ref().cwd, &expected_cwd);
@@ -370,11 +366,10 @@ async fn session_configured_preserves_profile_workspace_roots() {
async fn session_configured_external_sandbox_keeps_external_runtime_policy() {
let (mut chat, _rx, _ops) = make_chatwidget_manual(/*model_override*/ None).await;
let expected_app_server_permission_profile = AppServerPermissionProfile::External {
network: PermissionProfileNetworkPermissions { enabled: false },
let expected_app_server_permission_profile = PermissionProfile::External {
network: NetworkSandboxPolicy::Restricted,
};
let expected_permission_profile: PermissionProfile =
expected_app_server_permission_profile.clone().into();
let expected_permission_profile = expected_app_server_permission_profile.clone();
let expected_sandbox = SandboxPolicy::ExternalSandbox {
network_access: NetworkAccess::Restricted,
};
@@ -404,9 +399,7 @@ async fn session_configured_external_sandbox_keeps_external_runtime_policy() {
let actual_sandbox = SandboxPolicy::from(chat.config_ref().legacy_sandbox_policy());
assert_eq!(&actual_sandbox, &expected_sandbox);
assert_eq!(
AppServerPermissionProfile::from(
chat.config_ref().permissions.effective_permission_profile()
),
chat.config_ref().permissions.effective_permission_profile(),
expected_app_server_permission_profile
);
}
@@ -1,17 +1,16 @@
use super::*;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
fn app_server_workspace_write_profile(extra_root: AbsolutePathBuf) -> PermissionProfile {
AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -45,7 +44,6 @@ fn app_server_workspace_write_profile(extra_root: AbsolutePathBuf) -> Permission
glob_scan_max_depth: None,
},
}
.into()
}
#[tokio::test]
@@ -127,9 +125,9 @@ async fn preset_matching_does_not_treat_non_cwd_writable_profile_as_read_only()
.into_iter()
.find(|p| p.id == "read-only")
.expect("read-only preset exists");
let current_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let current_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -146,8 +144,7 @@ async fn preset_matching_does_not_treat_non_cwd_writable_profile_as_read_only()
],
glob_scan_max_depth: None,
},
}
.into();
};
let cwd = test_path_buf("/tmp/project").abs();
assert!(
+2 -3
View File
@@ -51,9 +51,6 @@ use codex_app_server_protocol::AskForApproval;
use codex_app_server_protocol::McpAuthStatus;
use codex_app_server_protocol::McpServerStatus;
use codex_app_server_protocol::McpServerStatusDetail;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_app_server_protocol::ToolRequestUserInputAnswer;
use codex_app_server_protocol::ToolRequestUserInputQuestion;
use codex_app_server_protocol::WebSearchAction;
@@ -68,9 +65,11 @@ use codex_protocol::approvals::NetworkPolicyAmendment;
use codex_protocol::mcp::Resource;
#[cfg(test)]
use codex_protocol::mcp::ResourceTemplate;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::local_image_label_text;
use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::plan_tool::PlanItemArg;
use codex_protocol::plan_tool::StepStatus;
use codex_protocol::plan_tool::UpdatePlanArgs;
+4 -5
View File
@@ -227,14 +227,13 @@ pub(crate) fn has_yolo_permissions(
approval_policy: AskForApproval,
permission_profile: &PermissionProfile,
) -> bool {
let permission_profile = AppServerPermissionProfile::from(permission_profile.clone());
approval_policy == AskForApproval::Never
&& matches!(
permission_profile,
AppServerPermissionProfile::Disabled
| AppServerPermissionProfile::Managed {
file_system: PermissionProfileFileSystemPermissions::Unrestricted,
network: PermissionProfileNetworkPermissions { enabled: true },
PermissionProfile::Disabled
| PermissionProfile::Managed {
file_system: ManagedFileSystemPermissions::Unrestricted,
network: NetworkSandboxPolicy::Enabled,
}
)
}
+7 -9
View File
@@ -1470,11 +1470,10 @@ fn session_header_indicates_yolo_mode() {
#[test]
fn yolo_mode_includes_managed_full_access_profiles() {
let permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: true },
file_system: PermissionProfileFileSystemPermissions::Unrestricted,
}
.into();
let permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Enabled,
file_system: ManagedFileSystemPermissions::Unrestricted,
};
assert!(has_yolo_permissions(
AskForApproval::Never,
@@ -1484,10 +1483,9 @@ fn yolo_mode_includes_managed_full_access_profiles() {
#[test]
fn yolo_mode_excludes_external_sandbox_profiles() {
let permission_profile: PermissionProfile = AppServerPermissionProfile::External {
network: PermissionProfileNetworkPermissions { enabled: true },
}
.into();
let permission_profile: PermissionProfile = PermissionProfile::External {
network: NetworkSandboxPolicy::Enabled,
};
assert!(!has_yolo_permissions(
AskForApproval::Never,
+10 -12
View File
@@ -44,22 +44,21 @@ pub(crate) fn legacy_compatible_permission_profile(
#[cfg(test)]
mod tests {
use super::*;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use pretty_assertions::assert_eq;
#[test]
fn compatibility_profile_preserves_unbridgeable_write_roots() {
let cwd = AbsolutePathBuf::try_from("/workspace/project").expect("absolute cwd");
let extra_root = AbsolutePathBuf::try_from("/workspace/extra").expect("absolute root");
let permission_profile: PermissionProfile = AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Restricted {
let permission_profile: PermissionProfile = PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -76,8 +75,7 @@ mod tests {
],
glob_scan_max_depth: None,
},
}
.into();
};
let compatibility_profile =
legacy_compatible_permission_profile(&permission_profile, cwd.as_path());
+21 -33
View File
@@ -15,13 +15,6 @@ use chrono::TimeZone;
use chrono::Utc;
use codex_app_server_protocol::AskForApproval;
use codex_app_server_protocol::CreditsSnapshot;
use codex_app_server_protocol::FileSystemAccessMode;
use codex_app_server_protocol::FileSystemPath;
use codex_app_server_protocol::FileSystemSandboxEntry;
use codex_app_server_protocol::FileSystemSpecialPath;
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
use codex_app_server_protocol::PermissionProfileFileSystemPermissions;
use codex_app_server_protocol::PermissionProfileNetworkPermissions;
use codex_app_server_protocol::RateLimitSnapshot;
use codex_app_server_protocol::RateLimitWindow;
use codex_config::LoaderOverrides;
@@ -31,10 +24,14 @@ use codex_protocol::ThreadId;
use codex_protocol::config_types::ApprovalsReviewer;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::models::ActivePermissionProfile;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_READ_ONLY;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
use codex_protocol::models::ManagedFileSystemPermissions;
use codex_protocol::models::PermissionProfile;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
use codex_protocol::permissions::FileSystemSpecialPath;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_utils_absolute_path::AbsolutePathBuf;
use insta::assert_snapshot;
@@ -43,11 +40,13 @@ use ratatui::prelude::*;
use tempfile::TempDir;
fn app_server_workspace_write_profile(network_enabled: bool) -> PermissionProfile {
AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions {
enabled: network_enabled,
PermissionProfile::Managed {
network: if network_enabled {
NetworkSandboxPolicy::Enabled
} else {
NetworkSandboxPolicy::Restricted
},
file_system: PermissionProfileFileSystemPermissions::Restricted {
file_system: ManagedFileSystemPermissions::Restricted {
entries: vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
@@ -77,7 +76,6 @@ fn app_server_workspace_write_profile(network_enabled: bool) -> PermissionProfil
glob_scan_max_depth: None,
},
}
.into()
}
async fn test_config(temp_home: &TempDir) -> Config {
@@ -308,9 +306,7 @@ async fn status_permissions_named_read_only_profile_shows_builtin_label() {
.permissions
.set_permission_profile_from_session_snapshot(
PermissionProfile::read_only(),
Some(ActivePermissionProfile::new(
BUILT_IN_PERMISSION_PROFILE_READ_ONLY,
)),
Some(ActivePermissionProfile::read_only()),
)
.expect("set permission profile");
@@ -340,9 +336,7 @@ async fn status_permissions_read_only_profile_shows_additional_writable_roots()
&file_system_policy,
NetworkSandboxPolicy::Restricted,
),
Some(ActivePermissionProfile::new(
BUILT_IN_PERMISSION_PROFILE_READ_ONLY,
)),
Some(ActivePermissionProfile::read_only()),
)
.expect("set permission profile");
@@ -703,13 +697,10 @@ async fn status_permissions_full_disk_managed_with_network_is_danger_full_access
.expect("set approval policy");
config
.permissions
.set_permission_profile(
AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: true },
file_system: PermissionProfileFileSystemPermissions::Unrestricted,
}
.into(),
)
.set_permission_profile(PermissionProfile::Managed {
network: NetworkSandboxPolicy::Enabled,
file_system: ManagedFileSystemPermissions::Unrestricted,
})
.expect("set permission profile");
assert_eq!(
@@ -729,13 +720,10 @@ async fn status_permissions_full_disk_managed_without_network_is_external_sandbo
.expect("set approval policy");
config
.permissions
.set_permission_profile(
AppServerPermissionProfile::Managed {
network: PermissionProfileNetworkPermissions { enabled: false },
file_system: PermissionProfileFileSystemPermissions::Unrestricted,
}
.into(),
)
.set_permission_profile(PermissionProfile::Managed {
network: NetworkSandboxPolicy::Restricted,
file_system: ManagedFileSystemPermissions::Unrestricted,
})
.expect("set permission profile");
assert_eq!(