Naive loops aren't the solution to loop engineering. Governed loops are.
Naive agent loops are useful, but reliable long-running agent work needs deterministic runtime judgment.
If you’ve been on AI Twitter or the broader agent-builder internet recently, you’ve probably seen the loop engineering discourse.
Peter Steinberger, the man behind OpenClaw, said he does not prompt anymore.
He writes loops, and then those loops prompt his agents.
Boris Cherny made a similar point. Within a couple days, half of AI Twitter decided that loop engineering was the new big thing.
For some context, in case loops are new to you: in July 2025, a developer named Geoff Huntley published Ralph, named after the Simpsons character Ralph Wiggum.
Ralph is a one-line bash loop that starts an agent. The agent receives fresh context every run, then stores memory to disk at the end of the run so the next agent knows what to do.
At first, not many people cared. Then in January, the whole thing went viral.
Twenty thousand GitHub stars. Dozens of explainers. Headlines. The whole nine yards.
A few months later, both Codex and Claude Code shipped /goal natively. Recently, I’ve seen at least five different posts and explainers talking about loop engineering and loops as though the whole concept just spawned out of the mist.
Here’s the thing.
For every “loops are the future” post, there is another post calling out all the issues that happen with agent loops.
Loops burn tokens. They make confident wrong assumptions. They ship slop. They are too unreliable.
And as someone who has been making and working with custom loops since December, I agree with the skeptics.
About one kind of loop.
I am going to give that kind of loop a name: naive loops.
I mean naive in the same way as naive RAG. It means a simple, obvious first iteration. Not that it is stupid, although some critics might say that it is.
It is just the basic version.
Trigger, run, check, repeat.
Ad infinitum. The same prompt over and over again.
Ralph is a naive loop. /goal is a naive loop. Automations, cron jobs, and scheduled routines are naive loops too. They are real, and they have legit use cases. I use automations and cron jobs.
But they all share the same failure modes.
There are more than five, but for the sake of simplicity, we are going to pretend there are five.
If you’ve used agent loops before, you are probably personally familiar with each of them.
Token burn
The first failure mode is token burn.
The loop fires again whether or not the last pass moved anything.
That is because nothing decides whether rerunning is justified or just a waste of tokens. You can set the loop to run a certain number of times so it does not keep running forever with no progress, but that is just an arbitrary cap you set ahead of time.
That cap is not judgment. It is a kitchen timer.
Helpful, sometimes.
Not the same thing.
Assumption drift
Assumption drift might be the most well-known problem.
Any ambiguity in your spec gets exaggerated in a loop. Nothing decides whether the spec was actually executable before execution, so agents fill in the gaps with less-than-great guesswork.
Then the loop keeps going.
The bad assumption does not stay local. It becomes the floor for the next run. Then the next run builds on it. Then the next run explains why the new weird thing is actually consistent with the previous weird thing.
Very thoughtful.
Still wrong.
Bad persistence
The loop does need persistent memory, but nothing decides what earns that persistence.
So the bad assumptions get remembered along with the useful insights. The memory layer does not know the difference between “we learned something important” and “the agent got confused but wrote it down confidently.”
That creates compounding slop.
Persistent memory is not automatically good. Persistent memory is only useful if something decides what deserves to persist.
Cognitive debt
The sneakiest failure mode is probably cognitive debt.
It ships. All checks are green. Tests are passing. And you stopped understanding it 300 commits ago.
That happens because there is no record of how completion occurred. You got a check mark when you needed an audit trail.
You needed some way to inspect how the work got there, why the decisions were made, what failed, what got patched, and what got accepted as done.
Instead, you got:
Tests are passing.
Cool.
Terrifying.
No recovery mechanism
Finally, there is no real recovery mechanism.
Nothing decides what happens after a failure.
So when you wake up to a codebase that does not compile and a loop that has been spiraling for several hours, the recovery system is you, after the fact, reverting to the last known good commit from before you started the loop in the first place.
Pretty advanced stuff.
Notice the pattern here.
There are five failures, all caused by one main issue:
Nothing is deciding.
Vital decisions are being made arbitrarily beforehand, by the agent in the moment, or by nobody.
Naive loops do not lack intelligence.
They lack consistent, reliable judgment.
That is where governed loops come in.
What governed means
While this whole loop debate was happening, I was running a little experiment on crates.io from April to now.
This is Millrace AI, an agentic runtime written in Rust.
Millrace AI is generated by a governed loop, not a naive loop. Each release I tried worked. No human or agent touched the Rust code generated by the pipeline. It is now maintained by a completely autonomous governed loop.
But before that matters, you need to know what governed means.
Start with a standard coding workflow.
You collaborate with an agent and write a spec. You tell the agent to implement it. You tell it to run a code review. It finds issues. You tell it to fix those issues. It fixes them. You tell it to run tests. The tests show something is broken, so you tell it to patch what broke.
Eventually the work seems complete and the tests are passing. Just to double check, you ask the agent if there are any gaps between what got implemented and the original spec.
If there are, rinse and repeat.
Nobody is trusting an agent to complete that whole managed workflow with a naive loop.
Nobody is trusting an AI to do legitimate agentic engineering by simply running:
Same prompt. Again. Good luck.
The decisions are simple, but agents still are not reliable enough over time to make the right decision at every seam.
They need deterministic governance.
And in the normal workflow, that governance is you. You are executing a repeatable decision process by hand.
That is the insight governed loops are built on.
Look at what you are doing at every point.
A package dependency suddenly is not on PATH after the latest Windows update, so you ask an agent what happened.
Tests fail after a task, so you ask an agent for a targeted patch plan.
All the tasks are done, so you prompt an agent to check the implementation against the spec.
Well, at least you should.
Every one of those interventions is deterministic in when it fires and standardizable in what gets asked.
The condition is mechanical.
The prompt is a template.
So why are you the one running it?
Make the troubleshooter stage. Make the patch-plan stage. Make the closure-check stage. Then automate the stages.
All of that collapses into one sentence:
If you can draw the decision tree, you can govern the loop.
And that is what Millrace is.
What Millrace does differently
Millrace has one deterministic tick loop at the core.
Every tick, the scheduler looks at the state of the work: what is claimed, what is blocked, what is closed. Then it routes to the next step.
Planning. Execution. Closure. Idle. Whatever is legal.
Agents run inside stages with typed contracts.
Three things matter here.
First, every stage is a brand new run. The agent starts with fresh context every time a new stage starts.
Second, state lives on disk. Not in a chat thread. Not in a context window being compacted over and over again.
Third, the decisions are made by the runtime.
Good old-fashioned code.
The same every time.
Agents do the work. The runtime decides what is next.
If you have seen the Ralph advocates, none of this should seem foreign. The community already discovered these issues the hard way.
“One task per loop” is a frozen compiled plan in Millrace. It is one of the main features.
“The tests decide what is real” is also a first-class feature. In Millrace, that is called a proof contract.
Those rules you add to CLAUDE.md after the agent makes a mistake, probably written in all caps? In Millrace, a mistake can spawn an agent to update relevant skills so the mistake is less likely to repeat.
The morning-after rescue prompt? Millrace handles that too, with different recovery mechanisms depending on the specific type of problem encountered.
It turns the patchwork of loop discipline into first-class behavior inside a programmatic engine.
That is the difference.
The part most people missed about /goal
There is a part of this story that most people do not talk about.
When the labs shipped /goal, they shipped Ralph’s persistence, but they did not ship arguably the most important part.
/goal runs one ever-growing thread that continually compacts over time.
The context rots.
The original Ralph insight was the opposite: wipe the agent every pass and keep memory on disk.
Millrace keeps that insight.
It runs a new agent every stage against durable state on disk, in both machine-readable and human-readable formats.
The important state does not depend on a single thread surviving compaction gracefully.
And when every agent starts fresh, context rot inside one ever-growing session stops being the failure mode.
That is not flashy.
Pretty handy.
The Level 5 Dark Factory part
Dan Shapiro popularized the term “Level 5 Dark Factory” in January. In his framing, it means the AI defines implementation, writes code, tests, fixes bugs, and ships.
Nobody is trusting a naive loop to do that reliably.
On the other hand, I have been running a dark factory on my desktop for over a month, using a single ChatGPT Pro subscription.
That is the power of a governed loop.
Back to the Python-to-Rust port.
For the original port, Codex manually queued eight small prompts, roughly 30 lines each, all at once. The runtime ensured those prompts were received in order so they did not disrupt existing work.
Each prompt got processed only after the previous prompt was completed.
From those prompts, Millrace generated 11 specs and 57 tasks. It autonomously recovered from two separate blockers.
That first run took 28 hours of runtime and 727 million input tokens, but over 95% of that was cached.
For the first run, the preliminary setup, initial prompts, publishing, documentation, and packaging were manual.
The generated code was 100% done by Millrace.
When Millrace finally ended, the resulting code just worked. It was functionally on parity with the original version of Millrace.
But that is not the coolest part.
Once the Rust runtime existed, I configured Millrace into a maintenance loop.
It now detects a new Python release, generates parity work, implements that work, writes tests for that work, and repairs gaps the first agent missed.
Once all the work is completed, the Arbiter agent decides whether the completed work actually satisfies the original goal.
If it does not, it creates a remediation spec that articulates the gaps and runs that remediation spec through Millrace again.
If it does satisfy the original spec, a programmatic release gate runs the checks and publishes.
Twelve releases were shipped that way.
Half of them while I was asleep.
Now I use the Rust runtime to dogfood the original Python framework.
The receipts
Two things are worth noticing.
First, there have been no non-functional deployments released as far as I have checked. The Arbiter has been sufficient to keep broken builds from shipping so far.
Obviously, it can still happen.
Let me be clear about that. This is not magic. It is a governed release path with receipts.
Second, and this is my favorite part, the evidence repo updates itself.
The evidence logging runs through the same pipeline it documents.
I feel like that is a pretty good example of true autonomy.
Do not just take my word for it. The public evidence repo has sanitized log bundles, generated metrics, checksums, a redaction policy, and a verifier script. If you are skeptical, you can check it for yourself.
Everything I am talking about is publicly available and open source under Apache-2.0.
What governed loops do not solve yet
Here is what governed loops do not solve yet.
First, taste.
The README from the maintenance loop is just changelog slop. The loop wrote it. The loop maintains it. It is abhorrent.
Governance is not judgment, and I did not configure a custom README curator agent to fix this.
Millrace might be able to guarantee releases pass their contracts. I have not figured out how to guarantee taste yet.
Granted, I have not really worked on that either.
Second, generality.
The Python-to-Rust loop proves potential. It proves that autonomy can exist. It does not prove that this level of governance generalizes to every workflow.
Third, cost.
Millrace is pretty cost efficient considering it is a loop, but that does not mean it is cheap.
The main reason generalization has not been proven yet is because tokens are expensive and I am broke.
Running a wide variety of projects and evaluation suites costs a lot of tokens. I do not have the funds for that.
I know I just said generality is not proven, but I am going to backtrack a little bit.
Right now, the engine does not know the type of work being done. None of the runtime governance is Rust-specific or even code-specific.
Only the configured workflow is code-specific.
The version 0.20 release line is decoupling the core kernel from configuration data so that routing, scheduling, operations, and the rest are generic and pluggable.
The goal is to support making any type of workflow you can sufficiently specify into a workflow that Millrace can govern.
I am not quite there yet.
But I am close.
Mostly because I do not have enough tokens.
Naive loops still have their place
Naive loops are not fake. They are not useless. They are not something everyone should stop using.
If you need a simple routine, scheduled automation, or disposable loop, use the simple thing.
But if you need a reliable workflow pipeline, you probably want something more sophisticated than Ralph Wiggum.
He is known for persistence.
Not his IQ.
That is the distinction I care about.
Naive loops do not lack intelligence. They lack consistent, reliable judgment.
Governed loops are what you get when you stop asking the agent to invent the workflow as it goes and start giving the workflow runtime authority.
Agents do the work.
The runtime decides what is next.
You can watch the companion YouTube video here: Naive loops aren’t the solution to loop engineering. Governed loops are.