SwarmSystem · Operator's Manual · Self-Healing Software

At 9:31 this morning, our dashboard fixed itself.

A crash alert fired. An AI read the stack traces and found one root cause behind six failing screens. It wrote the exact fix. A second AI tried to tear that fix apart, and failed. Then the full test suite voted. Only after every gate passed did the commit land, with an undo command attached. No human touched any of it. This page shows you how the whole system works, and how to build it into your own stack. Guardrails first.

6
crash groups closed by one fix
from our production log, July 14, 2026
3,020+
recorded errors behind those six groups
same log, same morning
1
commit, applied and pushed by the loop
with a revert command attached
0
human touches, end to end
reviewer and test suite gated it
Reference stack Sentry · Claude Code · git The pattern ports to any tracker and any agent CLI Written July 2026, from a running system
WAITING
What this is

Software that files its own fix. With the safety built first.

Self-healing here means one specific thing. When your system crashes, a loop detects it, diagnoses it, proposes an exact code fix, reviews that fix adversarially, runs your full test suite against it, and then either commits it with a complete audit trail or rolls it back to a clean tree. You choose how much of that runs unattended. The cage below is what makes that choice safe.

Detect Triage Propose Review Execute

Who this is for

You run an error tracker. We use Sentry; any tracker with an issues API works. You have a git repo with a test suite you actually trust. You can invoke an LLM agent from the command line with an enforceable tool whitelist. We use Claude Code; the pattern is agent-agnostic. And you have Slack, or any channel your team actually reads. If any of those are missing, build them first. This page will still be here.

How to read this page

Two registers. The main text teaches the pattern, which ports to any stack. Boxes like this one show our reference implementation: real numbers from our running system, so you can see one working instance. Our numbers are outputs of our environment. Tune yours.

WAITING
Part one · Guardrails

Build the cage before the animal.

Most people ask what the AI can fix. The better first question is: what stops a bad fix from shipping? Every unattended commit this system makes must pass through all twenty-one of these. Skip one and you are not running this system. You are running a slot machine with push access.

The twenty-one guardrails: each rule and the failure it prevents
GuardrailThe ruleThe failure it prevents
Full-suite gateEvery proposed diff runs your entire test suite before commit. Not a subset.A fix that quietly breaks three other things.
Exact-diff-only writesThe only thing that can touch the repo is a reviewed, machine-materialized git diff."The agent improvised" is not in this system's vocabulary.
Read-only proposerThe diagnosing agent gets read tools only. Enforced by whitelist, not by prompt.A helpful agent editing files mid-diagnosis.
Independent reviewerA second, fresh agent tries to refute every proposal. Any error in review counts as a fail.One model grading its own homework.
Two-strike breakerTwo consecutive failed or rejected proposals pause the whole loop until a human unpauses it.A bad day becoming a bad week.
Per-issue cooldownOne attempt per issue per 24 hours.The loop hammering the same wall all night.
Daily budgetAt most 5 proposals a day, one undecided at a time.Volume replacing judgment.
Regression watchdogAn auto-healed issue that returns within 7 days strikes the breaker.Declaring victory on a symptom.
Kill switchesIndependent flags shut down each layer. Remove the tracker key and everything is off.Needing a deploy to stop the machine.
Notify-with-revertEvery unattended commit posts to your channel with the exact revert command.Hunting through docs during an incident.
Audit lineageEvery transition writes an audit line. Every commit names its approver and the issues it resolves.Archaeology instead of history.
Perimeter ratchetA conformance suite derives coverage from the source: every scheduler heartbeats, every store is registered, every remediation is real. New code that skips coverage turns the suite red.Coverage that erodes one new module at a time.
Severity ringThe executor inspects every diff's file paths. Anything touching money, clients, secrets, or deploy code demotes to a human click, at any trust tier. A conformance test keeps the protected list from rotting.A "low-risk" label on a high-stakes file.
Grounded gatingAutonomy refuses to act when its own instruments are stale, blind, or unreadable. The human click path stays open.Confident action on out-of-date sight.
Baseline agingA pre-existing red test file is tolerated for 7 days, then it blocks unattended heals until a human fixes it. Going green resets the clock.An emergency posture becoming a way of life.
Recurrence-to-testThe second heal of the same issue must pin a regression test, or it demotes to a human click.False lessons compounding quietly.
Crash budgetMore than 5 new error classes in a rolling 7 days drops the loop to propose-only for the rest of the window. Diagnosis keeps flowing.Unattended patching during a storm that needs a human.
Escalation nagAn undecided proposal nags the channel at 48 hours, then daily. It runs even in fully manual mode. So does a paused loop: benched is a state someone hears about, not a state that goes quiet.Proposals rotting in a queue nobody reopens.
Blocked-fix ceilingAn approved fix blocked on a busy working tree retries itself when the tree clears and nags daily while it waits. Past seven days it never silently applies. It asks again.A week-old decision executing itself at 3am.
Red-team drillQuarterly, plant fixes the loop MUST refuse: a money-path diff, a protected-file diff, a wrong diagnosis, a poisoned signal. Every gate has to fire, on the record, against isolated state.A refusal gate that has never refused anything.
Surface admission examA new system joins the loop only by filling in a surface contract (scope, protected paths, test command, autonomy tier) and passing the red-team drill against that exact contract.Copy-pasting the healer somewhere it has not earned.
Your preflightWAITING

