/goal in Claude Code: let Claude keep working until a condition is met
TL;DR
/goal lets Claude Code work turn after turn until a measurable condition is true, judged by a separate small model. Write conditions with a check command, constraints and a turn limit, and combine with auto mode to run unattended.
You ask Claude Code to "fix every failing test in the auth folder", it fixes a few and stops to ask. You type "keep going", it does a bit more and stops again. Ten times over. The /goal command fixes exactly this: you set a completion condition, and Claude works turn after turn until it's met, without you prompting each step.
How it works
- After each turn, a small fast model (your configured "haiku" model) reads the condition and the conversation and returns one of three verdicts: not yet met (Claude keeps going, using the reason as guidance), met (the goal clears) or impossible (the goal clears, with the reason recorded).
- The nice part: whether the work is "done" is judged by a different model from the one doing it.
- Under the hood,
/goalis a session-scoped, prompt-based Stop hook.
/goal all tests in test/auth pass and the lint step is clean
/goal # status: time running, turns, tokens spent
/goal clear # cancel (stop, off and cancel also work)
Writing an effective condition
The evaluator doesn't run commands or read files; it only judges what Claude has surfaced in the conversation. So a good condition has:
- One measurable end state: a test result, a build exit code, a file count, an empty queue.
- A stated check: for example "
npm testexits 0" or "git statusis clean". - Constraints that matter: for example "no other test file is modified".
- A bound: add "or stop after 20 turns" so it doesn't run forever. Conditions can be up to 4,000 characters.
Compared with /loop and Stop hooks
| Approach | Next turn starts when | Stops when |
|---|---|---|
/goal | The previous turn finishes | The evaluator confirms met or impossible |
/loop | A time interval elapses | You stop it or Claude decides it's done |
| Stop hook | The previous turn finishes | Your script or prompt decides |
/goal doesn't change your permission mode. To run unattended, combine it with auto mode: auto mode removes per-tool prompts, /goal removes per-turn prompts.
Running non-interactively
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week" \
--output-format stream-json --verbose
Without stream-json, output only prints when the loop ends, so it can look stuck.
Risks and caveats
- Vague conditions waste turns: "clean, nice code" isn't measurable; the evaluator may never call it met.
- Cost grows with turns: evaluator cost is usually negligible, but the work turns aren't. Always set a turn limit.
- It stops when there's no progress: if Claude goes several turns without using a tool, Claude Code stops the loop and hands control back to you.
- Errors you must fix clear the goal: exhausted credits, authentication failures, context overflow that compaction can't clear, an unavailable model.
How to apply it
- Dev: Use it for work with a clear end: migrate an API until build and tests pass, split a big file until each piece is under N lines.
- Tech Lead: Provide condition templates for the team (check command, constraints, turn limit) so goals don't run unbounded.
- PM: Write acceptance criteria in measurable form; that's exactly what makes a good goal condition.
Sources & references
- Keep Claude working toward a goal — Claude Code Docs