Pattern Matrix/White Paper/F4

F4 · Self-Heal Loop

Coordinate Reflection × Loop (cyclic)
Cost Medium (each repair adds a few extra calls, but saves the engineering time spent on manual triage)
Pattern group Reflection patterns
Summary When a deterministic failure signal fires, the agent automatically diagnoses, repairs, verifies, and loops until convergence or a circuit break.

The problem it solves

Failing tests, lint errors, broken builds, a red CI run—these deterministic failure signals are the most valuable feedback an agent can receive, because they are unambiguously right or wrong and do not depend on subjective judgment. But having an engineer manually triage and manually fix every failure is heavy, repetitive work, and many failures have formulaic fixes (a missing dependency, a misplaced configuration, an obvious logic error). Having a human fix those is wasteful.

Self-Heal Loop lets the agent absorb these signals and close the repair loop automatically: a failure signal fires → diagnose the root cause → generate a fix → apply it → re-verify, and run another round if it is not fixed. It is the form of reflection closest to "agent autonomy," and it is the only mandatory loop in the reflection module—once a fix fails, another round is required, and there is no legitimate form called a "single-pass self-heal." Aider exposes it as a command-line flag, Spotify Honk runs it at production scale (650+ merged AI PRs per month), and GitHub Copilot Rubber Duck builds it as cross-model dual-review.

Why the coordinate is "Reflection × Loop"

  • Vertical axis · Reflection: the agent detects its own errors and repairs them. Self-repair is the most practical application of the reflection mechanism, and it is especially common in software. It does not improve an output that already works; it recovers from a state that is already broken—the agent reads the failure signal, understands it, diagnoses it, and corrects it, and the whole process is a review and correction of its own output.
  • Horizontal axis · Loop: the structure is a forced cycle of detect failure → diagnose → repair → re-test. This loop is structural and mandatory, unlike the optional replay of Generator-Critic—the starting point is "the output is already broken," the loop is the means of recovery, another iteration is required if it is not fixed, and the termination conditions are tests passing, max_iterations bottoming out, or a detected regression triggering a rollback.

Core mechanism

A production-grade Self-Heal Loop is built from a six-stage pipeline plus a triple stop mechanism. The pipeline: Test Fail → Diagnose → Generate Fix → Critic → Atomic Apply → Verify, and when verification fails, git revert returns to Diagnose to redo the work.

The triple stop mechanism is what upgrades Generator-Critic into Self-Heal; drop any one of them and you risk "breaking the main branch":

  1. max_iterations hard circuit break: the loop runs at most a few rounds (Aider uses 3). This prevents the agent from playing whack-a-mole indefinitely.
  2. dual-model critic verifier: use a reviewer from a different model family to review the fix. LLMs from the same family share blind spots; cross-family review introduces the perspective of an independent training history and breaks self-bias. GitHub Copilot Rubber Duck forces cross-model verification at three risk nodes (after the plan, after implementation, and after writing tests but before running them).
  3. stability check via signature: compare failure signatures to distinguish "fixed the same problem" (hash repeats) from "switched to a new problem," and perform regression detection (a severity escalation or a doubling of affected files counts as a regression and rolls everything back).

Spotify Honk's four-tier cascade of format/lint/build/test is worth copying outright—run the cheap signals first to filter out obvious problems, and reserve the expensive signals for genuinely semantic-level issues.

Production scenarios it fits

  • Domains where right and wrong are clear, such as code / tests / CI: auto-fixing CI failures, auto-fixing lint, auto-diagnosing and repairing test failures. This is the main battleground for Self-Heal, because there is a deterministic ground truth.
  • A standard capability for coding agents: Aider, Spotify Honk, and GitHub Copilot all treat it as a default feature; it is infrastructure for coding agents.
  • Engineering pipelines with a clearly layered ground-truth signal: a CI with a clean format/lint/build/test layering is what suits self-heal. The more distinct the signals, the more reliable the repair.

Where it tends to go wrong

  • Forcing it where there is no deterministic failure signal: subjective judgments such as writing and design have no objective right-or-wrong signal, so use Generator-Critic (F1) rather than Self-Heal. Tasks where the cost of repair exceeds the cost of failure (changing the schema of a production database) belong in the governance module's Approval Gate with human review.
  • Whack-a-mole: without a stability check, the agent fixes one error and introduces a new one, and after a few rounds the code is a mess. The defense is to run failure-signature comparison, regression detection, and max_iterations together as three layers.
  • Regression cascade: when each round's fix is not an atomic commit, a string of cascading changes leaves the rollback unable to restore the correct state. The defense is per-iteration atomic commits plus the strict constraint "modify only files in the diagnosis."
  • False recovery: the agent changes the test instead of the code, weakening the test so it passes—every metric is green and every problem remains. The defense is for the critic to explicitly review whether "production code or the test was changed," plus a rule that test coverage may not drop.
  • Bottoming out without handing off to a human: "crash if it can't be fixed" is an unacceptable engineering practice. HITL handoff must be a first-class citizen: bottoming out hands off to human review, and the queue needs someone clearing it daily.