Tick what is true today. The dot resolves when you are actually ready, not when you feel ready.

0 of 10All ten, or stay at Level 1
When to stop at Level 1

Some stacks should not run this yet.

Your test suite is slow enough that you batch runs instead of running on every change. Or it is flaky, and a gate that lies is worse than no gate. Or coverage is thin exactly where the crashes happen. Or nobody reads the alert channel on weekends.

None of these are permanent. All of them are disqualifying today. A propose-only loop is still worth running while you fix them.

WAITING
Part two · Architecture

One real crash, walked through every gate.

Here is the morning of July 14 in slow motion. Six screens in our dashboard had been crashing for weeks, with six different error signatures. Every one traced to the same seam: a fetch wrapper that let a degraded server answer "success" with no data attached. Watch that one bug travel the whole loop.

01 · DetectDONE

The tracker catches every crash and groups them by signature. Three things make this layer trustworthy rather than noisy. Scrubbing: a before-send hook strips user data from every event, and session replay stays off. The scrubber is load-bearing; give it a regression test. Release stamping: every event carries version plus git sha, so "which commit broke this" is a lookup, not a hunt. Signal hygiene: security denials and expected noise stay in local audit logs. The tracker gets crashes only. Scheduled jobs post check-ins, so silence is itself an alert.

Reference

Our security layer once flooded the tracker with junk issue groups minted from routine denials. One mirror-filter regex ended the burn. Fix the generator, not the instances.

02 · TriageDONE

A poller pulls unresolved issues every 5 minutes, ranks them by event volume and recency, and renders a queue in our dashboard. The cache is stale-while-error: an API failure never wipes what you knew, it only marks it stale. Every issue deep-links back to the tracker. The queue is where a human, or later the loop itself, decides what gets attention.

03 · ProposeDONE

A read-only agent gets the stack traces and one instruction that matters more than the rest: cluster stack-similar issues to one root cause. Six signatures, one seam, one proposal that names all six. The agent cannot write. Its whitelist has read tools only, so "read-only" is enforced by the runtime, not by the prompt. Its output is verbatim find-and-replace edits, never a diff. The server materializes those edits into a canonical git diff and restores the tree byte-for-byte.

Reference

Our first live proposal covered all six issues in one diff: two hunks, one file, at the shared fetch seam. Risk: low. The clustering instruction is why one morning closed six groups.

04 · ReviewDONE

A second agent, fresh context, one job: try to refute the proposal. It reads the diff and every crash site, and hunts for the case where the fix makes things worse. It answers in line format, because a one-token verdict cannot be broken by a long string. And it fails closed: a parse error, a timeout, or an unreadable answer all count as a fail. Nothing ships on a mumble.

The verdict, as our reviewer wrote it (condensed)
VERDICT: pass
CONCERN: one endpoint still returns a bare object instead of the standard envelope
CONCERN: callers that relied on the malformed shape will now see a clean failure
REASONING: the guard normalizes bad GET envelopes to the standard error shape,
which every crash site already handles.

The reviewer passed our fix and still raised real concerns. One became a tracked task. A reviewer that only says yes is decoration.

05 · ExecuteLIVE

