Why Your AI Agents Keep Making the Same Mistake (Even With Perfect CI)
Day 13: The Loop That Actually Compounds
Your CI is green. Your merge times are the best they've ever been. And somehow, for the third week in a row, a reviewer is leaving the exact same comment on an agent's PR. That's not a review problem — it's proof you've been measuring the wrong loop the whole time.
The team that never stopped shipping the same bug
One of the teams at PhoenixDX had numbers most EMs would kill for: high merge velocity, tight PR cycle time, CI green on nearly every run. And yet, week after week, reviewers kept flagging the same agent mistake — unsafe null handling, always in the same data-transform layer. A human caught it. It got fixed in that PR. Then the next agent session, working from a fresh context, wrote a near-identical bug right back in. Caught and fixed-forever are not the same thing. This team had a dashboard for the first one and nothing for the second.
Name the two loops explicitly
Loop 1 is the task loop: write, review, merge, deploy. Almost every org instruments this to death — CI status, PR cycle time, deploy frequency, lead time for changes, the works. Loop 2 is the learning loop: mistake caught, rule written, next agent inherits it. There's no dashboard for this one. No standard tool. In most orgs, no owner. It exists only if somebody deliberately builds it — otherwise it just doesn't happen.
Why Loop 1 metrics lie to you
CI green and fast merge time measure throughput — did this one unit of work move through the pipeline without friction. That's it. They say nothing about whether the system producing the work is getting any smarter. With human engineers, Loop 2 used to run for free: someone makes a mistake, feels bad about it, remembers, doesn't do it again. Agents don't have that. Every invocation starts close to a blank slate, bounded only by whatever context, system prompt, or repo instructions you hand it. So you end up with a team that has perfect Loop 1 health — every PR green, every merge fast — and a Loop 2 that's completely absent, quietly re-deriving the same wrong pattern forever.
- ▹CI green tells you this diff compiled and passed tests. It says nothing about whether the next diff repeats the same class of error.
- ▹Fast merge time tells you review friction was low. It doesn't tell you the reviewer's finding went anywhere past this one PR.
- ▹Deploy frequency tells you the pipeline is unblocked, not that whatever you just shipped is any less error-prone than last month's version.
- ▹None of these has a mechanism for catching a recurring mistake, because recurrence is a cross-PR signal, and every one of these metrics only looks at a single PR.
The tell
Here's the test, and it's a concrete one: can you point to an actual commit — in CLAUDE.md, the system prompt, a lint rule, an eval — that exists because of a mistake someone caught last week? If you can't, Loop 2 isn't running, no matter how sharp review felt in the moment. A team can catch everything, feel genuinely rigorous, and still be running on Loop 1 alone — because catching happens at review time, and encoding is a separate, deliberate act that only happens after the PR is already merged, if someone bothers to do it.
The fix we made concrete
We didn't add a new tool. We added one line to the review checklist that already existed: a review comment flagging an agent mistake isn't 'done' until someone answers 'does this belong in the agent's instructions?' If yes, it goes into CLAUDE.md, a lint rule, or a system-prompt addendum in that same PR cycle. Not backlogged. Not left to rot as tribal knowledge in a Slack thread nobody reopens.
## Review checklist addition
- [ ] If this comment flags an agent-authored mistake, ask: does this
belong in CLAUDE.md / lint config / system prompt?
- [ ] If yes, open or update the instruction file in this same PR —
not a follow-up ticket.
- [ ] If no (one-off, context-specific), say why in the thread so it
doesn't get silently re-litigated next time.Result — and the honest caveat
The recurring-error rate on that data-transform category dropped noticeably within a couple of weeks. Same class of null-handling bug, just... stopped showing up, because the rule was now sitting in front of every new agent session before it wrote a line. But — and this matters — it only works if somebody actually owns curating the file. Leave it unmanaged and this fix grows its own failure mode: CLAUDE.md turns into a rulebook nobody prunes, agents start skimming past whole sections of it (context dilution is real — a bloated instruction file gets skimmed, not obeyed), and you've quietly swapped 'no learning loop' for 'a learning loop that produces noise.' Somebody has to go back in periodically and consolidate, generalize, or just delete rules — the same way you'd refactor code instead of endlessly appending to it.
- ▹Loop 2 without an owner doesn't stay neutral — it decays into bloat, not signal.
- ▹A rule scoped to one PR won't generalize. Write it as a pattern, not a patch.
- ▹Every so often, read the whole instruction file start to finish and ask honestly which lines an agent would actually apply versus just skim past.
Today's exercise
Pull your last five agent-authored PRs that got human review comments. For every 'gotcha' someone caught — a subtle bug, a style violation, a wrong assumption about the codebase, whatever — check whether it's now a written rule somewhere an agent would actually read it: CLAUDE.md, a lint config, a system prompt, an eval. Count the ones that aren't written down anywhere. That number, not your merge time, is your team's real velocity ceiling. It's how many times you're going to pay the exact same review cost again, because nothing got encoded the first time around.
Extend your knowledge
- ▹Audit your own CLAUDE.md or system prompt today. Read it end to end and flag every line too vague to be checkable in review — vague rules are the first sign of bloat setting in.
- ▹Look at how your CI or lint config already encodes past incidents — a rule added after a specific postmortem, say. That's Loop 2 already running, just narrower and code-level. The exercise here is extending that same discipline to agent instructions.
- ▹Got a shared eval suite for agent output? Treat 'add a regression case for this caught mistake' as just as valid a Loop 2 target as CLAUDE.md — evals catch things prose rules miss entirely.
- ▹Add one standing item to your retros: 'which mistakes we caught this week still aren't written down anywhere.' Give Loop 2 a permanent checkpoint, not just a line on a checklist.
Discussion
Chat with Chi Cong (AI) about this article. Your conversation is private to you — you can publish a summary for others when you're done.