mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Skip missing paths in filesystem sandbox entries (#34598)
## Why Default read-only protections for project metadata should apply when paths such as `.git`, `.agents`, and `.codex` exist, without causing sandbox setup to materialize missing paths as ACL targets. ## What changed - Add an optional `missing_path_behavior` to filesystem sandbox entries and mark default project-metadata protections with `skip`. - Preserve the behavior through permission transforms and exec/MCP protocol serialization while keeping existing path wire variants stable. - Ignore skip-missing entries when projecting configuration or Windows sandbox overrides, while retaining explicit metadata carveouts. ## Testing - Cover protocol round trips for path and special-path entries. - Verify default metadata protections and Windows explicit carveout handling. GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
This commit is contained in:
@@ -148,6 +148,7 @@ mod tests {
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_utils_path_uri::LegacyAppPathString;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::Value;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -192,6 +193,62 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sandbox_state_serializes_skip_missing_entries_as_missing_path_behavior() {
|
||||
let sandbox_cwd = PathUri::from_host_native_path(
|
||||
std::env::current_dir().expect("current directory should be available"),
|
||||
)
|
||||
.expect("current directory should convert to a URI");
|
||||
let sandbox_state = SandboxState {
|
||||
permission_profile: PermissionProfile::workspace_write(),
|
||||
codex_linux_sandbox_exe: None,
|
||||
sandbox_cwd,
|
||||
use_legacy_landlock: false,
|
||||
};
|
||||
|
||||
let serialized = serde_json::to_value(&sandbox_state).expect("serialize sandbox state");
|
||||
let serialized_text = serde_json::to_string(&serialized).expect("serialize JSON text");
|
||||
assert!(
|
||||
!serialized_text.contains("generated_default_path"),
|
||||
"MCP sandbox metadata must preserve FileSystemPath's stable wire variants"
|
||||
);
|
||||
assert!(
|
||||
!serialized_text.contains("generated_default_special"),
|
||||
"MCP sandbox metadata must preserve FileSystemPath's stable wire variants"
|
||||
);
|
||||
|
||||
let entries = serialized
|
||||
.pointer("/permissionProfile/file_system/entries")
|
||||
.and_then(Value::as_array)
|
||||
.expect("workspace-write profile should contain filesystem entries");
|
||||
let skip_missing_entries = entries
|
||||
.iter()
|
||||
.filter(|entry| {
|
||||
entry.get("missing_path_behavior").and_then(Value::as_str) == Some("skip")
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(
|
||||
!skip_missing_entries.is_empty(),
|
||||
"skip-missing entries should be represented as optional missing_path_behavior"
|
||||
);
|
||||
assert!(
|
||||
skip_missing_entries.iter().all(|entry| {
|
||||
matches!(
|
||||
entry.pointer("/path/type").and_then(Value::as_str),
|
||||
Some("path" | "special")
|
||||
)
|
||||
}),
|
||||
"skip-missing entries should use the stable path/special variants"
|
||||
);
|
||||
|
||||
let deserialized: SandboxState =
|
||||
serde_json::from_value(serialized).expect("deserialize sandbox state");
|
||||
assert_eq!(
|
||||
deserialized.permission_profile,
|
||||
sandbox_state.permission_profile
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_stdio_requires_local_stdio_availability() {
|
||||
let runtime_context = McpRuntimeContext::new(
|
||||
|
||||
Reference in New Issue
Block a user