Claude Code Learning Hub
中文 Mingyu's Library

Hub / Tips / A · Reliability & quality

It says “done” but it isn’t — give it checks it can run itself

Claude reports “done,” you run it, and the feature is broken — the problem isn’t that it’s lying, it’s that you never gave it an objective standard for what “done” means.

Claude stops when the work “looks done.” Without a runnable check, “looks done” is its only signal — and you become the human verification loop, with every bug waiting for you to find it. Hand the verification to Claude itself and the loop finally closes.

One-line answer

Answer Give Claude a check it can run on its own that returns a pass/fail signal — tests, build exit codes, lint, a diff script, or screenshots — and require it to show evidence of the run rather than a verbal report. OfficialThe official best practices are explicit: without a check, “looks done” is its only signal; with one, Claude will build, run it, read the results, and iterate until it passes.

Steps

  1. Put the verification criteria in the task itself. Don’t just say “implement an email-validation function” — give concrete cases and ask it to “run the tests after implementing.” OfficialThe forms of check the docs list: test suites, build exit codes, linters, scripts that diff output against fixtures, browser screenshots compared to the design. Expected: Claude runs the check automatically after implementing, and keeps fixing on failure.
  2. Require evidence. Have Claude paste the test output, the commands it ran and what they returned, or a screenshot of the result — not a one-liner saying “done.” OfficialThe docs point out that reviewing evidence is faster than re-running the verification yourself, and it works for sessions you weren’t around for.
  3. Pick how hard the gate should be. Once the check exists, decide how forcefully it blocks completion: Official
    LevelHowCharacteristics
    Single promptAsk for “run the check and iterate” in the same messageZero setup — works for any task today
    Whole sessionSet the check as a /goal conditionAn independent evaluator re-checks after every turn; work continues until it’s satisfied
    Deterministic gateA Stop hook runs the check as a scriptThe turn can’t end until the check passes; after 8 consecutive blocks Claude Code force-releases
    Second opinionA verification subagent re-checks with a fresh contextThe model that did the work doesn’t grade itself
  4. Hooks are enforced; CLAUDE.md is advisory. OfficialHooks execute scripts at fixed lifecycle points — unlike the “advisory” instructions in CLAUDE.md, they guarantee the action actually happens. You can just have Claude write them for you; for example, the official sample PostToolUse hook runs Prettier after every edit:
    {
      "hooks": {
        "PostToolUse": [
          {
            "matcher": "Edit|Write",
            "hooks": [
              { "type": "command",
                "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
            ]
          }
        ]
      }
    }
    Note that the Stop hook fires every time Claude ends a reply, not only on “task complete”; in hook scripts, check the stop_hook_active field in the input to avoid infinite loops, and adjust the block cap via CLAUDE_CODE_STOP_HOOK_BLOCK_CAP.Official
  5. Add one last independent check. Have a subagent that took no part in the implementation critique the diff alone — see this cluster’s adversarial review. Our take“Verify yourself + get reviewed by someone else” is double insurance that mostly retires “says done, isn’t done.”

OfficialThe docs list “trusted but never verified” as a common failure pattern (the trust-then-verify gap), and the fix principle they give is: always provide a way to verify; if something can’t be verified, don’t ship it.

Copy-paste prompt

For this next task, a verbal "done" is not accepted — you must provide verifiable evidence:
1. Before starting, state how you plan to verify (tests / build / lint / screenshot diff — whichever applies).
2. After implementing, run the verification commands yourself (e.g. npm test, npm run build) and paste the key output verbatim.
3. If verification fails, keep fixing and re-verifying until everything passes; do not "go green" by skipping tests or suppressing errors.
4. When you finish, report: which commands you ran, what each returned, and which parts are still not covered by verification.

To turn verification into an enforced action, follow up with this — Officialthe docs confirm Claude can write hooks for you.

Write a hook for me: after every file edit, automatically run eslint; when it reports errors,
feed them back to you to fix. Put it in this project's .claude/settings.json,
and explain what each field means once you're done.

Sources & last verified