By Sagar Shankaran, Founder of CallSphere
Learn how to build AI-powered systems that automatically detect, diagnose, and fix code issues. Covers CI/CD integration, automated test repair, dependency updates, and real-world self-healing architecture patterns.
Key takeaways
A self-healing codebase is a software system that uses AI agents to automatically detect failures, diagnose root causes, generate fixes, and submit them for review with minimal human intervention. Unlike traditional automated remediation (restart on crash, circuit breakers, retry logic), self-healing with AI agents operates at the source code level. The agent reads the broken code, understands the failure, and writes a patch.
This is not science fiction. Teams at companies like GitHub (Copilot Workspace), Anthropic (Claude Code), and several YC startups are already shipping early versions of this pattern. The core insight is that modern LLMs are surprisingly good at the specific task of "given a failing test and the relevant code, produce a fix that makes the test pass."
The self-healing pipeline has four stages, each handled by a different component.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent for IT support in your browser — 60 seconds, no signup.
flowchart LR
PR(["PR opened"])
UNIT["Unit tests"]
EVAL["Eval harness<br/>PromptFoo or Braintrust"]
GOLD[("Golden set<br/>200 tagged cases")]
JUDGE["LLM as judge<br/>plus regex graders"]
SCORE["Aggregate score<br/>and per slice"]
GATE{"Score regress<br/>more than 2 percent?"}
BLOCK(["Block merge"])
MERGE(["Merge to main"])
PR --> UNIT --> EVAL --> GOLD --> JUDGE --> SCORE --> GATE
GATE -->|Yes| BLOCK
GATE -->|No| MERGE
style EVAL fill:#4f46e5,stroke:#4338ca,color:#fff
style GATE fill:#f59e0b,stroke:#d97706,color:#1f2937
style BLOCK fill:#dc2626,stroke:#b91c1c,color:#fff
style MERGE fill:#059669,stroke:#047857,color:#fff
The pipeline starts with your existing CI/CD system. When a build fails, a test breaks, or a linter reports an error, the failure event triggers the healing agent.
# .github/workflows/self-heal.yml
name: Self-Healing Pipeline
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
heal:
if: github.event.workflow_run.conclusion == 'failure'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
- name: Extract failure logs
id: logs
run: |
gh run view ${{ github.event.workflow_run.id }} --log-failed > failure_logs.txt
echo "logs_path=failure_logs.txt" >> "$GITHUB_OUTPUT"
- name: Run healing agent
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: python scripts/heal_agent.py --logs ${{ steps.logs.outputs.logs_path }}
The diagnosis agent reads the failure logs and identifies what went wrong. This is where the AI adds the most value compared to traditional pattern matching.
import anthropic
import json
client = anthropic.Anthropic()
def diagnose_failure(failure_logs: str, relevant_files: dict[str, str]) -> dict:
"""Diagnose the root cause of a CI failure."""
file_context = "\n".join(
f"--- {path} ---\n{content}" for path, content in relevant_files.items()
)
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
messages=[{
"role": "user",
"content": f"""Analyze this CI failure and identify the root cause.
## Failure Logs
{failure_logs}
## Relevant Source Files
{file_context}
Respond with JSON:
{{
"root_cause": "concise description of what went wrong",
"failure_type": "test_failure|build_error|lint_error|type_error|dependency_issue",
"affected_files": ["list of files that need changes"],
"confidence": 0.0-1.0,
"reasoning": "step-by-step analysis of how you reached this conclusion"
}}"""
}]
)
return json.loads(response.content[0].text)
Once the diagnosis is complete, a separate agent generates the fix. Separating diagnosis from fix generation improves accuracy because each agent focuses on one task.
def generate_fix(diagnosis: dict, files: dict[str, str]) -> list[dict]:
"""Generate code fixes based on the diagnosis."""
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8096,
messages=[{
"role": "user",
"content": f"""Generate a minimal fix for the following issue.
## Diagnosis
Root cause: {diagnosis["root_cause"]}
Type: {diagnosis["failure_type"]}
Affected files: {diagnosis["affected_files"]}
Reasoning: {diagnosis["reasoning"]}
## Current File Contents
{chr(10).join(f'--- {p} ---{chr(10)}{c}' for p, c in files.items())}
Rules:
1. Make the MINIMAL change needed to fix the issue
2. Do not refactor unrelated code
3. Preserve existing code style and conventions
4. If the fix requires adding imports, include them
Respond with JSON array of edits:
[{{
"file": "path/to/file",
"old_text": "exact text to replace",
"new_text": "replacement text"
}}]"""
}]
)
return json.loads(response.content[0].text)
The fix is applied locally, the failing tests are re-run, and if they pass, a pull request is automatically created.
Still reading? Stop comparing — try CallSphere live.
See the IT support AI agent handle a real call — complete, industry-specific, and live in your browser. No signup.
import subprocess
def validate_and_submit(edits: list[dict], branch_name: str) -> str:
"""Apply edits, run tests, and create a PR if tests pass."""
# Apply edits
for edit in edits:
path = edit["file"]
with open(path, "r") as f:
content = f.read()
content = content.replace(edit["old_text"], edit["new_text"])
with open(path, "w") as f:
f.write(content)
# Run the specific failing tests
result = subprocess.run(
["pytest", "--tb=short", "-x"],
capture_output=True, text=True, timeout=300
)
if result.returncode != 0:
raise FixValidationError(f"Fix did not resolve failure: {result.stdout}")
# Create PR
subprocess.run(["git", "checkout", "-b", branch_name])
subprocess.run(["git", "add", "-A"])
subprocess.run(["git", "commit", "-m", f"fix: auto-heal CI failure"])
subprocess.run(["git", "push", "origin", branch_name])
pr_result = subprocess.run(
["gh", "pr", "create",
"--title", "fix: Auto-heal CI failure",
"--body", "This PR was automatically generated by the self-healing pipeline.",
"--label", "auto-heal"],
capture_output=True, text=True
)
return pr_result.stdout.strip()
Self-healing without guardrails is dangerous. Every auto-generated fix must pass through safety checks.
SAFETY_RULES = {
"max_files_changed": 3,
"max_lines_changed": 50,
"forbidden_paths": [
"migrations/",
".env",
"secrets/",
"auth/",
"payment/"
],
"require_test_pass": True,
"require_human_review": True,
"max_retries": 2,
"confidence_threshold": 0.7
}
def check_safety(edits: list[dict], diagnosis: dict) -> bool:
"""Validate that proposed fix meets safety guardrails."""
if diagnosis["confidence"] < SAFETY_RULES["confidence_threshold"]:
return False
if len(edits) > SAFETY_RULES["max_files_changed"]:
return False
total_lines = sum(
len(e["new_text"].splitlines()) + len(e["old_text"].splitlines())
for e in edits
)
if total_lines > SAFETY_RULES["max_lines_changed"]:
return False
for edit in edits:
for forbidden in SAFETY_RULES["forbidden_paths"]:
if edit["file"].startswith(forbidden):
return False
return True
Once your self-healing pipeline is running, track these metrics to measure its effectiveness:
Teams running self-healing pipelines in production typically see 40-60% of routine CI failures resolved automatically within 5-15 minutes, compared to 2-8 hours for manual human resolution. The key is starting with the easy categories (type errors, import fixes, linter violations) and gradually expanding scope as you build confidence in the system.
Self-healing codebases are not about replacing developers. They are about eliminating the toil of fixing routine, mechanical failures so developers can focus on the creative work that actually requires human judgment. The architecture is straightforward: detect failures from CI, diagnose with an AI agent, generate minimal fixes, validate with tests, and submit for human review. Start with the easy wins, enforce strict safety guardrails, and expand gradually.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
See how Circini's automated incident management pipeline turns alert emails into triaged Jira tickets using Snowflake Cortex AI, GPT-4.1, Airflow & MS Teams.
A founder's guide to the personal AI assistant market: best AI assistant apps, business-grade options, and how CallSphere's voice agent fits in.
A founder's guide to free AI agents, low-code AI agent builders, and how to know when you should pay for a real platform like CallSphere.
Graphiti is the open-source temporal knowledge graph for AI agents in 2026. Learn how bi-temporal memory beats vector RAG for voice agents and long-running LLMs.
Chatbot app vs ChatGPT in 2026: a founder's clear take on the difference, when to use which, and how a real AI chatbot app development works.
How we built a fault-tolerant HVAC emergency triage and tech-dispatch platform on Kubernetes — three-tier CQRS, 11 micro-agents on the OpenAI Agents SDK + LangGraph, NATS JetStream, DTMF/SMS/WebSocket acceptance, circuit breakers, and an evaluation pipeline that catches regressions before they wake a tech at 3 AM.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI