Compare commits

...

2 Commits

Author SHA1 Message Date
Eric Traut
37a429f363 Merge branch 'main' into etraut/nested_apply_patch 2026-04-05 22:43:13 -07:00
Eric Traut
3a1db1cb53 Fix read-only apply_patch rejection message 2026-04-05 22:30:14 -07:00
2 changed files with 46 additions and 7 deletions

View File

@@ -12,6 +12,11 @@ use codex_protocol::protocol::SandboxPolicy;
use codex_sandboxing::SandboxType;
use codex_sandboxing::get_platform_sandbox;
const PATCH_REJECTED_OUTSIDE_PROJECT_REASON: &str =
"writing outside of the project; rejected by user approval settings";
const PATCH_REJECTED_READ_ONLY_REASON: &str =
"writing is blocked by read-only sandbox; rejected by user approval settings";
#[derive(Debug, PartialEq)]
pub enum SafetyCheck {
AutoApprove {
@@ -85,9 +90,7 @@ pub fn assess_patch_safety(
None => {
if rejects_sandbox_approval {
SafetyCheck::Reject {
reason:
"writing outside of the project; rejected by user approval settings"
.to_string(),
reason: patch_rejection_reason(sandbox_policy).to_string(),
}
} else {
SafetyCheck::AskUser
@@ -97,14 +100,22 @@ pub fn assess_patch_safety(
}
} else if rejects_sandbox_approval {
SafetyCheck::Reject {
reason: "writing outside of the project; rejected by user approval settings"
.to_string(),
reason: patch_rejection_reason(sandbox_policy).to_string(),
}
} else {
SafetyCheck::AskUser
}
}
fn patch_rejection_reason(sandbox_policy: &SandboxPolicy) -> &'static str {
match sandbox_policy {
SandboxPolicy::ReadOnly { .. } => PATCH_REJECTED_READ_ONLY_REASON,
SandboxPolicy::WorkspaceWrite { .. }
| SandboxPolicy::DangerFullAccess
| SandboxPolicy::ExternalSandbox { .. } => PATCH_REJECTED_OUTSIDE_PROJECT_REASON,
}
}
fn is_write_patch_constrained_to_writable_paths(
action: &ApplyPatchAction,
file_system_sandbox_policy: &FileSystemSandboxPolicy,

View File

@@ -162,8 +162,36 @@ fn granular_sandbox_approval_false_rejects_out_of_root_patch() {
WindowsSandboxLevel::Disabled,
),
SafetyCheck::Reject {
reason: "writing outside of the project; rejected by user approval settings"
.to_string(),
reason: PATCH_REJECTED_OUTSIDE_PROJECT_REASON.to_string(),
},
);
}
#[test]
fn read_only_policy_rejects_patch_with_read_only_reason() {
let tmp = TempDir::new().unwrap();
let cwd = tmp.path().to_path_buf();
let action = ApplyPatchAction::new_add_for_test(&cwd.join("inside.txt"), "".to_string());
let sandbox_policy = SandboxPolicy::new_read_only_policy();
let file_system_sandbox_policy =
FileSystemSandboxPolicy::from_legacy_sandbox_policy(&sandbox_policy, &cwd);
assert!(!is_write_patch_constrained_to_writable_paths(
&action,
&file_system_sandbox_policy,
&cwd,
));
assert_eq!(
assess_patch_safety(
&action,
AskForApproval::Never,
&sandbox_policy,
&file_system_sandbox_policy,
&cwd,
WindowsSandboxLevel::Disabled,
),
SafetyCheck::Reject {
reason: PATCH_REJECTED_READ_ONLY_REASON.to_string(),
},
);
}