Coding-Agent State Protocol

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.

22 July 2026 · 8 min read · deterministic verification

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:

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.

Diagram: the four boxes of an agent loop — trigger, topology, verifier, stop rule — as a row. Trigger and stop rule are muted, marked "the model decides" and "the model judges". Topology and verifier are amber-outlined, their dashed legs dropping onto an amber deterministic-floor bar labelled "casp check · state == git · plan executable?" with PASS exit 0 and FAIL exit 1 chips. Below, three muted tags: not the trigger, not the orchestrator, not the stop rule.
Two of the four boxes drop onto the floor: topology and verifier resolve against git. The other two are the model's, and should be.

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:

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.

Related articles