The executor is the only thing in the entire system that can write. It runs a fixed chain of gates. Passing every gate earns a commit. Failing any gate lands in the same place: a clean tree, nothing committed, the evidence kept.

  1. 1 · Preflight
    Are the diff's target files clean? A teammate editing the same file means wait, not strike.
    pass ↓fail ↳ wait
  2. 2 · Apply
    git apply the materialized diff. A diff that no longer applies stops here, tree untouched.
    pass ↓fail ↳ rollback
  3. 3 · Full suite
    Every test. Not the fast ones. Not the related ones. All of them.
    green ↓red ↳ gates 4 and 5
  4. 4 · Flake check
    A failing file re-runs alone, with the diff still applied. Passing alone means a contention flake, tolerated within a small bound.
    flake ↓real red ↳ gate 5
  5. 5 · Baseline check
    Is the suite red without the diff too? Then the main branch is broken, not the fix. Wait, do not blame the proposal.
    ours ↓baseline red ↳ wait
  6. 6 · Commit
    Lineage trailers: who approved, which issues this resolves, the heal id.
  7. 7 · Push + resolve
    Issues resolve in the tracker with the sha attached. A regression rule reopens them loudly if the crash returns.
  8. 8 · Notify
    The channel gets the summary and the exact undo command. You are never more than one paste away from reversing it.
    done
The commit, as it landed (identifiers generalized)
heal: guard the GET envelope at the shared fetch seam
      (resolves APP-9, APP-8, APP-A, APP-7, APP-B, APP-1P) [via error-queue]

Approved-By: heal-reviewer (auto, operator tier: low)
Heal-Id: fe3c740e
Sentry-Issue: https://yourorg.sentry.io/issues/APP-9/

The best thing this system did all week was refuse to ship.

Every FAIL branch ends in a clean tree, not a hopeful one

What the loop said that day

9:31 AMRegression alert. A previously resolved crash came back. Queue updated, watchdog noted.
laterProposal ready. One fix, six issues. Risk: low. Diff and diagnosis attached. Waiting on review.
+1 minReview: PASS with 3 concerns. Handing to the executor.
+5 minHealed. Full suite green. Committed, pushed, six issues resolved. Undo: git revert dc52e1d

Condensed from our alerts channel, July 14, 2026. Relative times shown where the exact minute is not in the log.

WAITING
Part three · Implementation

Four levels. Earn each one.

Do not build this in a weekend and flip everything on. Each level below is a complete, useful system on its own. Each ends with a gate you must witness in your own repo before moving up. The autonomy is not the achievement. The gates are.

Level 0 · Watch: detect and triage

needs: TRACKER_DSN

Wire the tracker with a scrubber and release stamping. Set two alert rules: first-seen and regression, both into your channel. Add check-ins to every scheduled job, so a job that silently stops running becomes an alert instead of a mystery. Then build the poller and the ranked queue.

poller.js · a shape, not a library
const EVERY = 5 * 60 * 1000;                      // 5 minutes
setInterval(async () => {
  try {
    const issues = await tracker.listIssues({ status: 'unresolved' });
    const ranked = issues
      .map(i => ({ ...i, score: i.events / Math.max(1, hoursSince(i.lastSeen)) }))
      .sort((a, b) => b.score - a.score);
    cache.write({ issues: ranked, fetchedAt: Date.now() });
  } catch (err) {
    cache.markStale(err.message);                 // stale-while-error: never wipe what you knew
  }
}, EVERY);
scrub.js · the before-send hook is load-bearing
tracker.init({
  dsn: process.env.TRACKER_DSN,                   // unset = the whole integration is off
  sendDefaultPii: false,
  release: `app@${VERSION}+${gitShortSha()}`,     // "which commit broke this" is a lookup
  beforeSend(event) { return scrubUserData(event); }  // give this a regression test
});
The gate out of L0

Throw a deliberate error in production code. It must reach your channel in under a minute, scrubbed of user data, stamped with a release. Skip nothing until this works.

Level 1 · Diagnose: propose-only

adds: HEAL_LOOP=on

Spawn a read-only agent against your ranked queue. Give it the stack traces, the repo, and the clustering instruction. Store its proposals in a queue with the cooldowns from the cage. Nothing writes anything yet. You read the diagnoses and apply the good ones by hand.

