Skip to content

fix(errors): honest failure classification + transient auto-retry + stuck/runaway guard #610

Description

@isadeks

Summary

Governing issue for the Stack B agent error-handling work (PR #599, which now also carries the merged #600 stuck-guard). Filed to close the ADR-003 loop — the work references the Linear incidents ABCA-483/659/662 but had no GitHub approved issue on a conforming branch.

Three related failure-diagnosis gaps, all from live incidents:

  1. Misleading terminal reasons. A real subtype=error_max_turns failure read as "Unexpected error"; a build/verify wall-clock kill wasn't distinguished from a crash; TaskDefinition is inactive and the claude-binary Exec format error weren't classified. (ABCA-483)
  2. No retry-semantics axis. Errors had no transient/service/user classification, so nothing could safely auto-retry a genuinely transient fault (an ECS deploy-race session-start) vs. surface a config/auth error immediately.
  3. Spin-to-cap with no signal. An agent that thrashed on a failing operation (e.g. git push → invalid credentials, retried every which way) ran to the max_turns cap with a bare "Exceeded max turns" reason and no indication it had looped. (ABCA-662)

Scope / acceptance criteria

  • Error classifier maps subtype=error_max_turns, build/verify TIMEOUT, TaskDefinition is inactive, and claude Exec format error to precise titles/remedies (specific patterns before the generic catch-all).
  • A transient | service | user ErrorClass axis drives retry semantics; absent ⇒ user (fail-safe: never auto-retry an unknown). The CLI ErrorClassification mirror stays in sync (types-sync gate).
  • session-start auto-retries once on a transient failure only (idempotent — no clone/commit/PR yet); a non-transient failure surfaces immediately. The retry-event emit is best-effort (a telemetry fault can't abort/mis-attribute the retry). Classify the raw error, not a wrapped string.
  • Advisory stuck/runaway guard detects a per-signature identical-failure streak AND a signature-agnostic failure-dominated trailing window, and enriches the max_turns terminal reason with a neutral observation of the repeated failure. Advisory-only (never kills; max_turns is the backstop); must NOT false-trip a healthy iterate-and-fix loop (K10).
  • Behavior-first test coverage for the classifier axes, the 4 retry branches, and the guard boundaries.

Notes

Implementation: #599 (error-classifier + session-start retry) with #600 (stuck-guard) already merged into its branch. Prior art: Linear ABCA-483/659/662. Requesting approved + branch rename to fix/<this-issue>-error-classifier-hardening before merge, per ADR-003. Follow-up test-seam coverage tracked in #608.

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedWhen an issue has been approved and readybugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions