A field guide to the verify step of the agentic loop — every mechanism that can give an agent a pass/fail signal, ordered from tightest & cheapest to richest & slowest. ★ marks the non-obvious verifiers worth reaching for when the obvious ones don't apply.
"Claude stops when the work looks done. Without a check it can run, 'looks done' is the only signal available, and you become the verification loop… Give Claude something that produces a pass or fail, and the loop closes on its own." — Anthropic, Best practices for Claude Code
Left = low latency, narrow scope, deterministic. Right = high latency, broad judgment, often non-deterministic. Prefer the leftmost verifier that can actually catch the failure you care about — then escalate only as needed.
| Verifier | Catches | Trust | Latency | How to wire it in Claude Code |
|---|---|---|---|---|
| Compiler / build exit code | Syntax, broken imports, type-incompatible code | deterministic | ≤ sec | "Build and fix until exit 0." Stop hook on the build command. |
| Type checker (tsc, mypy) | Contract/type violations — gold for dynamic langs | deterministic | sec | CLAUDE.md: "typecheck when you're done." |
| Linter / static analysis | Style, anti-patterns, some bug classes | semi | sec | Hook: run eslint/ruff after every file edit. |
| Unit tests | Function-level logic — strongest cheap signal | deterministic | sec | TDD: commit failing tests first, then iterate to green. |
| ★ Golden / fixture diff | Output drift vs. a known-good reference | deterministic | sec | "Diff output against fixture.json; fix until identical." |
| ★ Logs-as-feedback | Runtime state the agent can't otherwise see (server up? exception?) | semi | sec | App logs to a file; "read app.log and confirm no errors." |
| Integration / E2E run | Whether components actually work together & the app runs | deterministic | sec–min | Browser automation; "test as a human user would." |
| ★ Screenshot / visual diff | UI correctness vs. a design | semi | sec–min | "Screenshot the result, compare to the design, list diffs, fix." |
| ★ World-state / outcome check | Whether the world changed (DB row, file, API state) — not just the transcript | deterministic | sec–min | "Query the DB and confirm the booking row exists." |
| ★ Feature-list ground truth | Premature victory on long, multi-part work | deterministic | sec | JSON list of ~N features w/ pass/fail; agent can't stop until all pass. |
| ★ LLM-as-judge | Open-ended quality / rubric adherence where no deterministic check exists | calibrate | sec | Subagent grades output against a rubric (binary pass/fail). |
| ★ Adversarial verification subagent | Gaps the implementer is blind to | semi | sec–min | Fresh model sees only the diff + criteria; /code-review. |
| Human-in-the-loop | Anything graders miss; calibration gold standard | gold | min–hr | Checkpoints; review before merge/commit. |
A verifier only helps if something forces the agent to honor it. In Claude Code, escalate as the cost of a wrong "done" rises:
Source: Claude Code best practices · Hooks · Sub-agents.
1. Show evidence, don't assert success. Make Claude print the test output or the screenshot — never accept "done" on faith. (Best practices)
2. Commit the tests first. In TDD, commit failing tests as a checkpoint so the agent fixes the code, not the test. (Best practices)
3. Don't let the worker grade itself. For judgment calls, use a fresh-context verifier (subagent / LLM-judge). (Best practices)
4. Calibrate model-based verifiers. Measure agreement between the LLM-judge and a human before trusting it; binary beats a 1–5 scale. (Husain)
5. Error messages are feedback. Verifiers should emit specific, actionable errors — not opaque codes. (Writing tools for agents)
6. Speed is a feature. A fast check closes the loop more times per minute. Kill hanging tools. (Ronacher)