Skip to content

docs: reborn error recoverability audit + remediation plan - #5383

Merged
serrrfirat merged 1 commit into
mainfrom
claude/focused-spence-43f6c8
Jul 4, 2026
Merged

serrrfirat merged 1 commit into
mainfrom
claude/focused-spence-43f6c8

Conversation

@serrrfirat

Copy link
Copy Markdown
Collaborator

What

A findings + remediation-plan document (no code changes) mapping every reborn-binary run error to recoverable vs run-borking, analyzing what PR #4841 already covers, and laying out the path to the agreed two-bucket end state: a security-related error stops the run, otherwise everything is user-explainable or retriable.

Doc: docs/plans/2026-06-28-reborn-error-recoverability-audit.md. Builds on docs/plans/2026-06-12-reborn-no-borking-failures.md / PR #4841.

Highlights

  • The error spine — the host_runtime disposition layer (capability_failure_disposition) intends that no capability failure ever aborts (only ModelVisibleToolError / RetrySameCall), yet the recovery strategy aborts on the Permanent class.
  • Keystone defect — Dispatcher / InvalidOutput / Unknown are dispositioned recoverable by host_runtime but mapped to Permanent → Abort by capability_error_class. Since UnknownCapability/UnknownProvider → InvalidOutput, "the model called a nonexistent tool" currently kills the run instead of becoming a model-visible tool error. Re-bucketing that class is the single highest-leverage fix.
  • Confirmed handler defects — outbound_delivery maps every service error to a terminal Err and interpolates target_id into a safe_summary; the sandbox-plan path turns bad model input into a terminal InvalidInvocation; approval-lease expiry hard-borks.
  • reborn: no run-borking failures — failure explanation + retryable failed runs #4841 coverage + gaps — it delivers the explainable + retryable backbone, but retry is user-initiated only (no auto re-drive), checkpoint-gated (no from-input retry for early failures), and doesn't touch provider fidelity (rig/bedrock auth, Codex truncation) or detached bg-processes.
  • Target architecture — three lanes (SecurityStop | Retriable | Explainable) + one exhaustive-match classifier, with sequencing and an enforcement test.

Status

Discovery is complete for the core spine and the synthetic/local_dev handler scope. Two sweeps remain (flagged in §6.4): host_runtime/dispatcher variant-by-variant, and the tool-backend/extension layer. Two product decisions are open (§8): side-effect retry for no-checkpoint runs, and whether pre-run/ingress failures join the same taxonomy.

Opening as draft for discussion — this is a plan, not an implementation.

🤖 Generated with Claude Code

Maps every reborn run error to recoverable / run-borking, analyzes PR
#4841 coverage, and lays out the path to the two-bucket end state
(SecurityStop | Retriable | Explainable). Headline finding: the
host_runtime disposition layer intends no capability failure to abort,
but the recovery strategy aborts on Dispatcher/InvalidOutput/Unknown —
re-bucketing that class makes "model called a nonexistent tool" and
malformed-output failures recoverable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 27, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 29ef4f38-6707-4d5f-bc0a-f2a2a6063759

📥 Commits

Reviewing files that changed from the base of the PR and between 4c82051 and 72b2feb.

📒 Files selected for processing (1)
  • docs/plans/2026-06-28-reborn-error-recoverability-audit.md

📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added a detailed audit and remediation plan for error recoverability, including the current error classification map and recovery categories.
    • Summarized which failure cases are already covered, which remain gaps, and where retries still depend on user action or checkpoint availability.
    • Outlined a target path for consolidating failures into clearer handling lanes, along with key open decisions and rollout sequencing.

Walkthrough

Adds a new planning document, docs/plans/2026-06-28-reborn-error-recoverability-audit.md, auditing the reborn agent-loop's error classification and recoverability. Documents current error spine, PR #4841 coverage gaps, defect findings, target three-lane architecture, open decisions, and a code-location appendix. No code changes.

Changes

Reborn Error Recoverability Audit Plan

Layer / File(s) Summary
Intro and error spine
docs/plans/2026-06-28-reborn-error-recoverability-audit.md
Documents goals, locked decisions, and the existing loop-exit/executor error classification with the two-layer tool-failure disposition model.
Coverage and gap assessment
docs/plans/2026-06-28-reborn-error-recoverability-audit.md
Assesses PR #4841 coverage per failure case and identifies retriability gaps (checkpoint gating, codex truncation detection).
Defect hunt and target architecture
docs/plans/2026-06-28-reborn-error-recoverability-audit.md
Lists disposition/classification contradictions and handler/provider defects, then proposes a three-lane (SecurityStop/Retriable/Explainable) architecture with fix sequencing and enforcement tests.
Open decisions and appendix
docs/plans/2026-06-28-reborn-error-recoverability-audit.md
Enumerates open decisions and lists key code locations relevant to each concern.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related issues

