"All tests pass." Four of the most comforting words in software, and, when typed by a coding agent at the end of a long session, some of the least informative. Which tests? Run when? Before or after the agent quietly edited the one that kept failing?
This is not paranoia. It is, more or less, the official position of the people who build the agents. In a November 2025 engineering post on running Claude across long, multi-session coding jobs, Anthropic's Justin Young described an agent that "would look around, see that progress had been made, and declare the job done". The same post notes "Claude's tendency to mark a feature as complete without proper testing", and the fix involved a feature list in which the agent was only allowed to flip a "passes" field, with the blunt instruction that "It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality."
If that sounds familiar, it is because human teams have been here before. We spent the better part of two decades learning that "done" means nothing unless someone writes down what it means, and that work started on a vague ticket finishes as a vague feature. The agile world's answer was a pair of plain, unglamorous checklists: a Definition of Ready and a Definition of Done. They are about as exciting as a fire door. They are also exactly what your coding agent is missing.
This article explains why those two definitions matter more for agents than they ever did for people, then walks through setting them up in Claude Code so that the first is a gate you control and the second is something the agent physically cannot skip.
The Checklists Scrum Already Wrote
The Definition of Done comes straight from the Scrum Guide, the framework's canonical text by Ken Schwaber and Jeff Sutherland. The 2020 edition calls it "a formal description of the state of the Increment when it meets the quality measures required for the product", and it is unusually firm for a document that otherwise prefers gentle nouns like "commitment" and "transparency". "The moment a Product Backlog item meets the Definition of Done, an Increment is born." Conversely, "If a Product Backlog item does not meet the Definition of Done, it cannot be released or even presented at the Sprint Review." No partial credit, no "basically finished".
The Definition of Ready is the other end of the pipe. It never made it into the Scrum Guide itself, which only says that backlog items that can be done within one Sprint "are deemed ready for selection". The Agile Alliance glossary describes it as a team practice that makes "explicit and visible the criteria" a user story must meet before work starts, usually built on Bill Wake's INVEST checklist from 2003: Independent, Negotiable, Valuable, Estimable, Small, Testable. The glossary notes that a 1985 entry-task-validation-exit framework anticipated the idea, and places the first Scrum descriptions of it in 2008. Its main selling point is social: an explicit agreement lets the team "push back" on accepting ill-defined work, rather than discovering the gaps halfway through.
Of Wake's six letters, the one that matters most here is the T. His original essay argues that if a customer cannot say how to test something, the story may be unclear or may not be valuable at all. Hold that thought. It turns out to be the whole game with agents.
The Definition of Ready also has a respectable set of critics, and they are worth hearing before we build one. Mike Cohn of Mountain Goat Software warns that a rigid ready checklist "moves the team dangerously close to stage-gate process", which he describes as "another way of describing a waterfall process". His recommendation is to favour guidelines rather than rules. We will come back to that, because Claude Code happens to give you a neat way of honouring it.
Why Agents Need This More Than People Do
A human developer who picks up a vague ticket has a dozen informal correction mechanisms. They wander over to the product owner. They remember last quarter's argument about date formats. They feel a faint unease when the change touches billing. An agent has none of that, unless you put it in the context window.
Claude Code's own documentation is candid about this. "Each Claude Code session begins with a fresh context window," says the page on project memory. Whatever your team agreed about readiness and completion yesterday, today's session knows only what has been written down and loaded.
The second problem is that agents are extremely good at producing work that looks finished. Stack Overflow's 2025 Developer Survey asked developers what frustrated them about AI tools, and the top answer, cited by 66 per cent of those who responded, was "AI solutions that are almost right, but not quite". Second, at 45.2 per cent, was that debugging AI-generated code takes longer. "Almost right" is the precise failure a Definition of Done exists to catch: work that would pass a glance and fail a checklist.
The third problem is scale. The 2026 Stack Overflow results, published in October, found that 66 per cent of developers using AI tools now "live in coding agents", and named Claude Code (66 per cent) and GitHub Copilot (59 per cent) as the agents of choice. Google's DORA programme, in its 2025 report on AI-assisted software development, found AI adoption had a positive relationship with delivery throughput but a continuing negative relationship with delivery stability, and summarised the pattern in a line worth pinning above every monitor: "AI doesn't fix a team; it amplifies what's already there." If your team's notion of done is fuzzy, an agent will produce fuzzy work faster than any human ever could.
Finally, there is the perception gap. In METR's 2025 randomised trial, 16 experienced open-source developers took 19 per cent longer to complete issues when AI tools were allowed, while believing afterwards that AI had sped them up by 20 per cent. METR has since said those early-2025 results are dated: a February 2026 follow-up suggested developers are probably faster with newer tools, while calling its own data "only very weak evidence" of how much. The lesson that survives both studies is not that agents are slow. It is that our gut sense of whether the work went well is unreliable. Checklists exist precisely because gut feel is unreliable.
Advice Versus Enforcement
Before touching any configuration, it helps to understand the single most useful distinction in Claude Code's documentation. The best-practices guide splits every instruction into two kinds. Non-deterministic instructions are things Claude reads and then decides what to do with: your prompt, your CLAUDE.md file, a skill it picks up. Deterministic instructions are things the harness executes regardless of what the model thinks: hooks, permission deny rules, managed settings.
The guide's table puts it plainly. For deciding when the work is done, the non-deterministic options are "A request for evidence, /goal, /code-review", and the deterministic ones are "Tests, typecheck, a Stop hook, CI". The memory documentation adds the line that should reorganise how you think about CLAUDE.md: "Claude treats them as context, not enforced configuration."
That maps neatly onto our two definitions. A Definition of Ready is mostly judgement: is this task specific enough, are the edge cases named, is the scope sane? Cohn's advice to favour guidelines over rules fits naturally into the non-deterministic layer. A Definition of Done, by contrast, contains items that should never be negotiable: the build compiles, the tests pass, the linter is quiet. Those belong in the deterministic layer, where no amount of model confidence can talk its way past them. As the guide puts it, "If you keep adding emphasis to a CLAUDE.md line and Claude still misses it, that's a sign the line belongs in a hook."
So the plan is: write both definitions down, make Ready a conversation you invoke deliberately, and make Done a gate the harness enforces.
Write Both Definitions Down
Start with two short files in your repository. Keep them separate from CLAUDE.md so humans can read and review them too, then import them. Claude Code supports @path/to/file imports in CLAUDE.md, which pull the file into context alongside it.
docs/definition-of-ready.md might look like this:
# Definition of Ready
A task is ready for implementation when:
- The intended behaviour is stated as observable outcomes, not implementation steps
- Every outcome has an acceptance check that returns pass or fail
(a test name, a command and its expected output, or a fixture to diff against)
- Files or modules in scope are named; anything explicitly out of scope is listed
- Edge cases and error behaviour are written down
- Any new dependency, migration or public API change is called out
- Open questions are either answered or recorded as assumptions
And docs/definition-of-done.md:
# Definition of Done
Work is done when:
- `npm run typecheck` exits 0
- `npm run lint` exits 0
- `npm test` exits 0, and no existing test was deleted, skipped or weakened
- Every acceptance check in the task's SPEC.md passes, with the command and output shown
- New behaviour has tests that fail without the change
- Public API changes are reflected in docs/ and CHANGELOG.md
- The final message lists what changed, what was not done, and any assumptions made
Notice how concrete those are. That is deliberate, and it follows the documentation's own advice to "Write instructions that are concrete enough to verify", preferring "Run npm test before committing" to "Test your changes". A Definition of Done full of words like "clean", "robust" or "well-tested" is a mood board, not a checklist.
Then wire them into your project's CLAUDE.md:
## Ways of working
- Before implementing any feature, check the task against @docs/definition-of-ready.md
- Work is not complete until it meets @docs/definition-of-done.md
- When reporting completion, show the commands you ran and their output
Keep the whole file lean. The documentation recommends targeting under 200 lines per CLAUDE.md, warning that "Longer files consume more context and reduce adherence", and notes that imports organise a file without reducing its context cost.
Make Ready a Gate You Open
The Definition of Ready earns its keep at the start, before a single line of code is written. Claude Code's best-practices guide offers a prompt pattern that is, in effect, an automated refinement session:
I want to add rate limiting to the public API but haven't thought it through yet. Interview me until you could write the spec, then write it to SPEC.md.
According to the guide, Claude responds with multiple-choice questions about the parts you have not pinned down, such as per-user versus per-key limits and what is out of scope, and keeps asking until the answers add up to a spec. It then recommends starting a fresh session to build from that file, "so the build begins with a clean context and a written definition of done."
To make that repeatable for the whole team, turn it into a skill. Skills live in .claude/skills/<name>/SKILL.md and are invoked with a slash command; older .claude/commands/ files still work, because custom commands have been merged into skills. The important frontmatter field here is disable-model-invocation: true, which stops Claude loading the skill on its own initiative. Readiness becomes something you decide to check, not something the agent decides it has already satisfied.
---
name: ready
description: "Check a task against the Definition of Ready and produce SPEC.md"
disable-model-invocation: true
argument-hint: [task description or issue number]
---
Read docs/definition-of-ready.md. Then assess this task against it: $ARGUMENTS
For each criterion, say whether it is met, partly met or missing.
Do not write or edit any code.
Interview me, one question at a time, about every criterion that is not met.
When all criteria are met, write SPEC.md with: outcomes, acceptance checks
(each one a command or test that returns pass or fail), files in scope,
out of scope, edge cases and assumptions. Then stop.
Typing /ready add CSV export to the invoices page now runs your team's readiness conversation in the same shape every time. This is Cohn's "guidelines rather than rules" in practice: the skill asks the questions, but you and the agent still exercise judgement about which gaps matter. Nothing blocks you from starting work on a half-ready task if you decide the risk is worth it. You just cannot do it by accident.
A few prompts that work well alongside it:
Before writing anything, list every assumption you are making about this task
and mark which ones would change the implementation if they were wrong.
Rewrite each acceptance criterion in SPEC.md as a command I could run.
If you cannot express one as a command, tell me why instead of guessing.
That second prompt is Bill Wake's T, twenty-odd years later. If an acceptance criterion cannot be turned into a check, the story is not ready, no matter how confident everyone feels.
Make Done Non-Negotiable With a Stop Hook
Here is where most setups stop, with "Run the tests before you finish" written politely in CLAUDE.md. As we have established, that is advice. To make it a gate, use a Stop hook.
Hooks are, in the documentation's words, "user-defined shell commands" that run at specific points in Claude Code's lifecycle, providing "deterministic control: certain actions always happen rather than relying on the LLM to choose to run them." The Stop event fires when Claude finishes responding. If your hook exits with code 2, the harness prevents Claude from stopping, and anything the script writes to standard error is fed back to Claude as the reason.
The simplest version, adapted from the best-practices guide, sits in .claude/settings.json:
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/definition-of-done.sh" }
]
}
]
}
}
With the script doing the actual checking:
#!/bin/bash
# .claude/hooks/definition-of-done.sh
# Blocks Claude from finishing until the mechanical Definition of Done holds.
npm run typecheck --silent 1>&2 || { echo "Definition of Done: typecheck failed" >&2; exit 2; }
npm run lint --silent 1>&2 || { echo "Definition of Done: lint failed" >&2; exit 2; }
npm test --silent 1>&2 || { echo "Definition of Done: tests failed" >&2; exit 2; }
exit 0
Make it executable with chmod +x, and run /hooks inside Claude Code to confirm it is registered. Now, when the agent tries to wrap up with failing tests, it does not get to deliver its cheerful summary. It gets the compiler or test output and goes back to work. The guide describes exactly this loop for a typecheck: "instead of finishing, it gets the compiler errors back and keeps going until tsc passes."
Three caveats from the documentation are worth knowing before you ship this to your team. First, Stop hooks fire "whenever Claude finishes responding, not only at task completion", so a quick question in the middle of an exploratory session will also run your test suite. If your tests take minutes, keep the hook to fast checks and leave the heavy suite to CI. Second, there is a safety valve: Claude Code overrides a Stop hook after it blocks eight times in a row with no tool call in between, which stops a genuinely impossible condition from looping forever. The hooks guide adds that teams whose checks legitimately need more iterations can raise that cap with the CLAUDE_CODE_STOP_HOOK_BLOCK_CAP environment variable. If you want a single nudge rather than a persistent gate, have your script check the stop_hook_active field in the hook input. Third, a hook only checks what you can express as a command.
For those judgement calls, Claude Code supports prompt-based hooks, where a model evaluates the condition and returns "ok": false with a reason that becomes Claude's next instruction. The documentation's own example is a Stop hook whose prompt reads:
Check if all tasks are complete. If not, respond with {"ok": false, "reason": "what remains to be done"}.
Point one at the softer half of your Definition of Done. Just remember which layer it lives in: it is a model's opinion, enforced by the harness, which is better than nothing and worse than an exit code.
Have Someone Else Mark the Homework
A Definition of Done is only as good as whoever checks it. The agent that wrote the code is, unavoidably, the agent most persuaded by the reasoning that produced it. Subagents fix this neatly, because each one "runs in its own context window" and "doesn't see your conversation history."
The best-practices guide includes a reviewer that is worth copying almost verbatim into .claude/agents/reviewer.md:
---
name: reviewer
description: Reviews changed files against the spec they were built from. Use after implementing a feature, before opening the PR.
tools: Read, Grep, Glob
---
You're reviewing code you didn't write. Compare the changed files against the spec you're given,
check that every requirement is implemented and the listed edge cases have tests,
and report only the gaps that affect correctness. Skip style.
The tools line matters. Restricted to reading and searching, this reviewer cannot "helpfully" fix anything, and the documentation points out that the limit is enforced by Claude Code rather than requested in a prompt. Then, once the Stop hook is satisfied:
use a subagent to review the rate limiter diff against SPEC.md, check every requirement is implemented and the listed edge cases have tests, report gaps that affect correctness and skip style
Do not drop "skip style". The documentation is drily accurate on this point: "A reviewer that's asked to find problems will always find something." Fix every finding and you get extra abstraction layers and tests for cases that cannot happen. Your Definition of Done should say what matters, and your reviewer should look only for that.
One more prompt belongs in every team's muscle memory, because "All tests pass" on its own is worthless:
Show me the exact commands you ran to verify this and paste their output.
List anything in the Definition of Done you did not check, and why.
For a session you were not watching, as the guide notes, that output is "the only evidence you have."
Leave It Running Without Leaving It Unsupervised
The payoff for all this setup comes when you stop watching. Claude Code's /goal command sets a completion condition and keeps Claude working, turn after turn, until it is met. After each turn, a separate small, fast model checks whether the condition holds, so completion "is decided by a fresh model rather than the one doing the work."
A goal is effectively a session-scoped Definition of Done:
/goal every acceptance check in SPEC.md passes, npm test exits 0, no existing test file is modified, or stop after 30 turns
The documentation's guidance on writing conditions reads like a good Definition of Done checklist: one measurable end state, a stated check such as "npm test exits 0", and the constraints that must not change along the way. It also warns that the evaluator "doesn't run commands or read files independently", judging only what Claude has surfaced in the conversation. That is why the Stop hook still matters: the goal decides whether to keep going, the hook guarantees the checks actually ran.
Before any unattended run, the best-practices guide lists five questions, the first two of which are our definitions in miniature: "Does it know what done looks like?" and "Can it check its own work?"
What You Get for an Afternoon's Configuration
The benefits are not mysterious, but they compound. The most obvious is that "almost right" gets caught by the machine instead of by you on Friday afternoon. The documentation describes the alternative without much sympathy: without a check to run, "that makes you the test suite, and every mistake sits there until you happen to notice it."
Less obviously, the definitions make agent output consistent across people. When the Definition of Ready, the /ready skill, the Stop hook and the reviewer all live in the repository, every developer on the team gets the same gates, and new joiners inherit them on clone. The agent's behaviour stops depending on who happened to write the prompt.
They also make delegation sensible. DORA's finding that AI amplifies what is already there cuts both ways. A team with a written, enforced notion of done is precisely the "strong team" that the report says AI makes better. And a well-formed SPEC.md with runnable acceptance checks is a far better artefact to review in a pull request than a chat transcript.
Finally, they make your own judgement visible. Writing a Definition of Done forces a team to agree what it actually cares about, which is a conversation many teams have been politely avoiding since long before agents arrived.
Keeping the Gates Honest
A few warnings, so you do not swap one dysfunction for another.
Do not let the Definition of Ready become a bureaucratic toll booth. Cohn's stage-gate worry applies to agents too: if /ready demands a design document for a one-line typo fix, people will stop using it. Keep it a guideline you invoke, not a hook that blocks.
Do not put preferences in hooks. The documentation's advice runs both ways: "if you have hooks for things that are only preferences, delete them and let Claude decide." Hooks are for the items your team would genuinely refuse to merge without.
Do not let the files rot. If two instructions contradict each other, the memory documentation warns, "Claude may pick one arbitrarily". Review both definitions when your build or test commands change, and run /doctor prompt-audit to have Claude look for stale or conflicting instructions.
And do not mistake the hook for the whole Definition of Done. Exit codes prove the code compiles and the tests pass. They cannot prove the tests are the right tests. That is still your job, and it is the job the reviewer subagent and your own reading of the diff are for. The documentation's own table is clear about who has the last word: not Claude's summary of what it did, but branch protection and a person who approves the merge.
The Fire Door Principle
Nobody admires a fire door. Nobody writes conference talks about checklists. But the reason the Scrum Guide insists that work not meeting the Definition of Done "cannot be released" is the same reason Anthropic's own engineers ended up forbidding their agent from editing its tests: left to judge its own work, any worker, human or otherwise, will occasionally decide that close enough is fine.
Coding agents have made the cost of producing code very low. They have not made the cost of shipping wrong code any lower. The Definition of Ready and the Definition of Done are how you move the expensive part, deciding what right looks like, to the beginning and the end of the loop, where you control it, and let the agent get on with the middle. Write them down, wire them in, and the next time your agent tells you all the tests pass, you will already have seen the output.
References and Sources
- Young, Justin (Anthropic). "Effective harnesses for long-running agents." Anthropic Engineering, 26 November 2025. https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- Schwaber, Ken; Sutherland, Jeff. "The Scrum Guide: The Definitive Guide to Scrum: The Rules of the Game." November 2020. https://scrumguides.org/scrum-guide.html
- Agile Alliance. "Definition of Ready." Agile Glossary. https://www.agilealliance.org/glossary/definition-of-ready/
- Wake, Bill. "INVEST in Good Stories, and SMART Tasks." XP123, 17 August 2003 (postscript added 16 February 2011). https://xp123.com/invest-in-good-stories-and-smart-tasks/
- Cohn, Mike. "The Dangers of a Definition of Ready." Mountain Goat Software, last updated 28 June 2023. https://www.mountaingoatsoftware.com/blog/the-dangers-of-a-definition-of-ready
- Stack Overflow. "2025 Developer Survey: AI." Stack Overflow, 2025. https://survey.stackoverflow.co/2025/ai
- Donovan, Ryan. "The results of the 2026 Developer Survey are here!" Stack Overflow Blog, 6 October 2026. https://stackoverflow.blog/2026/10/06/the-results-of-the-2026-developer-survey-are-here/
- Harvey, Nathen; DeBellis, Derek (DORA, Google Cloud). "Announcing the 2025 DORA Report: State of AI-Assisted Software Development." Google Cloud Blog, 23 September 2025. https://cloud.google.com/blog/products/ai-machine-learning/announcing-the-2025-dora-report
- Becker, Joel; Rush, Nate; Barnes, Beth; Rein, David (METR). "Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity." METR, 10 July 2025. https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/
- Becker, Joel; Rush, Nate; Cunningham, Tom; Rein, David; Mahamud, Khalid (METR). "We are Changing our Developer Productivity Experiment Design." METR, 24 February 2026. https://metr.org/blog/2026-02-24-uplift-update/
- Anthropic. "How Claude remembers your project." Claude Code Documentation. https://code.claude.com/docs/en/memory
- Anthropic. "Best practices for Claude Code." Claude Code Documentation. https://code.claude.com/docs/en/best-practices
- Anthropic. "Automate actions with hooks." Claude Code Documentation. https://code.claude.com/docs/en/hooks-guide
- Anthropic. "Hooks reference." Claude Code Documentation. https://code.claude.com/docs/en/hooks
- Anthropic. "Extend Claude with skills." Claude Code Documentation. https://code.claude.com/docs/en/skills
- Anthropic. "Create custom subagents." Claude Code Documentation. https://code.claude.com/docs/en/sub-agents
- Anthropic. "Keep Claude working toward a goal." Claude Code Documentation. https://code.claude.com/docs/en/goal
Tim Green
UK-based Systems Theorist & Independent Technology Writer
Tim explores the intersections of artificial intelligence, decentralised cognition, and posthuman ethics. His work, published at smarterarticles.co.uk, challenges dominant narratives of technological progress while proposing interdisciplinary frameworks for collective intelligence and digital stewardship.
His writing has been featured on Ground News and shared by independent researchers across both academic and technological communities.
ORCID: 0009-0002-0156-9795
Email: tim@smarterarticles.co.uk
Listen to the free weekly SmarterArticles Podcast

Top comments (0)