Skip to content

[Feature]: Step-level on_failure: hook for recovery gates #2591

@doquanghuy

Description

@doquanghuy

Problem Statement

When a non-gated step fails, Spec Kit aborts the entire run.
There's no step-level hook for "if this step fails, prompt the
operator before tearing down."

For long pipelines (10+ steps with expensive AI calls), a single
transient failure (network blip, quota 429, downstream hiccup)
wastes the previous N steps' work.

Proposed Solution

A step-level lifecycle hook routing failures to a recovery gate:

- id: my-expensive-step
  type: command
  integration: claude
  command: speckit.heavy-thing
  on_failure:
    gate: my-recovery-gate
# pseudo for engine
def execute_step(step):
    try:
        return _run_step(step)
    except StepFailedError as e:
        if step.on_failure and step.on_failure.gate:
            verdict = invoke_gate(step.on_failure.gate, context={
                "failed_step_id": step.id,
                "error": str(e),
                "exit_code": e.exit_code,
            })
            if verdict == "retry": return _run_step(step)
            if verdict == "skip":  return None
        raise

Default (no on_failure: declared) is byte-equivalent to today.
Opt-in per step.

Component

Other

AI Agent (if applicable)

All agents

Acceptance Criteria

  • New optional on_failure: field on step config.
  • When step fails and on_failure.gate is set, the gate is
    invoked with failure context.
  • Verdicts retry, skip, abort honoured; unknown verdict
    re-raises the failure.
  • Default behaviour byte-equivalent.
  • Tests: declared-and-fired, declared-but-step-succeeded,
    undeclared, each verdict path.

Additional Context

Want shape agreement ({ gate: ... } vs. { retry: 1 } vs.
{ switch: ... }) before opening a PR.

AI disclosure: drafted with Claude Opus, human-reviewed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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