core: keep session permission profiles symbolic

This commit is contained in:
pakrym-oai
2026-07-09 19:39:43 -07:00
parent 6e417ed780
commit 7e95377bc5
3 changed files with 24 additions and 70 deletions
+14 -11
View File
@@ -116,19 +116,19 @@ impl SessionConfiguration {
&self.environments.environments
}
pub(super) fn workspace_roots(&self) -> Vec<AbsolutePathBuf> {
pub(super) fn primary_workspace_roots(&self) -> Vec<AbsolutePathBuf> {
self.environments
.environments
.first()
.and_then(|environment| {
.map(|environment| {
environment
.workspace_roots
.iter()
.map(PathUri::to_abs_path)
.collect::<std::io::Result<Vec<_>>>()
.ok()
.unwrap_or_default()
})
.unwrap_or_else(|| vec![self.cwd().clone()])
.unwrap_or_default()
}
pub(crate) fn codex_home(&self) -> &AbsolutePathBuf {
@@ -140,10 +140,12 @@ impl SessionConfiguration {
}
pub(super) fn permission_profile(&self) -> PermissionProfile {
self.permission_profile_state
.permission_profile()
.clone()
.materialize_project_roots_with_workspace_roots(&self.workspace_roots())
self.permission_profile_state.permission_profile().clone()
}
fn materialized_permission_profile(&self) -> PermissionProfile {
self.permission_profile()
.materialize_project_roots_with_workspace_roots(&self.primary_workspace_roots())
}
pub(super) fn active_permission_profile(&self) -> Option<ActivePermissionProfile> {
@@ -171,7 +173,7 @@ impl SessionConfiguration {
}
pub(super) fn sandbox_policy(&self) -> SandboxPolicy {
let permission_profile = self.permission_profile();
let permission_profile = self.materialized_permission_profile();
codex_sandboxing::compatibility_sandbox_policy_for_permission_profile(
&permission_profile,
self.cwd(),
@@ -179,7 +181,8 @@ impl SessionConfiguration {
}
pub(super) fn file_system_sandbox_policy(&self) -> FileSystemSandboxPolicy {
self.permission_profile().file_system_sandbox_policy()
self.materialized_permission_profile()
.file_system_sandbox_policy()
}
pub(super) fn network_sandbox_policy(&self) -> NetworkSandboxPolicy {
@@ -198,7 +201,7 @@ impl SessionConfiguration {
permission_profile: self.permission_profile(),
active_permission_profile: self.active_permission_profile(),
environments: self.environments.clone(),
workspace_roots: self.workspace_roots(),
workspace_roots: self.primary_workspace_roots(),
profile_workspace_roots: self.profile_workspace_roots().to_vec(),
ephemeral: self.original_config_do_not_use.ephemeral,
reasoning_effort: self.collaboration_mode.reasoning_effort(),
+8 -57
View File
@@ -4502,7 +4502,9 @@ async fn session_configuration_apply_preserves_profile_file_system_policy_on_cwd
)
.expect("set permission profile");
let expected_file_system_sandbox_policy = file_system_sandbox_policy
.materialize_project_roots_with_workspace_roots(&session_configuration.workspace_roots());
.materialize_project_roots_with_workspace_roots(
&session_configuration.primary_workspace_roots(),
);
let updated = session_configuration
.apply(&SessionSettingsUpdate {
@@ -4564,7 +4566,9 @@ async fn session_configuration_apply_permission_profile_preserves_existing_deny_
.expect("permission profile update should succeed");
let mut expected_file_system_policy = requested_file_system_policy
.materialize_project_roots_with_workspace_roots(&session_configuration.workspace_roots());
.materialize_project_roots_with_workspace_roots(
&session_configuration.primary_workspace_roots(),
);
expected_file_system_policy.glob_scan_max_depth = Some(2);
expected_file_system_policy.entries.push(deny_entry);
assert_eq!(
@@ -4821,59 +4825,6 @@ enabled = false
);
}
#[tokio::test]
async fn session_configuration_apply_retargets_legacy_workspace_root_on_cwd_update() {
let mut session_configuration = make_session_configuration_for_tests().await;
let workspace = tempfile::tempdir().expect("create temp dir");
let original_cwd = workspace.path().join("repo-a").abs();
let project_root = workspace.path().join("repo-b").abs();
session_configuration.environments =
TurnEnvironmentSelections::new(original_cwd.clone(), Vec::new());
let sandbox_policy = SandboxPolicy::WorkspaceWrite {
writable_roots: Vec::new(),
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_sandbox_policy = FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(
&sandbox_policy,
session_configuration.cwd(),
);
session_configuration
.set_permission_profile_for_tests(
PermissionProfile::from_runtime_permissions_with_enforcement(
SandboxEnforcement::from_legacy_sandbox_policy(&sandbox_policy),
&file_system_sandbox_policy,
NetworkSandboxPolicy::from(&sandbox_policy),
),
)
.expect("set permission profile");
let updated = session_configuration
.apply(&SessionSettingsUpdate {
environments: Some(TurnEnvironmentSelections::new(
project_root.clone(),
Vec::new(),
)),
..Default::default()
})
.expect("cwd-only update should succeed");
assert_eq!(updated.workspace_roots(), vec![project_root.clone()]);
assert!(
updated
.file_system_sandbox_policy()
.can_write_path_with_cwd(project_root.as_path(), updated.cwd().as_path()),
"cwd-only update should keep the new cwd writable"
);
assert!(
!updated
.file_system_sandbox_policy()
.can_write_path_with_cwd(original_cwd.as_path(), updated.cwd().as_path()),
"cwd-only update should not keep the old implicit cwd writable"
);
}
#[tokio::test]
async fn session_configuration_apply_preserves_absolute_cwd_write_root_on_cwd_update() {
let mut session_configuration = make_session_configuration_for_tests().await;
@@ -5275,7 +5226,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
let per_turn_config = Session::build_per_turn_config(
&session_configuration,
session_configuration.cwd().clone(),
session_configuration.workspace_roots(),
session_configuration.primary_workspace_roots(),
);
let model_info = construct_model_info_offline_for_tests(
session_configuration.collaboration_mode.model(),
@@ -7409,7 +7360,7 @@ where
let per_turn_config = Session::build_per_turn_config(
&session_configuration,
session_configuration.cwd().clone(),
session_configuration.workspace_roots(),
session_configuration.primary_workspace_roots(),
);
let model_info = construct_model_info_offline_for_tests(
session_configuration.collaboration_mode.model(),
+2 -2
View File
@@ -471,7 +471,7 @@ impl Session {
pub(crate) fn build_effective_session_config(
session_configuration: &SessionConfiguration,
) -> Config {
let workspace_roots = session_configuration.workspace_roots();
let workspace_roots = session_configuration.primary_workspace_roots();
let mut config = Self::build_per_turn_config(
session_configuration,
session_configuration.cwd().clone(),
@@ -718,7 +718,7 @@ impl Session {
.transpose()
.ok()
.flatten()
.unwrap_or_else(|| session_configuration.workspace_roots());
.unwrap_or_default();
let per_turn_config =
Self::build_per_turn_config(&session_configuration, cwd.clone(), workspace_roots);
{