Self-Improving Systems: Loops, Reviews, Guardrails
If someone keeps stealing your bike, buy a lock. Turn a bug that happened once into a system that can't happen twice.
Chasing the thief vs. buying the lock
If your bike keeps getting stolen, you can chase down each thief after the fact — or you can buy a lock and stop the class of problem. Most bug fixes are chasing the thief: you find the broken line, you patch it, you move on. The bike is still unlocked. The next thief walks up to the exact same rack.
A self-improving system is one where fixing a bug also installs the lock — a test, a guardrail, or a scheduled review that makes the same class of failure structurally harder to repeat. The fix closes today's incident. The lock closes the door on tomorrow's.
Not "is it fixed?" — that's the low bar. Ask: if this exact mistake happened again next month, would anything catch it before it shipped? If the honest answer is no, you patched the symptom and left the lock off the bike.
Not all locks are equal strength
There are three different mechanisms for making a fix permanent, and they catch a recurrence at three different points — the earlier the catch, the stronger the lock.
Write a test that reproduces the exact bug, watch it fail, then fix the code until it passes. Now that failure mode is checked on every future change, automatically, forever. Strongest lock: it runs before the code ever reaches a user.
A hook, a lint rule, or a permission check that blocks the dangerous action structurally — like the git-guardrails hooks that stop a destructive git push --force before it runs. It doesn't need to understand your code; it just refuses the specific shape of the mistake.
A scheduled loop that periodically re-reads recent changes or logs for a known bad pattern and flags it. Weakest lock of the three — the mistake already shipped once before the review runs — but it's the only option for failure modes a test can't reach (drift, stale config, a service quietly falling over).
Pick the strongest lock the failure mode allows. A logic bug earns a test. A dangerous command earns a guardrail. A slow-drift problem — a credential nearing expiry, a queue quietly backing up — is what cron reviews are for.
What this looks like day to day
# Loop deployed a broken build twice in one month
fix_1 = "patch the broken line, redeploy"
fix_2 = "add a build-then-verify step the loop
must pass before it deploys"
The first fix removes today's symptom. The second fix is the lock: it changes the loop itself so a broken build can no longer reach production, no matter what specific bug caused it next time.
In practice this is a verify step wired into the loop's run script — same shape as the 4-check deploy verify used on Raven Cargo work: build succeeds, the right process is listening, the endpoint responds, the content is actually correct.
Claude Code's own hooks work the same way structurally — a PreToolUse hook can block a specific dangerous command outright, the same job a hand-rolled hook or hard-coded lint rule does elsewhere.
Not every recurring mistake is a code bug — some are "I keep making this same judgment call wrong." Writing it down as a durable feedback memory (the rule, the reason, when it applies) is the human-judgment version of a guardrail: the next session reads it before repeating the mistake, instead of relying on you to remember.
A lock for every bike is its own failure mode
The instinct, once you see the pattern, is to want a guardrail for everything. Resist it. A test for a bug that will never recur again is dead weight someone has to maintain. A guardrail for a scenario that can't actually happen is friction with no payoff. The discipline is proportionality, not maximum coverage.
It already happened more than once, or the blast radius of a repeat is large (production data, a live client site, a destructive git operation).
A one-off typo, a scenario that can't occur given how the system is actually built, or a rule you'd only ever apply once.
Would you bet the bug repeats, or that the cost of a repeat is worse than the cost of maintaining the lock? If neither, skip it and move on.
The top rung: a system that audits its own output
The most mature version of this isn't just locks bolted on after each incident — it's a loop that periodically checks its own recent work for the failure patterns you've already caught before, without you having to remember to look.
A loop or agent ships something wrong. You catch it, fix it, and — critically — write down what class of mistake it was.
A test, a hook, or a scheduled review is added — matched to the failure mode's strength, per the ladder above.
A periodic pass (weekly, monthly) reads what's shipped since the last review and asks: did any of our known failure patterns almost happen again? Did a lock nearly get skipped? That review is itself a guardrail — on the guardrails.
This is the same principle as a budget cap and a pause switch on an autonomous loop: the system doesn't just do work, it periodically checks whether it's still doing the work safely. That check is what turns "a loop that runs" into a system that actually improves over time instead of just repeating its own mistakes faster.
Check yourself
Three questions on locks, not thieves.
A bug ships to production. You find the broken line, fix it, and redeploy. Two weeks later, a near-identical bug ships from a different part of the same code.
What was missing from the first fix?
You've found a logic bug that you can reliably reproduce with a specific input. You're deciding how to lock it down permanently.
Which is the strongest lock for this situation?
You made a one-off typo in a config value. It's already fixed. A teammate suggests writing a permanent guardrail so it "never happens again."
What does proportionality say here?
Every fix answers "is it broken right now?" A self-improving system also answers "can it happen again?" — and locks the door with the strongest mechanism the failure mode allows: a test where you can, a guardrail where you must, a scheduled review where neither reaches. Lock proportionally, and check the locks themselves once in a while.