Skip to content

feat(tools): shell exit-code taxonomy and FailureKind integration#2226

Merged
bug-ops merged 1 commit intomainfrom
l-icl-tool-error-correction
Mar 27, 2026
Merged

feat(tools): shell exit-code taxonomy and FailureKind integration#2226
bug-ops merged 1 commit intomainfrom
l-icl-tool-error-correction

Conversation

@bug-ops
Copy link
Copy Markdown
Owner

@bug-ops bug-ops commented Mar 27, 2026

Summary

Complements #2214 (ToolErrorCategory + ToolErrorFeedback) with two gaps that remained after that PR:

  • Shell executor exit-code classification: ShellExecutor now returns ToolError::Shell { exit_code, category, message } for well-known failure modes instead of embedding errors in the output string. Flows through existing ToolErrorFeedback.format_for_llm() injection in native.rs.
  • Skill evolution integration: From<ToolErrorCategory> for FailureKind maps the taxonomy to skill evolution signals, replacing the string heuristic for classified tool failures.

Changes

  • crates/zeph-tools/src/executor.rs: ToolError::Shell { exit_code, category, message } variant; category() delegates to stored category
  • crates/zeph-tools/src/shell/mod.rs: classify_shell_exit() function; emit_completed() helper; execute_block returns Err(ToolError::Shell) for exit 126/127 and stderr patterns
  • crates/zeph-skills/src/evolution.rs: From<ToolErrorCategory> for FailureKind — PolicyBlocked/ConfirmationRequired/ToolNotFound → WrongApproach, InvalidParameters/TypeMismatch → SyntaxError, Timeout → Timeout, infrastructure → Unknown

Shell exit classifications

Condition Category
exit 126 (not executable) PolicyBlocked
exit 127 (command not found) PermanentFailure
stderr: "permission denied" (any case) PolicyBlocked
stderr: "no such file or directory" (any case) PermanentFailure
any other non-zero exit output returned as-is (unchanged behavior)

Test plan

  • 6687/6687 tests pass (--features full)
  • cargo +nightly fmt --check clean
  • cargo clippy clean on changed crates
  • classify_shell_exit: exit 126, 127, stderr patterns, exit 0 → None, generic exit 1 → None
  • ToolError::Shell.category(): PolicyBlocked, PermanentFailure, not quality failure
  • From<ToolErrorCategory> for FailureKind: all 11 variants tested

Closes #2207, closes #2206.

@github-actions github-actions bot added documentation Improvements or additions to documentation skills zeph-skills crate rust Rust code changes core zeph-core crate enhancement New feature or request size/XL Extra large PR (500+ lines) labels Mar 27, 2026
@bug-ops bug-ops force-pushed the l-icl-tool-error-correction branch from a73a147 to 8adeeb9 Compare March 27, 2026 09:28
@github-actions github-actions bot added size/L Large PR (201-500 lines) and removed core zeph-core crate size/XL Extra large PR (500+ lines) labels Mar 27, 2026
@bug-ops bug-ops changed the title feat(reliability): L-ICL localized error correction and fault taxonomy feat(tools): shell exit-code taxonomy and FailureKind integration Mar 27, 2026
@bug-ops bug-ops enabled auto-merge (squash) March 27, 2026 09:28
, #2206)

Complements #2214 (ToolErrorCategory + ToolErrorFeedback) with two gaps that
remained after that PR:

**Shell executor exit-code classification**
ShellExecutor now returns `ToolError::Shell { exit_code, category, message }`
for well-known failure modes instead of embedding errors in the output string:
- exit 126 (permission denied) → ToolErrorCategory::PolicyBlocked
- exit 127 (command not found) → ToolErrorCategory::PermanentFailure
- stderr containing "permission denied" → PolicyBlocked
- stderr containing "no such file or directory" → PermanentFailure

These errors flow through the existing `ToolErrorFeedback.format_for_llm()`
injection in native.rs, producing structured `[tool_error]` blocks for the LLM.

**Skill evolution FailureKind integration**
`From<ToolErrorCategory> for FailureKind` maps the taxonomy to skill evolution
signals: PolicyBlocked/ConfirmationRequired/ToolNotFound → WrongApproach,
InvalidParameters/TypeMismatch → SyntaxError, Timeout → Timeout, infrastructure
errors (RateLimited, ServerError, NetworkError, PermanentFailure, Cancelled) →
Unknown. Eliminates string heuristic for classified tool failures.

Closes #2207, closes #2206.
@bug-ops bug-ops force-pushed the l-icl-tool-error-correction branch from 8adeeb9 to e051c9d Compare March 27, 2026 09:33
@bug-ops bug-ops merged commit 1913d63 into main Mar 27, 2026
25 checks passed
@bug-ops bug-ops deleted the l-icl-tool-error-correction branch March 27, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request rust Rust code changes size/L Large PR (201-500 lines) skills zeph-skills crate

Projects

None yet

1 participant