# Loop contract

Version: 1.0
Updated: 2026-10-02
Method: https://suhailmohebi.com/notes/designing-skills-and-loops/

Purpose: bound a repeating agent loop so it ends on evidence, a budget or a human decision, never on the agent’s own confidence.

Output: a one-page loop spec with its class, exit rule, caps, gates and a record of every iteration.

## Use when

You want an agent to repeat work until something is true (fix until checks pass, draft until good enough, watch until a threshold is crossed) and must know how it stops.

## Quick start

1. Classify the loop with the test in section 1.
2. Write the exit rule before the first iteration: an exact predicate, or a rubric scored by an independent reviewer within a budget.
3. Set caps and gates, paste the spec from section 8 into the agent’s brief, and keep one record per iteration.

A loop whose only stop condition is the agent deciding it is done is not bounded.

## 1. Classify the loop

> Could a script decide pass or fail from the current state, with no taste involved, and give the same verdict every time?

| Answer | Class | Exit rule | Example |
|---|---|---|---|
| Yes, for the whole outcome | Deterministic | Exact predicate and a fixed retry budget | Link checker reports zero broken internal links |
| No | Non-deterministic | Named rubric, independent reviewer, budget; accept, retry or ask a human | Research synthesis, naming, explanatory writing |
| Partly | Hybrid | Model judgement inside, exact checks on the way in and out | Judge which diff is risky; check revision, tests and live hash exactly |

Most valuable work is hybrid. Pin identity, sources, permissions, schema, format and budget before the model acts; check claims, links, tests, policy, hashes and live state after.

## 2. Trigger, action and exit

- Trigger: [request, schedule, change or failed check]
- Action per iteration: [one bounded change], touching only [paths or systems]
- Exact exit: [predicate], evaluated by [command]. It must be stable, observable and safe to re-run.
- Judgement exit: rubric [criteria and scale], threshold [score], reviewer [an agent or person that did not produce the work].
- Reviewer’s distinct job: [falsify claims / test audience fit / expose a missed trade-off]
- Return: PASS with evidence, or BLOCKED with the last evidence and the open question.

Tie the exit to the user outcome, not to an artifact existing.

“Keep trying until it looks right” is not an exit rule. “Run the link checker until it reports zero broken internal links, at most three repair passes” is.

## 3. Caps and budgets

| Limit | Value | When reached |
|---|---|---|
| Iteration cap |  | Stop: BLOCKED with the last evidence |
| Wall-clock time |  | Stop: BLOCKED |
| Cost or token budget |  | Stop: BLOCKED |
| Evidence delta | Each pass adds evidence or removes a known defect | Stop after the first pass without one |
| Confidence floor |  | Label the uncertainty or escalate; do not smooth the wording |

More generations are not automatically more truth. A second reviewer helps only when its job differs from the producer’s.

## 4. Fresh-state check at the start of every iteration

- [ ] Re-read the source of truth (files, branch and revision, live URL, queue), not the previous iteration’s summary.
- [ ] Confirm only this loop’s recorded changes moved the target: revision, hash or timestamp matches the record. If not, stop and re-scope.
- [ ] Run the exit check before acting. If it already passes, exit with that evidence.
- [ ] Confirm the budget covers one more full iteration.

## 5. Gates and forbidden actions

Escalate to a human when a cap is reached, the same failure repeats, evidence conflicts, confidence falls below the floor, or the next step is irreversible.

Irreversible, public, financial, permission-changing or message-sending actions leave the loop: stop and hand them to a human.

The loop may never:

- edit, skip or delete the check, test, rubric or threshold that decides its exit;
- grade its own output;
- touch anything outside [scope];
- push, deploy, publish, send, delete or spend;
- start one more iteration past a cap.

## 6. Per-iteration record

| # | State read (revision, time) | Change made | Result and evidence | Delta | Decision |
|---|---|---|---|---|---|
| 1 |  |  |  |  | Continue / Exit / Escalate |

## 7. Anti-patterns

| Anti-pattern | Symptom | Control |
|---|---|---|
| Infinite refinement | Every pass rewrites; the score stays flat | Attempt budget plus evidence delta |
| Self-grading | The producer scores its own draft | A reviewer with a different context and a distinct job |
| Moving the goalposts | Threshold, test or rubric edited mid-loop | Freeze the exit rule at iteration 0; changes need a human |
| Silent scope growth | Files or systems outside the scope change | Compare touched paths with the scope every iteration |

## 8. Copy-ready loop spec

```text
LOOP: [name]
CLASS: [deterministic | non-deterministic | hybrid]
TRIGGER: [request, schedule, change or failed check]
SOURCE OF TRUTH: [files, revision, URL]. Re-read it at the start of every iteration.
ACTION: one bounded change per iteration, only within [scope].
EXIT (exact): [predicate], evaluated by [command], tied to the user outcome.
EXIT (judgement): rubric [criteria, scale], threshold [score], reviewer [independent agent or person]; a human makes the final call.
CAPS: [3] iterations, [time], [cost or tokens].
CONTINUE ONLY IF: the last iteration added evidence or removed a known defect.
ESCALATE WHEN: a cap is reached, the same failure repeats, evidence conflicts, or the next step is irreversible.
NEVER: change the check, rubric or threshold; grade your own work; touch [out of scope]; push, deploy, publish, send, delete or spend.
RECORD EACH ITERATION: state read, change, result and evidence, delta, decision.
RETURN: PASS with evidence, or BLOCKED with the last evidence and the open question.
AFTER EXIT: turn a repeated failure into a precondition, test or stop condition, not a warning.
```

## Worked example

**A. Deterministic.** Exit: `npm run typecheck` exits 0 on `feature/x`. Caps: 3 iterations, 20 minutes, no paid API calls. Scope: `src/forms/` only.

| # | State read (revision, time) | Change made | Result and evidence | Delta | Decision |
|---|---|---|---|---|---|
| 1 | abc1234 clean, 10:02 | Fixed an import path in `src/forms/a.ts` | Exit 1, 2 errors (log) | 5 → 2 errors | Continue |
| 2 | abc1234 + change 1, 10:09 | Typed the submit handler | Exit 0, 0 errors (log) | 2 → 0 errors | Exit: PASS |

**B. Hybrid.** A release summary for non-specialist readers: a judged core inside an exact enclosure, capped at 3 rounds, 30 minutes and 50k tokens.

- Rubric, each scored 1–5, threshold 4 on all: claims traceable to the changelog; audience fit; every breaking change listed.
- Exact enclosure: under 150 words, checked by a word count, not by the reviewer.
- Reviewer: a separate agent given only the changelog, rubric and draft, told to falsify claims.

| # | State read (revision, time) | Change made | Result and evidence | Delta | Decision |
|---|---|---|---|---|---|
| 1 | changelog abc1234, 11:00 | First draft | 4/4/2, 131 words: one breaking change missing | First scored draft | Continue |
| 2 | changelog abc1234, 11:12 | Added the missing change | 4/4/4, 142 words (review notes) | One defect removed | Exit: human decides |

**Verdict:** A passed on its exact predicate at iteration 2. B met its rubric threshold inside its exact enclosure at round 2 and stopped; publishing stays a human decision.

## Stop if

- The exit rule cannot be written before iteration 1. Without a predicate or a rubric, this is a question for a human, not a loop.
- The same failure repeats with no evidence delta.
- Anyone proposes changing the check, rubric or threshold mid-loop.
- The fresh-state check shows the source of truth changed under the loop.
- The next action is irreversible, public, financial, permission-changing or sends a message.