propose.js · read-only is a runtime property
const proposal = await agent.run({
  tools: ['Read', 'Grep', 'Glob'],                // no Write, no Bash: it cannot touch the repo
  cwd: REPO_ROOT,
  prompt: buildPrompt(issueCluster),              // traces + "cluster to ONE root cause"
  timeoutMs: 15 * 60 * 1000,
});
// output contract, strictly validated:
// { summary, risk, resolvesIssues: [...], edits: [{ file, find, replace }], testPlan }
const diff = materializeDiff(proposal.edits);     // server-side, below
materialize.js · agents never write diffs
function materializeDiff(edits) {
  assertInsideRepo(edits.map(e => e.file));       // refuse absolute paths and ".." segments
  const before = snapshotBytes(edits);            // exact bytes, for the restore
  try {
    for (const e of edits) applyExactlyOnce(e);   // find must match verbatim, exactly once
    return git('diff');                           // git writes the canonical, appliable diff
  } finally {
    restoreBytes(before);                         // the repo is untouched after this returns
  }
}
The gate out of L1

Run it for a week minimum. Apply at least one proposed diff by hand, after verifying the diagnosis yourself. If the diagnoses are wrong, stay here. Wrong at L1 costs reading time. Wrong at L3 costs a bad commit.

Level 2 · Approve: human-gated commits

adds: AUTO_APPROVE=off · breaker + budgets live

Build the executor with the full gate chain from the loop section. Add an approve and reject control on an exact diff view, with a double-confirm. The breaker, cooldown, and daily budget go live here. Every approval is a named human. Every transition writes an audit line.

execute.js · the gate order, exactly
async function applyProposal(p) {
  if (dirtyTargets(p.diff))   return wait('someone is editing these files');
  if (!gitApply(p.diff))      return fail('diff no longer applies');    // tree untouched
  const suite = runFullSuite();
  if (!suite.green) {
    if (isolatedPass(suite.redFiles, { withDiff: true }))
      { /* contention flake, tolerated within a small bound */ }
    else if (!baselineGreen()) { rollback(); return wait('main is red without this diff'); }
    else                       { rollback(); return fail('the diff broke the suite'); }
  }
  const sha = commit(p, { trailers: lineage(p) }); // Approved-By, issue links, heal id
  push(); resolveIssues(p.resolvesIssues, sha);
  notify(`Healed. ${sha}. Undo: git revert ${sha}`);
  return ok(sha);
}
The gate out of L2

You have personally watched one red suite roll back to a clean tree with nothing committed. Trigger it on purpose with a deliberately bad edit if you must. Do not proceed on faith.

Level 3 · Unattend: reviewer-gated auto, low-risk only

adds: AUTO_APPROVE=low · regression watchdog

Add the adversarial reviewer between proposal and executor. The chain becomes: propose, review, and only a reviewer PASS on a low-risk proposal reaches the executor unattended. Medium and high risk still wait for a human click. The 7-day regression watchdog arms on every auto-healed issue. Every auto-commit posts notify-with-revert.

review.js · fail closed, parse by line
const text     = await freshAgent.run({ tools: ['Read','Grep','Glob'], prompt: refutePrompt(p) });
const verdict  = /^\s*VERDICT:\s*(pass|fail)\b/im.exec(text)?.[1];
const concerns = [...text.matchAll(/^\s*CONCERN:\s*(.+)$/gim)].map(m => m[1]);
if (!verdict) return { pass: false, error: 'unparseable review' };   // fail closed
return { pass: verdict === 'pass', concerns };
Reference

We ran the manual path first. Four things failed on our first live day, and each one became a permanent gate (see the museum below). Only after that, and an explicit operator decision, did we set AUTO_APPROVE=low. Never start at "all".

The gate into L3

Two clean weeks at L2, plus the ladder contract in the governance section signed by whoever owns the repo. Then flip to low, not all. Revisit the tier after a week of unattended heals.

Separate appendix, separate switch: runtime actions (kick a wedged job, reload a config, clear a stale lock) run behind their own flag, off by default. Run supervised dry-runs before trusting it: ours caught an action that reported success while doing nothing (see the museum). Prefer firing a fresh, instrumented run of the job over restarting infrastructure, keep a 24 hour cooldown per action, and never point any of it at anything that moves money.

