Derive sandbox contexts from turn environments (#40551)

## What changed

- Add Windows sandbox mode, private-desktop behavior, and legacy Landlock selection to each `EnvironmentConfig`.
- Centralize sandbox context construction on `TurnEnvironment`, preserving environment-owned permissions, paths, and backend settings while applying additional permission grants.
- Use the environment-derived context for project instructions, capability discovery, file uploads, and filesystem-oriented tools.

## Testing

- Verify capability discovery uses the selected environment's permission profile and sandbox backends when they differ from the thread defaults.

GitOrigin-RevId: 7ae2fed90c8ada950f2e8431e571e9b2c793c291
This commit is contained in:
Adam Perry @ OpenAI authored and copyberry committed 2026-08-25 05:16:45 +00:00
1 parent 348f49b292
commit 8444cf63b5
47 files changed
+341 -151

No files matched your search

+1 -17
View File
@@ -18,7 +18,6 @@
use crate::config::Config;
use crate::context::UserInstructions as ContextUserInstructions;
use crate::environment_selection::TurnEnvironmentSnapshot;
use crate::tools::sandboxing::executor_windows_sandbox_level;
use codex_config::ConfigLayerSource;
use codex_config::default_project_root_markers;
use codex_config::merge_toml_values;
@@ -30,7 +29,6 @@ use codex_extension_api::UserInstructions;
use codex_file_system::FileSystemSandboxContext;
use codex_file_system::FindUpErrorPolicy;
use codex_file_system::find_nearest_ancestor_with_markers;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_path_uri::PathUri;
use futures::StreamExt;
@@ -58,7 +56,6 @@ pub(crate) async fn load_project_instructions(
config: &Config,
user_instructions: Option<UserInstructions>,
environments: &TurnEnvironmentSnapshot,
windows_sandbox_level: WindowsSandboxLevel,
) -> io::Result<Option<LoadedAgentsMd>> {
let mut loaded = LoadedAgentsMd::from_user_instructions(user_instructions);
if config.active_project.is_untrusted() {
@@ -76,20 +73,7 @@ pub(crate) async fn load_project_instructions(
.permission_profile()
.file_system_sandbox_policy()
.has_full_disk_read_access())
.then(|| {
// TODO(anp): Move sandbox context construction to a method on TurnEnvironment.
let mut sandbox = FileSystemSandboxContext::from_permission_profile_with_cwd(
turn_environment.permission_profile().clone(),
turn_environment.cwd().clone(),
);
sandbox.workspace_roots = turn_environment.workspace_roots().to_vec();
sandbox.windows_sandbox_level =
executor_windows_sandbox_level(windows_sandbox_level, turn_environment.cwd());
sandbox.windows_sandbox_private_desktop =
config.permissions.windows_sandbox_private_desktop;
sandbox.use_legacy_landlock = config.features.use_legacy_landlock();
sandbox
});
.then(|| turn_environment.sandbox_context(/*additional_permissions*/ None));
match read_agents_md(
config,
filesystem.as_ref(),