From 1551cd68ded1f9400ecc6d2ddefe4e1200e910ab Mon Sep 17 00:00:00 2001 From: jif-oai Date: Wed, 27 May 2026 10:56:12 +0200 Subject: [PATCH] tmp hack (#24577) # External (non-OpenAI) Pull Request Requirements External code contributions are by invitation only. Please read the dedicated "Contributing" markdown file for details: https://github.com/openai/codex/blob/main/docs/contributing.md If your PR conforms to our contribution guidelines, replace this text with a detailed and high quality description of your changes. Include a link to a bug report or enhancement request. --- codex-rs/core/src/config/config_tests.rs | 154 ++++++++++++++++------- codex-rs/core/src/config/mod.rs | 9 +- 2 files changed, 115 insertions(+), 48 deletions(-) diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index c8e597f2ab..53d987e7f0 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -1551,6 +1551,7 @@ async fn default_permissions_profile_populates_runtime_sandbox_policy() -> std:: .await?; let cwd_root = cwd.path().abs(); + let memories_root = codex_home.abs().join("memories"); assert_eq!( config.permissions.file_system_sandbox_policy(), FileSystemSandboxPolicy::restricted(vec![ @@ -1572,12 +1573,18 @@ async fn default_permissions_profile_populates_runtime_sandbox_policy() -> std:: }, access: FileSystemAccessMode::Read, }, + FileSystemSandboxEntry { + path: FileSystemPath::Path { + path: memories_root.clone(), + }, + access: FileSystemAccessMode::Write, + }, ]), ); assert_eq!( &config.legacy_sandbox_policy(), &SandboxPolicy::WorkspaceWrite { - writable_roots: vec![], + writable_roots: vec![memories_root], network_access: false, exclude_tmpdir_env_var: true, exclude_slash_tmp: true, @@ -1839,16 +1846,23 @@ async fn permission_profile_override_keeps_workspace_roots_out_of_legacy_project ) .await?; + let memories_root = codex_home.abs().join("memories"); assert!( config .permissions .file_system_sandbox_policy() .can_write_path_with_cwd(cwd.path(), cwd.path()) ); + assert!( + config + .permissions + .file_system_sandbox_policy() + .can_write_path_with_cwd(memories_root.as_path(), cwd.path()) + ); assert_eq!( &config.legacy_sandbox_policy(), &SandboxPolicy::WorkspaceWrite { - writable_roots: vec![], + writable_roots: vec![memories_root], network_access: false, exclude_tmpdir_env_var: true, exclude_slash_tmp: true, @@ -2743,6 +2757,9 @@ async fn permissions_profiles_allow_direct_write_roots_outside_workspace_root() config.custom_permission_profile_ids, vec!["dev".to_string()] ); + let legacy_memories_root = AbsolutePathBuf::from_absolute_path(std::fs::canonicalize( + codex_home.path().join("memories"), + )?)?; assert!( config .permissions @@ -2752,7 +2769,7 @@ async fn permissions_profiles_allow_direct_write_roots_outside_workspace_root() assert_eq!( &config.legacy_sandbox_policy(), &SandboxPolicy::WorkspaceWrite { - writable_roots: vec![external_write_path], + writable_roots: vec![external_write_path, legacy_memories_root], network_access: false, exclude_tmpdir_env_var: true, exclude_slash_tmp: true, @@ -2813,12 +2830,13 @@ async fn permissions_profiles_reject_nested_entries_for_non_workspace_roots() -> async fn load_workspace_permission_profile( profile: PermissionProfileToml, -) -> std::io::Result { +) -> std::io::Result<(Config, AbsolutePathBuf, AbsolutePathBuf)> { let codex_home = TempDir::new()?; let cwd = TempDir::new()?; std::fs::write(cwd.path().join(".git"), "gitdir: nowhere")?; + let memories_root = codex_home.abs().join("memories"); - Config::load_from_base_config_with_overrides( + let config = Config::load_from_base_config_with_overrides( ConfigToml { default_permissions: Some("dev".to_string()), permissions: Some(PermissionsToml { @@ -2832,42 +2850,59 @@ async fn load_workspace_permission_profile( }, codex_home.abs(), ) - .await + .await?; + let legacy_memories_root = AbsolutePathBuf::from_absolute_path(std::fs::canonicalize( + codex_home.path().join("memories"), + )?)?; + + Ok((config, memories_root, legacy_memories_root)) } #[tokio::test] async fn permissions_profiles_allow_unknown_special_paths() -> std::io::Result<()> { - let config = load_workspace_permission_profile(PermissionProfileToml { - description: None, - extends: None, - workspace_roots: None, - filesystem: Some(FilesystemPermissionsToml { - glob_scan_max_depth: None, - entries: BTreeMap::from([( - ":future_special_path".to_string(), - FilesystemPermissionToml::Access(FileSystemAccessMode::Read), - )]), - }), - network: None, - }) - .await?; + let (config, memories_root, legacy_memories_root) = + load_workspace_permission_profile(PermissionProfileToml { + description: None, + extends: None, + workspace_roots: None, + filesystem: Some(FilesystemPermissionsToml { + glob_scan_max_depth: None, + entries: BTreeMap::from([( + ":future_special_path".to_string(), + FilesystemPermissionToml::Access(FileSystemAccessMode::Read), + )]), + }), + network: None, + }) + .await?; assert_eq!( config.permissions.file_system_sandbox_policy(), - FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { - path: FileSystemPath::Special { - value: FileSystemSpecialPath::unknown( - ":future_special_path", - /*subpath*/ None - ), + FileSystemSandboxPolicy::restricted(vec![ + FileSystemSandboxEntry { + path: FileSystemPath::Special { + value: FileSystemSpecialPath::unknown( + ":future_special_path", + /*subpath*/ None + ), + }, + access: FileSystemAccessMode::Read, }, - access: FileSystemAccessMode::Read, - }]), + FileSystemSandboxEntry { + path: FileSystemPath::Path { + path: memories_root.clone(), + }, + access: FileSystemAccessMode::Write, + }, + ]), ); assert_eq!( &config.legacy_sandbox_policy(), - &SandboxPolicy::ReadOnly { + &SandboxPolicy::WorkspaceWrite { + writable_roots: vec![legacy_memories_root], network_access: false, + exclude_tmpdir_env_var: true, + exclude_slash_tmp: true, } ); assert!( @@ -2883,7 +2918,7 @@ async fn permissions_profiles_allow_unknown_special_paths() -> std::io::Result<( #[tokio::test] async fn permissions_profiles_allow_unknown_special_paths_with_nested_entries() -> std::io::Result<()> { - let config = load_workspace_permission_profile(PermissionProfileToml { + let (config, memories_root, _) = load_workspace_permission_profile(PermissionProfileToml { description: None, extends: None, workspace_roots: None, @@ -2903,12 +2938,23 @@ async fn permissions_profiles_allow_unknown_special_paths_with_nested_entries() assert_eq!( config.permissions.file_system_sandbox_policy(), - FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { - path: FileSystemPath::Special { - value: FileSystemSpecialPath::unknown(":future_special_path", Some("docs".into())), + FileSystemSandboxPolicy::restricted(vec![ + FileSystemSandboxEntry { + path: FileSystemPath::Special { + value: FileSystemSpecialPath::unknown( + ":future_special_path", + Some("docs".into()) + ), + }, + access: FileSystemAccessMode::Read, }, - access: FileSystemAccessMode::Read, - }]), + FileSystemSandboxEntry { + path: FileSystemPath::Path { + path: memories_root, + }, + access: FileSystemAccessMode::Write, + }, + ]), ); assert!( config.startup_warnings.iter().any(|warning| warning.contains( @@ -2922,23 +2968,32 @@ async fn permissions_profiles_allow_unknown_special_paths_with_nested_entries() #[tokio::test] async fn permissions_profiles_allow_missing_filesystem_with_warning() -> std::io::Result<()> { - let config = load_workspace_permission_profile(PermissionProfileToml { - description: None, - extends: None, - workspace_roots: None, - filesystem: None, - network: None, - }) - .await?; + let (config, memories_root, legacy_memories_root) = + load_workspace_permission_profile(PermissionProfileToml { + description: None, + extends: None, + workspace_roots: None, + filesystem: None, + network: None, + }) + .await?; assert_eq!( config.permissions.file_system_sandbox_policy(), - FileSystemSandboxPolicy::restricted(Vec::new()) + FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { + path: FileSystemPath::Path { + path: memories_root.clone(), + }, + access: FileSystemAccessMode::Write, + }]) ); assert_eq!( &config.legacy_sandbox_policy(), - &SandboxPolicy::ReadOnly { + &SandboxPolicy::WorkspaceWrite { + writable_roots: vec![legacy_memories_root], network_access: false, + exclude_tmpdir_env_var: true, + exclude_slash_tmp: true, } ); assert!( @@ -2953,7 +3008,7 @@ async fn permissions_profiles_allow_missing_filesystem_with_warning() -> std::io #[tokio::test] async fn permissions_profiles_allow_empty_filesystem_with_warning() -> std::io::Result<()> { - let config = load_workspace_permission_profile(PermissionProfileToml { + let (config, memories_root, _) = load_workspace_permission_profile(PermissionProfileToml { description: None, extends: None, workspace_roots: None, @@ -2967,7 +3022,12 @@ async fn permissions_profiles_allow_empty_filesystem_with_warning() -> std::io:: assert_eq!( config.permissions.file_system_sandbox_policy(), - FileSystemSandboxPolicy::restricted(Vec::new()) + FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { + path: FileSystemPath::Path { + path: memories_root, + }, + access: FileSystemAccessMode::Write, + }]) ); assert!( config.startup_warnings.iter().any(|warning| warning.contains( diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 1dd2c7097f..fff14a93df 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -2619,6 +2619,8 @@ impl Config { Some(WindowsSandboxModeToml::Unelevated) => WindowsSandboxLevel::RestrictedToken, None => WindowsSandboxLevel::from_features(&features), }; + let memories_root = codex_home.join("memories"); + std::fs::create_dir_all(&memories_root)?; let profiles_are_active = effective_permission_selection.profiles_are_active( default_permissions_override.as_deref(), permission_config_syntax, @@ -3232,11 +3234,12 @@ impl Config { network_requirements, &network_permission_profile, )?; - let helper_readable_roots = get_readable_roots_required_for_codex_runtime( + let mut helper_readable_roots = get_readable_roots_required_for_codex_runtime( &codex_home, zsh_path.as_ref(), main_execve_wrapper_exe.as_ref(), ); + helper_readable_roots.push(memories_root.clone()); let effective_permission_profile = constrained_permission_profile.value.get().clone(); let (mut effective_file_system_sandbox_policy, effective_network_sandbox_policy) = effective_permission_profile.to_runtime_permissions(); @@ -3254,6 +3257,10 @@ impl Config { filesystem_requirements, ); } + effective_file_system_sandbox_policy = effective_file_system_sandbox_policy + .with_additional_legacy_workspace_writable_roots(std::slice::from_ref( + &memories_root, + )); let effective_file_system_sandbox_policy = effective_file_system_sandbox_policy .with_additional_readable_roots(resolved_cwd.as_path(), &helper_readable_roots); let effective_permission_profile = PermissionProfile::from_runtime_permissions_with_enforcement(