# Verifiable completion condition

> A verifiable completion condition is a loop stop rule with one measurable end state the model can prove from its own output - the loop ends, not spins.

URL: https://bartlomiejkrupa.dev/notes/verifiable-completion-condition/
Category: concept | Updated: 2026-07-01
Summary: A verifiable completion condition is a loop stop rule with one measurable end state the model can prove from its own output - the loop ends, not spins.

A verifiable completion condition is the stop rule for an autonomous agent loop: a single measurable end state the model can **prove from its own output**. It's what separates a loop that terminates from one that spins on a vague target like "make the code better."

## What makes one verifiable

- **One measurable end state** - a test result, a build exit code, a file count, an empty queue. Not a mood ("clean," "done").
- **A stated check** - how the agent proves it: `npm test` exits 0, `git status` is clean, `wc -l` under a budget.
- **Constraints that matter** - what must not change on the way there, e.g. "no other test file is modified."

## Bad vs good

| Vague (spins) | Verifiable (terminates) |
| --- | --- |
| "Fix the auth bug" | "`npm test test/auth` exits 0 and no other test file is modified" |
| "Clean up this file" | "`user.ts` is split so each module is under 200 lines and the build passes" |
| "Handle the backlog" | "Every issue labeled `migrate` is closed and the queue is empty" |

## Where it applies

The concept is provider-agnostic - it's the same property a TDD red-green loop or a prompt-based Stop hook needs. In Claude Code it's exactly what [`/goal`](/articles/claude-code-goal-command) asks for. And because that evaluator can't run tools, the proof has to reach the transcript: see [the /goal evaluator only reads the transcript](/notes/goal-evaluator-transcript-only). The broader pattern is [LLM-as-a-judge](/notes/llm-as-a-judge).

Scoping a build up front works the same way: give every task its own verifiable end state before prompting for it, not after - see [how to plan and scope a build with an LLM](/articles/plan-and-scope-a-build-with-an-llm).

Sources:
- Keep Claude working toward a goal: https://code.claude.com/docs/en/goal
- Best practices for Claude Code: https://code.claude.com/docs/en/best-practices