Review note: Documentation-only change (+240/-0, one file). No code, no exported/public entity changes, nothing to gate against sandbox/trust/secrets/egress/migration invariants — nothing for clippy/rustfmt/cargo-deny/check_no_panics to catch here either. Recommend confirming referenced code-location appendix (§ code locations) still matches current file/module paths before merging, since stale pointers in an audit doc silently rot.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5383 June 27, 2026 21:52 Destroyed
@github-actions github-actions Bot added scope: docs Documentation size: XS < 10 changed lines (excluding docs) risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jun 27, 2026

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

Copy link
Copy Markdown
Contributor

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 introduces a comprehensive audit and remediation plan for the Reborn Error Recoverability initiative, detailing error classification, identifying gaps, and outlining a target architecture to route failures into three distinct lanes (SecurityStop, Retriable, and Explainable). The review feedback suggests correcting a variable name in a documented code snippet and advises using length-prefixed encoding with domain-separated digests when designing deterministic identifiers for the RunFailureReason taxonomy.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.


### Building blocks (dependency order)

1. **`RunFailureReason` taxonomy** — wire-stable, user-facing, distinct from internal `LoopFailureKind`; carries `{lane, retry_policy, user_message, correlation_id}`. (#4841's `FailureExplanationProvider` + `safe_summary` category is most of this.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

When designing the wire-stable RunFailureReason taxonomy or generating any deterministic identifiers/hashes from multiple string components (such as combining lane, retry_policy, user_message, and correlation_id), please ensure you use an injective length-prefixed encoding combined with a domain-separated collision-resistant digest rather than simple concatenation with a delimiter. This eliminates the risk of separator-collision attacks or accidental collisions.

References
  1. Derive deterministic identifiers from multiple components using length-prefixed components combined with a domain-separated collision-resistant digest, rather than raw string concatenation, to prevent accidental or malicious collisions.

| Site | Condition | Current | Fix |
|---|---|---|---|
| `crates/ironclaw_reborn_composition/src/runtime/local_dev/outbound_delivery.rs:108,213` (via `outbound_delivery_host_error`, :575) | model picks bad/nonexistent `target_id` (InvalidRequest/NotFound), forbidden, conflict, rate-limited, transient-unavailable | maps **all** `RebornServicesErrorCode` → `Err` → terminal | mirror `project_service_outcome`: InvalidRequest/NotFound→`Failed{InvalidInput}`; Unauthenticated/Forbidden→`Denied`; Conflict→`Failed{OperationFailed}`; RateLimited→`Failed{Resource}`; Unavailable→`Failed{Unavailable}`; only Internal→`Err` |
| `outbound_delivery.rs:223` | model-supplied `target_id` interpolated into `safe_summary` | `format!("set delivery target to {target_id}")` — a delimiter in the id trips validation → terminal | fixed host-authored string; id travels in `output` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

There is a minor typo in the documented code snippet. In crates/ironclaw_reborn_composition/src/runtime/local_dev/outbound_delivery.rs:223, the actual variable interpolated is target_summary rather than target_id.

Suggested change
| `outbound_delivery.rs:223` | model-supplied `target_id` interpolated into `safe_summary` | `format!("set delivery target to {target_id}")` — a delimiter in the id trips validation → terminal | fixed host-authored string; id travels in `output` |
| outbound_delivery.rs:223 | model-supplied target_id interpolated into safe_summary | format!("set delivery target to {target_summary}") — a delimiter in the id trips validation → terminal | fixed host-authored string; id travels in output |

@railway-app

railway-app Bot commented Jun 27, 2026

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-5383 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jun 27, 2026 at 9:52 pm

@serrrfirat
serrrfirat marked this pull request as ready for review July 4, 2026 20:20
@serrrfirat
serrrfirat merged commit 28c3e94 into main Jul 4, 2026
31 of 32 checks passed
@serrrfirat
serrrfirat deleted the claude/focused-spence-43f6c8 branch July 4, 2026 20:20

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-5383 — 72b2feb0 Deployed Jun 27, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules scope: docs Documentation size: XS < 10 changed lines (excluding docs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant