Skip to content

feat(cli-sub-agent): emit --fork-from recovery hint on sandbox fs denial (#685)#963

Merged
RyderFreeman4Logos merged 1 commit intomainfrom
fix/685-fork-from-recovery-hint
Apr 20, 2026
Merged

feat(cli-sub-agent): emit --fork-from recovery hint on sandbox fs denial (#685)#963
RyderFreeman4Logos merged 1 commit intomainfrom
fix/685-fork-from-recovery-hint

Conversation

@RyderFreeman4Logos
Copy link
Copy Markdown
Owner

Summary

  • 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.
  • 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.
Followup tracked in #962 (gate hint on fs-sandbox-active telemetry).

Test plan

  • cargo test -p cli-sub-agent sandbox_fs_denial_hint
  • cargo test -p cli-sub-agent error_hints
  • cargo test --workspace
  • just pre-commit

🤖 Generated with Claude Code

…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>
@RyderFreeman4Logos
Copy link
Copy Markdown
Owner Author

Local pre-PR cumulative review (csa review --range main...HEAD, tier-4-critical, session 01KPNW9TZSRW58Q1J7TZ47977S):

  • reviewer 2 (codex): 1 MEDIUM finding (R2-001, security.false-positive-sandbox-recovery-hint, CWE-440). findings.toml: 1 medium, 0 critical/high/low/info.
  • reviewer 1 (gemini-cli): (not captured — likely UNCERTAIN).
  • Overall risk: medium.

The MEDIUM finding

sandbox_fs_denial_hint() only does string matching and is called unconditionally from pipeline_session_exec and run_cmd_execute. The new recovery hint should only fire when CSA actually enabled filesystem sandboxing and the denial plausibly came from that sandbox.

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 --extra-writable. No automatic privilege change; only user-facing recommendation text. But the recommendation could normalize broader writable-path grants for plain host perm failures.

Decision

Per 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 sandbox_info / filesystem_mode into hint generation, suppress when sandboxing off, regression test).

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.

@RyderFreeman4Logos RyderFreeman4Logos merged commit 333c9c0 into main Apr 20, 2026
6 of 7 checks passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +130 to +134
let suggested = Path::new(&path)
.parent()
.filter(|parent| !parent.as_os_str().is_empty())
.map(|parent| parent.display().to_string())
.unwrap_or(path);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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 ..

Suggested change
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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

csa run: emit --fork-from recovery hint when sandbox blocks filesystem write

1 participant