WAITING
Part four · Evidence

Nine failures we keep on display.

Every guardrail on this page exists because something real broke. The first four broke on our first live day. Three more arrived over the two days after, each in a place the first four could not reach. The last two never got the chance to break anything: we found them on purpose, by unplugging the system and timing the silence. Each is now a permanent part of the system. Steal the lessons without paying for them.

July 14, 2026 · first manual approval

The corrupt patch

The first approved fix died at the apply gate: "corrupt patch at line 25." The agent had hand-written a unified diff and got the arithmetic wrong. Nothing shipped; the rollback held. Agents now output verbatim find-and-replace edits, and git itself writes the diff.

What it built: exact-diff-only writes

July 14, 2026 · first auto review

The verdict that broke JSON

The reviewer returned its verdict as JSON, and one long explanation string arrived unterminated. The parse failed, and fail-closed held: no commit. Verdicts moved to line format, where a one-token answer cannot be broken by a long sentence.

What it built: the fail-closed reviewer

July 14, 2026 · mid-morning

The flake that killed a good fix

A reviewer-passed heal was rejected because one unrelated test file goes red under parallel load. It had done the same thing earlier that day, without any diff. The executor now re-runs red files in isolation with the diff applied. Genuine reds still roll back.

What it built: flake discipline inside the suite gate

July 14, 2026 · same afternoon

The red that wasn't ours

A teammate's commit turned the main branch red while a heal was in flight. The loop blamed the proposal and burned a strike on someone else's bug. Now it checks the baseline: a suite that is red without the diff means wait, not strike.

What it built: baseline awareness

July 15, 2026 · the day after going public

The day the loop went blind

The dashboard went behind a public tunnel, and bot noise turned one routine security event into thousands of tracker events a day. The error quota drained, and the tracker started rate-limiting real crashes at ingest. The loop looked green on every check while new crashes fell on the floor. Proven during a drill: the planted event never arrived.

What it built: a per-class throttle on every telemetry mirror, and a BLIND state the status page shows loudly

July 15, 2026 · watchdog review

The regression that wasn't

The watchdog struck the breaker on an auto-healed issue that "came back." It had not come back. The resolve call to the tracker had silently failed, leaving the issue open with zero new events. The fix was two rules: resolve calls verify and retry, and the watchdog only strikes on new events after the heal, never on an open flag.

What it built: a watchdog that counts events, not labels

July 16, 2026 · supervised dry-run

The heal that did nothing

The runtime-remediation layer shipped off by default, pending dry-runs. The dry-runs found why they exist: its restart action checked that a function existed, returned a success message, and acted on nothing. Flipped on in production, it would have logged "healed" forever while healing nothing. Remediations now do the thing itself, and a test asserts every action resolves to something real.

What it built: dry-runs as a mandatory gate, and the perimeter ratchet

July 16, 2026 · first blackout drill

The impostor heartbeat

We killed the dashboard on purpose to time the alarm. No alarm came. A forgotten second instance, started weeks earlier on a different port for an audit, was still running every scheduled job: checking in the "alive" monitor for a process that was dead, and double-posting the morning brief. Schedulers now arm only on the canonical port. Any other instance serves pages and stays dark, and says so in its log.

What it built: one-instance scheduling, and the blackout drill itself

July 16, 2026 · same drill

The miss nobody heard

The tracker had recorded twenty consecutive missed check-ins on one monitor and told no one. That monitor's issue had been marked resolved, and every alert rule watched for new or returning issues, never for misses on a closed one. A dedicated rule now fires on every monitor-failure event, resolved or not. Re-timed after both fixes: process killed to miss declared in under ten minutes.

What it built: alert on the event class, not the issue state

WAITING
Part five · Keeping it true

A loop you can watch working.

A self-healing system invites a special kind of rot: everything looks green because nothing is checking. We added these four habits after the loop was already "done," because done and provable turned out to be different claims. They are what let this page say "confirmed" instead of "configured."

The wiring pageLIVE

Build one status page where every claim binds to a live check. Each node of the loop, from ingest to commit, is colored by a real probe of the real thing: the token exists, the poller ticked, the alert rules are enabled, the queue store reads, the fleet of scheduled jobs has actually checked in. A node with nothing live to show is drawn in a neutral color and says so. It never pretends to be green. And give the verdict one state beyond live, stale, paused, and down: BLIND, for when the tracker is rate-limiting new events while accepting none. A loop that cannot see new crashes passes every other check while missing the only one that matters.

