From 0dac67f375793263cdc529c55720b990b6dfad03 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 1 Aug 2025 11:27:02 -0700 Subject: [PATCH] chore: introduce SandboxPolicy::WorkspaceWrite::use_exact_writable_roots Without this change, it is challenging to create integration tests to verify that the folders not included in `writable_roots` in `SandboxPolicy::WorkspaceWrite` are read-only because, by default, `get_writable_roots_with_cwd()` includes `TMPDIR`, which is where most integrationt tests do their work. This introduces a `use_exact_writable_roots` option to disable the default includes returned by `get_writable_roots_with_cwd()`. --- codex-rs/common/src/sandbox_summary.rs | 4 ++++ codex-rs/core/src/config.rs | 2 ++ codex-rs/core/src/protocol.rs | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/codex-rs/common/src/sandbox_summary.rs b/codex-rs/common/src/sandbox_summary.rs index 3d33d92836..a0c6aadfc0 100644 --- a/codex-rs/common/src/sandbox_summary.rs +++ b/codex-rs/common/src/sandbox_summary.rs @@ -7,6 +7,7 @@ pub fn summarize_sandbox_policy(sandbox_policy: &SandboxPolicy) -> String { SandboxPolicy::WorkspaceWrite { writable_roots, network_access, + use_exact_writable_roots, } => { let mut summary = "workspace-write".to_string(); if !writable_roots.is_empty() { @@ -19,6 +20,9 @@ pub fn summarize_sandbox_policy(sandbox_policy: &SandboxPolicy) -> String { .join(", ") )); } + if *use_exact_writable_roots { + summary.push_str(" (exact writable roots)"); + } if *network_access { summary.push_str(" (network access enabled)"); } diff --git a/codex-rs/core/src/config.rs b/codex-rs/core/src/config.rs index a65ec09674..caf6013069 100644 --- a/codex-rs/core/src/config.rs +++ b/codex-rs/core/src/config.rs @@ -350,6 +350,7 @@ impl ConfigToml { Some(s) => SandboxPolicy::WorkspaceWrite { writable_roots: s.writable_roots.clone(), network_access: s.network_access, + use_exact_writable_roots: false, }, None => SandboxPolicy::new_workspace_write_policy(), }, @@ -720,6 +721,7 @@ writable_roots = [ SandboxPolicy::WorkspaceWrite { writable_roots: vec![PathBuf::from("/tmp")], network_access: false, + use_exact_writable_roots: false, }, sandbox_workspace_write_cfg.derive_sandbox_policy(sandbox_mode_override) ); diff --git a/codex-rs/core/src/protocol.rs b/codex-rs/core/src/protocol.rs index bc922eb0e2..db95ad03b5 100644 --- a/codex-rs/core/src/protocol.rs +++ b/codex-rs/core/src/protocol.rs @@ -175,6 +175,10 @@ pub enum SandboxPolicy { /// default. #[serde(default)] network_access: bool, + + /// When set to `true`, will not include defaults like TMPDIR. + /// (Mainly used for testing.) + use_exact_writable_roots: bool, }, } @@ -199,6 +203,7 @@ impl SandboxPolicy { SandboxPolicy::WorkspaceWrite { writable_roots: vec![], network_access: false, + use_exact_writable_roots: false, } } @@ -230,7 +235,15 @@ impl SandboxPolicy { match self { SandboxPolicy::DangerFullAccess => Vec::new(), SandboxPolicy::ReadOnly => Vec::new(), - SandboxPolicy::WorkspaceWrite { writable_roots, .. } => { + SandboxPolicy::WorkspaceWrite { + writable_roots, + use_exact_writable_roots, + .. + } => { + if *use_exact_writable_roots { + return writable_roots.clone(); + } + let mut roots = writable_roots.clone(); roots.push(cwd.to_path_buf());