feat(cli-sub-agent): emit --fork-from recovery hint on sandbox fs denial (#685)#963
Conversation
…ial (#685) When a csa run session fails with a filesystem sandbox denial pattern (Read-only file system, Permission denied, Operation not permitted, EACCES/EPERM/Errno 13/Errno 30), emit a hint pointing the caller at `csa run --fork-from <SID> --extra-writable <parent> --prompt-file <continuation>` so the partial work (discovery, reads, setup) done before the denial is preserved instead of lost on re-dispatch. Best-effort parses the denied path out of standard OSError/PermissionError line shapes and suggests its parent as --extra-writable; falls back to a generic placeholder when no path is recoverable. Closes #685. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Local pre-PR cumulative review (csa review --range main...HEAD, tier-4-critical, session 01KPNW9TZSRW58Q1J7TZ47977S):
The MEDIUM finding
Triggering case: a non-zero run whose stdout/stderr contains "Permission denied" or "Read-only file system" markers — even if fs sandboxing was not enabled — gets told to retry with DecisionPer severity-tiered merge protocol (feedback_review_severity_tiered): only HIGH/CRITICAL/P1 block merge; MEDIUMs aggregate into followup issue + merge. Filed followup #962 for fs-sandbox-active gate with concrete fix direction (thread Merging as-is. The core value of the PR (recovery guidance for the common OOM-like sandbox case) is preserved; the false-positive narrowing is a follow-up improvement without blocking the rescue path. |
There was a problem hiding this comment.
Code Review
This pull request bumps the project version to 0.1.448 and introduces a diagnostic hint system for sandbox filesystem denial errors. When a command fails due to permission or read-only filesystem issues, the system now attempts to parse the denied path and suggest a continuation command using the --extra-writable flag. Feedback was provided regarding the path suggestion logic, specifically that relative paths consisting only of a filename should suggest the current directory ('.') as the writable path rather than the filename itself.
| let suggested = Path::new(&path) | ||
| .parent() | ||
| .filter(|parent| !parent.as_os_str().is_empty()) | ||
| .map(|parent| parent.display().to_string()) | ||
| .unwrap_or(path); |
There was a problem hiding this comment.
The current logic for determining the suggested writable path doesn't correctly handle relative paths without a directory component (e.g., a bare filename like output.txt). In such cases, Path::parent() returns Some(""), which is then filtered out, causing the fallback to the original path. This results in an incorrect suggestion like --extra-writable output.txt instead of --extra-writable ..
To fix this, we can adjust the logic to explicitly handle an empty parent path and replace it with ..
| let suggested = Path::new(&path) | |
| .parent() | |
| .filter(|parent| !parent.as_os_str().is_empty()) | |
| .map(|parent| parent.display().to_string()) | |
| .unwrap_or(path); | |
| let suggested = Path::new(&path) | |
| .parent() | |
| .map(|p| p.display().to_string()) | |
| .map(|s| if s.is_empty() { ".".to_string() } else { s }) | |
| .unwrap_or(path); |
Summary
csa runsession fails with a filesystem sandbox denial pattern (Read-only file system, Permission denied, Operation not permitted, EACCES/EPERM/Errno 13/Errno 30), emit a hint pointing the caller atcsa run --fork-from <SID> --extra-writable <parent> --prompt-file <continuation>so the partial work (discovery, reads, setup) done before the denial is preserved.--extra-writable; falls back to a generic placeholder when no path is recoverable.Closes #685.
Followup tracked in #962 (gate hint on fs-sandbox-active telemetry).
Test plan
cargo test -p cli-sub-agent sandbox_fs_denial_hintcargo test -p cli-sub-agent error_hintscargo test --workspacejust pre-commit🤖 Generated with Claude Code