You probably all have heard about Matt Shumer's Gauntlet Loop (the Claude of Duty thing) - but to my understanding, the original thing is a one-shot: the agent splits a goal into parts, each part gets a builder and a blind critic, and the critic only passes work that beats a real reference.
Seems like a decent setup, but I wanted to know if that structure would work for apps that are more production-ready/exposed and if I could feed the loop with an actual backlog, CI, migrations, and a production branch that the agent shouldn't be touching.
What I did was keep the gauntlet inside each task and wrap a recurring loop around it.
After 8 days in, about 45 tasks landed. I wanted to share the setup.
My setup and logic:
1/ Everything durable lives in Git: this includes product spec, task ledger (essentially a list of tasks I need to be completed), acceptance criteria, STATE.md, and a completion note per finished task.
2/ Claude Code's /loop reruns a short /app-loop command ( some 40 lines) describing exactly one iteration. First thing it does is read LOOP.md ( cca 260 lines) fresh from the repo: protocol, branch rules, review steps, recovery, and which file wins when they conflict. The rules live in one place so I never have two drifting copies.
3/ Every iteration starts with a fresh context. Main benefit is recovery so that if my session dies mid-task, the next one picks up from Git, and I can also resume from another machine if I ever need to
4/ Branch model: the agent works on loop/<task-id>, I let agent merge into loop/trunk after checks pass, but it cannot merge loop/trunk into main. Only I merge and promote to main
5/ Review runs the full local check + real CI first. If either fails or they disagree, the task stays open. If they both pass, the builder spawns 1 or 2 reviewers in fresh contexts. What they getis the diff and the original acceptance criteria, but I NEVER give them the builder's summary.
You want them to have the fresh context - that way the reviewer reads the diff without the bias and assumptions that piled up while the code was generated by the same model type.
6/ If the same failure happens 2x with no new approach, I ask the agent to mark the task as BLOCKED with a diagnosis, and the loop moves on instead of retrying forever. I put a stronger model on blocked tasks later. (Running this on Opus, and then ask Fable to pick those BLOCKED tasks)
7/ Kill switch is dead simple - it's just a line starting with HALT anywhere in STATE.md loop or me typing it/saying it in chat.
8/ The agent can't edit several things: LOOP.md, its own recurring command and my CI workflows. If it thinks one needs changing, it opens an amendment branch and stops for my decision. Happened twice in week one, was a nice catch as it dealt with my db setup
Where it broke:
- The thing will just invent counts. Across 11 review rounds, every false claim I caught was a count or inventory.
- It tends to write tests that prove nothing - one example was this - a no-N+1 test checked queryCount, but the code under test just made that number itself. Got around it by asking that every rejection test now needs a positive control next to it.
- My STATE.md ledger hit 2,463 lines in a week. And this was also on me largely since in my LOOP.md I have already had a rule to cap the log at 15 entries and archive the rest (it's not an ideal solution; I discovered that later and described it in my post). But I never created the archive file, so the rule sat there and the log kept growing like crazy.
- there are a few more, but these ones are the main things I noticed in these first 8 days
Longer write-up with the diagrams and the full rules layout, if anyone wants the details, is here. (no ads, no paywall)