# Claude Code's /goal: Set a Condition, Walk Away. A practical guide

> Source: <https://corti.com/claude-codes-goal-set-a-condition-walk-away-a-practical-guide/>
> Published: 2026-07-14 04:14:52+00:00

# Claude Code's /goal: Set a Condition, Walk Away. A practical guide

Claude Code has always been turn-based: you prompt, Claude works, control returns to you. That model breaks down for long-running work — migrations, backlog grinding, "keep fixing until CI is green" — where you end up typing "continue" every few minutes.

The `/goal`

command, introduced in **Claude Code v2.1.139 (May 2026)**, changes that. You declare a completion condition; Claude keeps starting new turns until an independent evaluator confirms the condition is met. No per-turn prompting.

## How it works

`/goal`

is a wrapper around a session-scoped, prompt-based **Stop hook**. The mechanics:

- You set a condition:
`/goal all tests in test/auth pass and the lint step is clean`

. This immediately starts a turn, with the condition itself as the directive — no separate prompt needed. - When Claude finishes a turn, the condition plus the conversation so far are sent to your configured
**small fast model**(Haiku by default). - The evaluator returns a yes/no decision with a short reason.
**No**→ Claude starts another turn, with the reason injected as guidance for what to work on next.** Yes**→ the goal clears and an "achieved" entry is recorded in the transcript.

Two properties are worth internalizing:

**Completion is judged by a fresh model, not the one doing the work.** The main model can't declare itself done; a separate evaluator decides. This avoids the classic failure mode where an agent optimistically stops early.**The evaluator has no tools.** It doesn't run commands or read files. It only sees what Claude has surfaced in the conversation. This directly shapes how you must write conditions (more below).

While a goal is active, a `◎ /goal active`

indicator shows elapsed time, and each evaluation's reason appears in the status view and transcript.

## Basic usage

```
# Set a goal (starts working immediately)
/goal all tests in test/auth pass and the lint step is clean

# Check status: condition, elapsed time, turns evaluated,
# token spend, and the evaluator's most recent reason
/goal

# Stop early (aliases: stop, off, reset, none, cancel)
/goal clear
```

Rules of the road:

- One goal per session. Setting a new one replaces the active one.
- The condition can be up to 4,000 characters.
`/clear`

(new conversation) also removes an active goal.- A goal still active when a session ends is restored on
`--resume`

/`--continue`

, but the turn count, timer, and token-spend baseline reset. Achieved or cleared goals are not restored.

### Non-interactive mode

`/goal`

works in headless (`-p`

) mode, the desktop app, and Remote Control. With `-p`

, the entire loop runs to completion in a single 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.

## Writing conditions that actually work

Because the evaluator can only judge what's in the transcript, the condition must be **demonstrable through Claude's own output**. "All tests in `test/auth`

pass" works: Claude runs the tests, the output lands in the conversation, the evaluator reads it.

A condition that survives many turns has three parts:

**One measurable end state**— a test result, a build exit code, a file count, an empty queue.** A stated check**— how Claude proves it: "`npm test`

exits 0", "`git status`

is clean".**Constraints that must hold on the way there**— "no other test file is modified", "public API signatures unchanged".

Example of a well-formed condition:

```
/goal every module in src/legacy/ is migrated to the v2 client API;
prove it by running `npm run build` (exits 0) and `npm test` (all pass);
no files outside src/legacy/ and test/ are modified;
or stop after 25 turns
```

Note the last clause: **there is no built-in turn or time limit.** A goal runs until the condition is met or you clear it. To bound runtime, put the limit in the condition itself (e.g., `or stop after 20 turns`

) — Claude reports progress against that clause each turn and the evaluator judges it from the conversation.

Anti-patterns:

*"The code is clean and well-structured"*— not measurable; the evaluator will flip-flop or never say yes.*"The production deployment succeeds"*— depends on state the evaluator can't verify and Claude may not be able to demonstrate safely.- Conditions with no bounding clause on open-ended work — an unachievable condition burns tokens indefinitely.

## When `/goal`

makes sense and when it doesn't

**Good fits** — substantial work with a verifiable end state:

- Migrating a module to a new API until every call site compiles and tests pass
- Implementing a design doc until all acceptance criteria hold
- Splitting a large file into focused modules until each is under a size budget
- Working through a labeled issue backlog until the queue is empty

**Poor fits:**

**Single-turn tasks.** If one prompt does it, a goal adds evaluator overhead for nothing.**Work needing human judgment mid-flight**— design decisions, ambiguous requirements. The loop won't pause to ask; it will pick something and keep going.** Subjective end states.**If you can't phrase completion as something a model can verify from terminal output, use normal turns.** Time-driven repetition.**"Re-check every 10 minutes" is`/loop`

, not`/goal`

(see below).**Work that should run without an open session**— nightly tests, morning triage — belongs to scheduled tasks/cloud routines instead.

`/goal`

vs. `/loop`

vs. Stop hooks vs. auto mode

| Approach | Next turn starts when | Stops when |
|---|---|---|
`/goal` | Previous turn finishes | Evaluator model confirms condition met |
`/loop` | A time interval elapses | You stop it, or Claude decides it's done |
| Stop hook | Previous turn finishes | Your own script or prompt decides |
| Auto mode | — (single turn only) | Claude judges the work done |

`/goal`

and a Stop hook both fire after every turn.`/goal`

is the session-scoped shortcut; a Stop hook lives in settings, applies to every session in scope, and can run a**script** for deterministic checks (e.g., actually executing the test suite) instead of a model judgment. If you need custom or deterministic evaluation, write the hook yourself.- Auto mode is complementary, not competing: it auto-approves tool calls
*within*a turn but never starts a new one. Auto mode removes per-tool prompts;`/goal`

removes per-turn prompts. For fully unattended runs you typically want both.

## Catches

**Trust and hooks requirements.** Because the evaluator rides the hooks system,`/goal`

only runs in workspaces where you've accepted the trust dialog. It's unavailable when`disableAllHooks`

is set at any settings level, or when`allowManagedHooksOnly`

is set in managed settings — relevant in enterprise-managed environments. The command tells you why rather than failing silently.**The evaluator is only as good as the transcript.** If Claude claims tests pass without showing output, a lenient evaluation can end the goal prematurely; conversely, if the proof never lands in the conversation, the goal never clears. Bake the proof command into the condition.**No automatic budget.** Turn/time limits are your responsibility, expressed in the condition text.**Unattended = your permission model applies.** A multi-hour autonomous loop executes whatever your tool-approval settings allow. Review your auto-mode/permission configuration before setting a goal and walking away.**Evaluator judgment is probabilistic.** It's a small model making a yes/no call each turn, not a deterministic gate. For hard guarantees, a script-based Stop hook is the stricter tool.

## Costs

Two token streams:

**Main-turn spend**— the dominant cost. A goal is simply many consecutive turns of your main model; a 20-turn goal costs roughly what 20 manually-prompted turns would. Check`/goal`

(no argument) mid-run to see cumulative token spend, and bound runs with a turns clause.**Evaluation spend**— one small-fast-model call per turn (Haiku by default), billed on whichever provider your session uses. Per the docs, this is*typically negligible*compared to main-turn spend.

The real cost risk isn't the evaluator — it's an unbounded or unachievable condition keeping the main model busy. Measurable end state + explicit stop clause is the mitigation.

## Requirements recap

- Claude Code
**v2.1.139+** - Trusted workspace (accepted trust dialog)
- Hooks not disabled (
`disableAllHooks`

unset; no`allowManagedHooksOnly`

restriction) - Works in interactive mode,
`-p`

/headless, the desktop app, and Remote Control
