Loop Engineering: The Boxes in the Loop That Can't Be the Model
The discipline everyone is naming this year is loop engineering — designing the trigger, topology, verifier, and stop rule of an agent that works, checks itself, and repeats. A model can be three of those four. The two it can't be are the two that decide whether the loop is telling you the truth.
The bottleneck moved. For a while it was the prompt — phrase the instruction well and the model did the rest. Then it was context — fit the right files, the right history, the right tools into the window. The thing people are naming now sits one level up from both: loop engineering, the design of the loop an agent runs when it works, checks its own result, and decides whether to go again. Trigger, topology, verifier, stop rule. Get those four right and an agent runs a backlog overnight. Get them wrong and it runs confidently off a cliff.
Most of loop engineering is a model's job, and rightly so. But two of those four boxes are exactly where a model grading its own work fails — quietly, in a way no amount of a better model fixes. This is about which two, and what has to go there instead.
Four boxes, and who fills them
Lay the loop out as its parts:
- The trigger — what starts a run. A schedule, a webhook, a human, another agent. A model can decide this.
- The topology — the shape of the work: what runs, in what order, what depends on what. A model can plan this.
- The verifier — the check that decides whether a step actually succeeded. Tests, types, a review pass, a gate.
- The stop rule — when to stop looping: done, blocked, escalate. A model can judge this.
Three of the four can be the model, and the loop is better for it — the whole point of the discipline is that the model drives. The verifier is the exception, and it is the exception for a structural reason, not a quality one.
The verifier can't grade its own homework
A verifier earns trust by being unable to talk itself into a PASS. That is why the strong checks in any loop are deterministic: a test suite passes or fails, a typechecker resolves or it doesn't, an exit code is a fact rather than an opinion. The model cannot argue with 1.
The moment the verifier is a model — a second agent reviewing the first — you have traded a fact for an opinion. A review agent works well on code, because code hands the reviewer ground truths it can execute: run the tests, read the types, replay the diff. But the loop produces a second artifact the code checks never touch: the record — the "phase shipped" note, the last_commit line, the queued next step, the status the next run reads before it opens a single file. Nothing in the loop grades that. It is prose, written by the same process that wrote the code, with none of the coverage. We took that argument apart in Self-Verifying AI Agents; the short version is that a model reading last_commit: 9f31c2e judges whether the close reads plausibly — and a fabricated close reads exactly as plausibly as an honest one, because both come from the same distribution.
So the verifier box needs something the model cannot supply: a check that resolves every claim against the repository, mechanically, with no model in the path. Drifted state in, non-zero exit out.
Here is that floor doing its one job — a state file that claims the next slice is queued when git shows it already shipped:
$ casp check casp:check · 26 PASS · 0 WARN · 1 FAIL ────────────────────────────────────────────────────────────────────── FAIL CASP-PROMPT-003 next_prompt is already SHIPPED · docs/plan/sessions/PHASE-14-ANALYTICS-DASHBOARD.md has status: shipped → either update state.json.next_prompt to the real next slice, or re-execute the shipped prompt explicitly ✗ 1 drift detected. Push blocked — fix before push.
Nothing probabilistic produced that verdict. Same input, same exit code, every time. That is what the verifier box is for.
The topology has a truth value too
The verifier is the box everyone points at. The one people miss is the topology — and it is the more interesting claim, because a plan looks like the kind of thing only a model could judge.
A model is the right author of a plan. But once the plan is written down — a queue of steps, each declaring what it runs after — the shape of that plan has become a checkable fact, not a matter of taste. A step that says it runs after a slice that exists nowhere is not a debatable plan; it is an unexecutable one. A cycle — A after B, B after A — is not an aggressive plan; it is one no order can satisfy. Those aren't judgment calls. They resolve against the files on disk, deterministically, the same way the state check resolves against git.
That is the second thing the floor validates. The plan is authored by the model; its topology is certified by something that can't be argued with:
$ casp check casp:check · 27 PASS · 0 WARN · 1 FAIL ────────────────────────────────────────────────────────────────────── FAIL CASP-PROMPT-007 next_after names a slice that resolves to nothing · docs/plan/sessions/PHASE-17-BILLING-SEATS.md → 'phase-16-usage-metering' matches no prompt, session log, or phase id PASS the queued next_after chain was checked · 3 chained prompt(s) ✗ 1 drift detected. Push blocked — fix before push.
The distinction the floor draws is exact: an unexecutable plan — a dangling dependency, a cycle — fails, because it cannot be true. An ambiguous plan — two steps claiming the same predecessor, a step nothing reaches — only warns, because a deliberate parking lot of queued-but-unchained work is a legitimate way to plan. The floor refuses the impossible and leaves the merely undecided to you. A model can't hold that line reliably, because to a model a plausible-but-broken chain reads exactly like a working one.
What the floor is not
The credibility of "put a floor in the verifier and topology boxes" depends on being just as clear about the boxes it does not fill:
- It is not the trigger. It never starts a run, schedules anything, or wakes an agent. It prints the next step and refuses when the state is drifted; your harness decides when to ask.
- It is not the orchestrator. It does not run steps, pass output between them, or drive the loop. It hands over one validated slice; the agent does the work. A printer and a gate, not an autopilot.
- It is not the stop rule. It has no opinion on whether you are done, blocked, or should escalate. It reports drift; you decide what that means for the run.
None of those is a missing feature. A deterministic floor that tried to be the trigger or the orchestrator would need judgment, and the instant it needs judgment it stops being a floor. The value is precisely that it does one narrow thing the model can't do for itself, and stays out of the three it can.
The two boxes, and the line between them
Loop engineering is the right frame, and most of it belongs to the model. Drive the loop, plan the work, decide when to stop — that is what the model is for, and the better the model, the better all three get.
The two boxes that don't move with the model are the two that decide whether the loop is telling you the truth: whether the recorded state is real, and whether the plan can actually be run. Both resolve against the repository, not against the model's confidence in itself. Put a floor there — one that exits non-zero and blocks the push — and the rest of the loop can be as autonomous as you dare, because the one thing that can't check itself no longer has to.
casp is that floor: a CLI, no LLM in the check, no network, no account. It reads what your project claims — its state and its plan — and resolves every claim against git.
# install npm i -g @justethales/casp # in your repo casp init # scaffold the layer casp check # deterministic — exit 1 on drift
@justethales/casp · MIT · no LLM in the check · zero telemetry · source on GitHub
The model holds the context. CASP proves the state is true — against git.