Key metrics

  • Self-heal success rate (healthy range 60-80%): the proportion of repairs that succeed automatically, with the rest handed off to humans. Spotify Honk runs around 70% with the triple stop in place. Below 50% means the ground-truth signal is unclear or the diagnostic capability is insufficient.
  • Average repair rounds (healthy range ≤3 rounds): if it has not converged after more than 3 rounds, a dev-tool scenario should hand off to a human; only production scale can support more rounds.
  • Regression rate (healthy range <10%): the proportion of repairs that introduce a new failure. A high rate means the stability check or atomic commit is missing.
  • HITL queue clear-out latency (healthy range cleared the same day): how long it takes for someone to handle a case after bottoming out hands it off. A backlog means the organizational ops path is not in place.

Minimal implementation skeleton

for i in range(MAX_ITERATIONS):           # MAX=3, same as Aider
                diagnosis = diagnose(current_failure)
                fix = generate_fix(diagnosis)         # modify only files in the diagnosis
                critique = cross_family_critic(fix)   # different vendor, breaks self-bias
                if critique.block:
                    return "blocked_by_critic"        # hand off to HITL
                commit = atomic_apply(fix)            # per-iteration atomic commit
                new_failure = verify()                # format/lint/build/test four-tier cascade
                if new_failure is None:
                    return "fixed"
                if is_regression(current_failure, new_failure):   # severity up / files doubled
                    rollback(all applied commits)
                    return "rolled_back_regression"
                current_failure = new_failure
            return "max_iterations_human_handoff"     # bottomed out, hand off to human review
            

Four engineering points: the dual-model critic should use cross-family, not the same family at a different size; regression-detection rules are defined by the business (you can add performance, security, and coverage regressions); atomic commits must be truly atomic—do not change 5 files at once, or the rollback will not return; and bottoming out must actually have someone watching the HITL queue.

Enterprise deployment example

A DevTool company built a CI/CD auto-repair agent. The first version was aggressive—any failure was fixed automatically, up to 10 iterations, with no critic, no rollback, and no stability check. In the second week there was an incident: a test failed → the agent changed the code → it failed again but with a different error → it changed it again → after 9 changes it had rewritten unrelated code throughout, the main branch was a mess, and the rollback could not restore the correct state because the 9 commits were not atomic. The post-mortem found three root causes: no stability check (it was playing whack-a-mole), no critic verification (the agent applied whatever it claimed it had fixed), and no git audit trail. The third version was rewritten from scratch with the triple stop mechanism—a max-iterations hard circuit break, a dual-model critic (Sonnet writes, GPT-5.4 reviews, cross-family), and a stability check via signature comparison. Verification runs the format/lint/build/test four-tier cascade, each round is an atomic commit for precise rollback, and bottoming out hands off to a HITL human review of the PR. After the rework, main-branch incidents dropped to zero, the self-heal success rate was 70% (the remaining 30% handed off to humans), and the cost was that a single repair's latency rose from about 30 seconds to about 90 seconds—in a financial scenario, this much latency is a worthwhile trade for accuracy.

Relationship to other patterns

  • Generator-Critic (F1): a sibling pattern whose boundary must be nailed down. Generator-Critic is "improve after generation"—the chain is a linear pipeline, replay is optional, and the starting point is a usable output; Self-Heal Loop is "repair after failure"—the loop is a mandatory structure, and the starting point is a broken output. This distinction makes their stop conditions, rollback, and blast radius all different. The former is for subjective tasks, the latter for tasks with a deterministic failure signal.
  • Adversarial Review (collaboration module): the cross-family critic connects here. Rubber Duck's dual-model review is a lightweight version of this idea, and Adversarial Review pushes it to the extreme (multi-agent debate).
  • Iterative Hypothesis (reasoning module): the same Loop lineage; both are an iterative "try—verify—try again" structure.
  • Guardrail Sandwich (action module): the same sandbox lineage. Honk runs the agent in an isolated container with restricted permissions, compressing the blast radius from "production wide open" to "wide open inside the sandbox."

What this pattern teaches

Self-Heal Loop is not simply auto-fixing code; it defines the boundary of agent autonomy—in domains where it can self-heal (a deterministic ground truth exists) the agent can work independently, and in domains where it cannot (an irreversible blast radius) a human must step in. This line is exactly the same lineage as DevOps's decades-long judgment of "what can be automated and what must be human-reviewed."


This page is part of the ADPS pattern white papers. Back to the pattern matrix, or see the runnable code catalog.