Reference

Ours runs fourteen checks behind one page. The two silent failure modes it watches hardest: a scheduler that has never checked in (silence never trips a staleness alarm, so absence itself is the signal, with a grace window of twice the job's own period), and a per-machine store that never got registered for auditing.

The fire drillDONE

Quarterly, plant a harmless defect in a sacrificial file, commit it, and fire one real event. Then stand back and watch the whole chain earn its keep: the alert, the proposal, the adversarial review, the full suite, the commit with the revert command attached, the issue resolved. One button, owner-only. It refuses politely on a 24 hour cooldown, an in-flight heal, or a closed storm guard, because a drill that weakens a guard costs more than it proves. A safety system you have never watched fire is a rumor.

Reference

Our first full drill ran July 15: planted defect to healed commit, end to end, no human past the button. The drill checklist on the wiring page derives entirely from evidence that already exists, git history and the live queue, so it cannot drift from reality.

The red-team drillDONE

The fire drill proves the loop can heal. The red-team drill proves it can refuse: plant fixes the loop must reject, and verify every gate fires. A diff that touches a money screen. A diff that touches a protected security file. A diagnosis the evidence contradicts. A poisoned signal feed. Each one must be turned away at the specific gate built to catch it, on the record, against isolated state so the drill's own rejections never trip the live breaker. The result is a receipt, not a claim: a running check on the proof page that reads REFUSED 4 of 4, with a date. When that receipt is stale or missing, the check goes amber on its own. This same exam is how a new surface earns the loop: fill in its contract, pass the drill against it, and only then does the healer watch it. A guardrail you have never seen refuse something is a memory, not a guarantee.

Reference

Our first run refused all four, including the reviewer catching that a planted "fix" did not contain the guard its diagnosis claimed. Designing the drill found two ring gaps before it ever ran: money-facing frontend files and the security chokepoint chain were unprotected. The exam paid for itself before the first question.

The blackout drillDONE

The fire drill proves the loop can heal. The blackout drill proves the alarms can fire: kill the process on purpose, and time how long until something tells you. The whole monitoring stack rests on one assumption, that silence gets noticed, and that assumption is exactly the thing no green dashboard can prove. Ours failed its first blackout twice, in ways no amount of watching the healthy system would have found: an impostor instance keeping the heartbeat alive, and a tracker swallowing missed check-ins on a resolved issue (both in the museum above). Run it quarterly, alongside the fire drill. Detection should be a measured number, not an assumption.

Reference

Our measured gap after both fixes, process killed to miss declared: 9 minutes 59 seconds, against a 10 minute check-in window. The number gets re-measured every quarter.

The loop that learnsLIVE

Log it where you already learn. Every applied heal appends a short entry to the same feed your nightly review reads, so fixes become tomorrow's context instead of buried commits. A recurrence metric keeps the score honest: fixes that stuck are healed issues with zero new events since the commit.

Lessons become tests. Any failure whose root cause generalizes gets pinned as a conformance check in the suite, in the same commit that fixes it. Prose lessons fade. A red test does not.

The perimeter ratchet. The quiet failure mode of any monitoring system is the module added after it: a new scheduled job with no heartbeat, a new store outside the audits, a new telemetry stream without a throttle. So derive the perimeter from the source itself. A conformance suite walks the code and fails on any standing job that does not check in, any capture site outside the throttle, any store outside the registry, any remediation that does not resolve to a real action. Because the executor runs the full suite before every unattended commit, the loop refuses to heal on top of an uncovered perimeter. Coverage stops being a memory and becomes a property of the build.

Reference

Our ratchet's first audit caught three schedulers running with no heartbeat, one of them shipped the day before, plus one unregistered store. We proved the bite by planting a bare scheduler: the suite went red and named the file and the fix. That red is the guarantee.

WAITING
Part six · The honest ledger

What it costs. What it pays.

CostsWORKING

Agent tokens. Every heal is two agent runs: a proposer and a reviewer, minutes of runtime each. Cheap next to an engineer-hour, but not free.

Tracker plan realities. Alert rules and issue APIs are standard. Extras are not: budget for cron monitors if you want vendor-side check-in alerts, and treat vendor AI root-cause add-ons as optional. The loop is complete without them.

The discipline tax. A green, fast, trusted test suite is the entry fee, and it never stops being due. The loop amplifies whatever your suite is: rigor or noise.

Human time, early. The L1 and L2 weeks are real hours spent reading diffs. That reading is what buys the right to stop reading.

Reference

Our plan includes one active cron monitor; more run about $0.78 per month each (public Sentry pricing). The vendor's AI root-cause add-on answered 402 until budgeted. We link out to it and let the propose agent do the diagnosis.

PaysDONE

Crashes triaged in minutes, not weeks. The 5-minute poll turns a crash into a ranked queue entry with the stack trace attached before anyone notices the symptom.

Silent-error debt stops compounding. Six of our screens crashed for weeks because nobody had a spare afternoon. One unattended morning ended all six.

Mornings become a log read. The channel tells you what crashed, what the loop proposed, what the reviewer thought, what shipped, and how to undo it. Two minutes, and you know. One velocity line keeps the trend honest: new crash classes versus last week, heals applied and regressed, and the median hours from proposal to commit.

The audit trail is free. Lineage trailers answer "what changed and why" forever, for every heal, without anyone writing a postmortem.

WAITING
Part seven · Ownership

Who holds the keys.

Autonomy is a governance decision wearing a technical costume. Write this part down before you flip anything.

The ladder contract

  1. Name the owner. One human owns the repo's autonomy level. Not a team, not a rotation. A name.
  2. L0 to L1: the owner turns on proposals after the L0 gate passes.
  3. L1 to L2: the owner reads a week of diagnoses and signs off on their quality.
  4. L2 to L3: two clean weeks, and the owner has personally watched a rollback happen.
  5. Any incident: anyone on the team can flip the loop off, no permission needed. Turning it back on takes the owner.

What never gets automated

Money paths: billing, payouts, bank syncs. Schema migrations. Security configuration. Anything that talks to a customer. The loop fixes crashes. It does not do surgery. Ours will not even auto-restart a wedged job on a money path; those stay propose-only regardless of any flag.

And make the list a gate, not a memory. Ours started as policy; now the executor inspects every diff's file paths against the protected list and demotes any match to a human click, at any trust tier (the severity ring). A conformance test walks the codebase so the list cannot rot as new modules land. A rule the code does not enforce is a rule the code will eventually break.

The circuit panel

Every layer has its own switch. Shell environment beats the env file for these flags, so a supervised terminal can dry-run a level without changing the system's defaults.

Kill switches and autonomy flags, and what each setting does
FlagEffect
TRACKER_DSN removedEverything off. The app boots identically without it.
HEAL_LOOP=offLoop off. No proposals, no reviews, no commits.
AUTO_APPROVE=offDefault. Every diff waits for a human click.
AUTO_APPROVE=lowReviewer-gated auto for low-risk proposals only.
AUTO_APPROVE=allAny risk, unattended. We do not run this. Neither should you.
HEAL_AUTOPROPOSE=offDefault. Diagnosis waits for a human click. On: persistent top-ranked crashes spawn the read-only proposer on their own. Proposals only, never commits.
AUTO_HEAL=offDefault. Runtime restart actions propose only. A separate ladder with its own dry-runs.

Tune our numbers to your suite

Every constant on this page is an output of our environment. Our full suite is 2,200+ tests and finishes in about a minute, so 5 proposals a day is cheap for us. If your suite takes an hour, your budget is different and your cooldowns are different. Copy the gates. Do not copy the constants.

And the last line of the contract: you own this loop, its commits, and its risk. This page is the map, not a warranty.

WAITING
What changes

What mornings look like now.

The tracker is quiet, or it isn't. Either way the channel tells the story: what crashed overnight, what the loop proposed, what the reviewer thought, what shipped, and the one line that undoes it. You read for two minutes and start the day knowing.

The morning of July 14, ours read: one alert at 9:31, one proposal, one passing review, one green suite, six issues closed, one revert command nobody needed. We built the cage first. Then we let it run.

Building your own second brain?

Write us what you are wiring up and where it fights you. We answer operator to operator.

Write to us See what we build