Skip to content
AGENTIC_ENG
Claude

Claude Code /goal: keep a session running until a fresh model says it's done

AUTHOR:
Bartłomiej Krupa
PUBLISHED:
2026.07.01
EST_READ:
7 min

/goal sets a completion condition and Claude keeps taking turns toward it — no per-turn prompting — until a separate small fast model (Haiku by default) confirms the condition is met. After each turn that evaluator returns yes/no plus a short reason; “no” starts another turn with the reason as guidance, “yes” clears the goal. It’s a session-scoped shortcut over a prompt-based Stop hook. Requires Claude Code v2.1.139+, one active goal per session, condition up to 4,000 characters.

Definitions

/goal — a Claude Code command that sets a completion condition for the current session; the same command sets, checks, and clears it depending on the argument.

Completion condition — the plain-text end state Claude works toward, up to 4,000 characters. Setting it starts a turn immediately, with the condition itself as the directive.

Evaluator — the small fast model (default Haiku) that, after each turn, reads the condition and the conversation so far and returns a yes/no decision plus a short reason. It does not call tools.

Set a goal

Run /goal followed by the condition. Setting it starts a turn right away — you don’t send a separate prompt. A ◎ /goal active indicator shows how long it’s been running. If a goal is already active, the new one replaces it (one per session).

/goal all tests in test/auth pass and the lint step is clean

Write a condition the evaluator can actually verify

This is the whole game. The evaluator judges your condition against what Claude has surfaced in the conversation — it doesn’t run commands or read files on its own. So write the condition as something Claude’s own output can demonstrate. “All tests in test/auth pass” works because Claude runs the tests and the result lands in the transcript for the evaluator to read.

A condition that holds up across many turns has three parts:

PartWhat it isExample
Measurable end stateOne checkable facta test result, a build exit code, a file count, an empty queue
Stated checkHow Claude should prove itnpm test exits 0”, “git status is clean”
ConstraintsWhat must not change on the way”no other test file is modified”

To bound the run, add a turn or time clause — or stop after 20 turns. Claude reports progress against it each turn and the evaluator judges that from the conversation too.

The failure mode is a condition whose proof never reaches the transcript — see the /goal evaluator only reads the transcript. The property that makes a stop rule terminate rather than spin is covered in verifiable completion condition.

Check status, then clear

Run /goal with no argument to see state: the condition, how long it’s run, how many turns were evaluated, current token spend, and the evaluator’s most recent reason. If no goal is active but one was achieved earlier in the session, the status shows that achieved condition with its duration, turn count, and token spend.

/goal

Clear an active goal before it completes with /goal clear. The aliases stop, off, reset, none, and cancel all work, and running /clear to start a new conversation also removes the goal.

/goal clear

Resume behavior: a goal still active when a session ends is restored on --resume or --continue — the condition carries over, but the turn count, timer, and token-spend baseline all reset. A goal that was already achieved or cleared is not restored.

How evaluation works

/goal is a wrapper around a session-scoped prompt-based Stop hook. Each time Claude finishes a turn, the condition and the conversation so far go to your configured small fast model (default Haiku). It returns a yes-or-no decision and a short reason:

  • “no” — Claude keeps working; the reason is passed in as guidance for the next turn.
  • “yes” — the goal clears and an achieved entry is recorded in the transcript.

The evaluator runs on whichever provider your session uses. Because it does not call tools, it can only judge what Claude has already put in the conversation. Evaluation tokens bill on the small fast model and are typically negligible next to main-turn spend.

/goal vs /loop vs Stop hook vs auto mode

Four features keep a session moving; they differ on what starts the next turn and what stops it.

ApproachNext turn starts whenStops when
/goalThe previous turn finishesA model confirms the condition is met
/loopA time interval elapsesYou stop it, or Claude decides work is done
Stop hookThe previous turn finishesYour own script or prompt decides
Auto modeN/A — within a single turnClaude judges the work done

/goal and a Stop hook both fire after every turn; /goal is the session-scoped, type-a-condition version, while a Stop hook lives in settings, applies to every session in scope, and can run a script for deterministic checks. Auto mode is orthogonal: it approves tool calls within a turn but never starts a new one. The two compose — auto mode removes per-tool prompts, /goal removes per-turn prompts — which is what makes an unattended run possible.

Run it unattended

Pair /goal with auto mode and each turn runs without approval prompts, from the first tool call to the evaluator’s verdict. Headless, the whole loop runs in one invocation:

claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"

Ctrl+C interrupts a non-interactive goal before the condition is met. This is the hands-off pattern for a migration or refactor: set a condition like “every call site compiles and npm test exits 0,” turn on auto mode, and let it run until CI-grade checks pass in the transcript. It’s the same explore-then-execute discipline as plan mode, applied to the finish line instead of the start — and it’s one more lever over how the agentic loop fills the context window across a long unattended run.

When it won’t start

/goal runs only where you’ve accepted the workspace trust dialog, because the evaluator is part of the hooks system. It’s also unavailable when disableAllHooks is set at any settings level, or when allowManagedHooksOnly is set in managed settings. In each case the command tells you why instead of silently doing nothing.

Bottom line

/goal turns a verifiable end state into an autonomous loop: Claude works, a fresh Haiku evaluator checks the transcript, and the session keeps running until the condition holds. The only real skill is writing a condition whose proof Claude actually surfaces — the evaluator sees the conversation and nothing else. Get that right, add auto mode, and you have hands-off multi-turn work with a model-checked stop.

FAQ

Does the /goal evaluator run my tests?
No. The evaluator is a prompt-based Stop hook running your small fast model (Haiku by default), and it does not call tools — it only judges what Claude has already surfaced in the conversation. So Claude has to run the checks itself and let the proof land in the transcript: a passing test summary, `npm test` exiting 0, a clean `git status`. If the result never appears in the conversation, the evaluator cannot see it.
Can I run /goal in headless mode?
Yes. `claude -p "/goal <condition>"` runs the whole loop to completion in a single non-interactive invocation; press Ctrl+C to stop it before the condition is met. /goal also works in the desktop app and through Remote Control.
Why won't /goal start?
Three reasons, and the command tells you which: the workspace trust dialog hasn't been accepted (the evaluator is part of the hooks system), `disableAllHooks` is set at any settings level, or `allowManagedHooksOnly` is set in managed settings. It also requires Claude Code v2.1.139 or later.