Goal or Loop
Pick the right autonomy primitive for a task, then hand back a command the user
can paste cold into a fresh session.
/goal and /loop look interchangeable ("run this until it's done") but fail in
opposite ways when mismatched. This skill teaches the decision, not the constants.
When to Use This Skill
Use this skill when the user has a task they want to run autonomously but has
not yet chosen the mechanism and asks things like:
- "Should I use /goal or /loop for this?"
- "Is this a goal or a loop?"
- "What's the best way to run this until it's done / until it converges?"
- "Set this up to run autonomously / unattended until X is true."
- "Keep working on this until done."
Do not use this skill when:
- The user already typed
/loop or /goal (the choice is made — help them with that command directly).
- The ask is plainly "set up a recurring task / poll every N min / watch-mode" → that is the
loop-patterns skill.
- The ask is "schedule a task that survives the session closing / runs in the cloud" → that is the
schedule skill (/schedule).
The Two Commands (what makes them differ)
|
/goal <condition> |
/loop [interval] <prompt> |
| Core idea |
Work turn-after-turn until a condition verifies |
Run a prompt on a cadence, or wait on an external clock |
| Who decides "done" |
A separate small judge model reads the transcript each turn |
Cadence fires, or the model omits the next wakeup to stop |
| What the judge can see |
Transcript text only — cannot run commands or read files; can be spoofed by a fabricated success string |
n/a |
| Run shape |
Single continuous run, context grows; runs unattended, no mid-run approval |
Interval mode = session cron; self-paced = model picks delay at runtime |
| Lifetime |
Ends on verify / impossible / max-turns cap / /goal clear |
Session-scoped (dies when session closes); auto-expires after about a week |
| Best for |
"Keep going until X is objectively, transcript-provably true" |
Polling / watch-mode / waiting on something that changes on its own clock |
Full mechanics and the constants that can drift: see decision-table.md
and the drift note in maintenance.md.
The Decision Procedure
Run the gates in order. Stop at the first one that resolves.
Gate 0 — Does this even need autonomy?
Recommend NEITHER and name the better primitive when the task:
| Situation |
Better primitive |
| Completes in a single turn / one-shot |
Just prompt normally |
| Needs human judgment mid-run |
Plan mode, or interactive work |
| Is a bounded delegate-and-return job |
A subagent |
| Is cadence work that must survive the session ending |
/schedule (not /loop) |
| Is destructive AND would run unsupervised |
Interactive work with approval |
| Is watching for an event that can be streamed/pushed (a log line, a CI result) |
the Monitor tool (streams output, no polling) or Channels (CI pushes the event in) — often more token-efficient than a polling /loop |
Do not force a fit. A function to write, a question to answer, a refactor you'll
review as it goes — none of these want /goal or /loop.
Before recommending /goal, note its requirements (it is a session-scoped
Stop hook): a trusted workspace, and hooks must be enabled — /goal is
unavailable if disableAllHooks (any settings level) or allowManagedHooksOnly
(managed settings) is set. If you know the environment blocks hooks (e.g. a
locked-down/CI/managed setup), say so and prefer /loop or a manual approach.
Gate 1 — Adaptive interview (only when underspecified)
If the input already names a clear done-signal or a cadence, skip this gate.
Otherwise ask a short batch (max ~3 questions) covering only the gaps:
- What is the objective, concretely?
- What is the done-signal (or the cadence)?
- Will you keep this session open? (session-scoped vs survives-close)
- Does it mutate state — writes, deletes, deploys?
Ask only what is missing. Do not interrogate a well-specified task.
Gate 2 — Classify
| The task is... |
Verdict |
| A verifiable end-state, provable from the transcript alone, no waiting on an external clock |
/goal |
| Cadence-driven, OR satisfying it requires waiting on an external clock (even if a clean end-state exists) |
/loop |
| Has BOTH a terminal deliverable AND an ongoing watch/maintenance clause |
SEQUENCE (/goal then /loop) |
External-clock precedence: when the work must wait on something that changes
on its own schedule, cadence wins regardless of end-state. "Poll the build until
it goes green" has an end-state ("green") but you are waiting on CI's clock →
that is /loop, not /goal.
Actor-vs-clock test (apply before invoking external-clock precedence). Ask:
who makes progress between ticks — an external system, or the agent?
- External system advances it (CI is compiling, a deploy pipeline you don't
control is rolling out, a queue drains itself) → genuine external clock →
/loop.
- The agent advances it (the agent itself runs
./deploy.sh, reads the
failure, fixes it, re-runs) → there is no external clock; this is iterative
convergence → /goal (fragile if the proof is world-state). "Run until the
deploy succeeds" where the agent runs the deploy is a fragile /goal, not a
/loop — the agent is the actor, not a waiter. Do not mislabel agent-driven
retry-and-fix as external-clock waiting.
Evidence-source check — gate before emitting ANY /goal
Classify how the done-condition would be proven:
| Evidence source |
Example |
Verdict |
| Self-validating in-transcript |
test runner pass/fail, a diff, a grep count, a file the model wrote then re-read |
/goal is safe |
| World-state relayed |
deploy status, DB migrated, remote API behavior |
/goal is fragile — the judge cannot verify and can be spoofed |
| Unobservable from text |
"looks clean", "feels fast", "code is good" |
/goal is wrong |
- Fragile → require the condition to include verbatim command output, and warn the user to spot-check. (Or route to
/loop / interactive.)
- Wrong → refuse
/goal. Route to NEITHER / interactive work and say why.
Output Format (strict)
Emit exactly this shape. The fence must be self-contained and paste-cold-ready.
- Rationale — 1-2 lines, plain text, above the fence. Name the pick and why. NEVER an in-band comment. Do not restate the command in prose above the fence, and do not write two rationale blocks — one tight reason, then the fence. (The craft lives inside the condition, not in a longer preamble.)
- Fenced block — the literal command ONLY. No comments, no prose, no
# line, nothing else inside the fence.
- Stewardship note — plain text, below the fence: how it terminates, how to stop it, where to see it is still running, and its cost/duration shape qualitatively (no fabricated dollar figures).
For a SEQUENCE, emit two ordered fenced blocks with a plain-text note:
"run block 1; when it ends, run block 2."
Copy-paste skeletons for each verdict: prompt-blocks.md.
Validate any emission against the hard rules: run scripts/check-emission.sh.
Rules the fenced block MUST obey
- The block contains ONLY the literal command.
/loop reads the first whitespace token to choose interval-vs-self-paced; a leading comment (/loop # note\n5m foo) silently misparses into self-paced mode. Neither command has comment syntax. Put nothing before or inside the command.
- Self-contained. Name the repo / branch / files / acceptance criteria inline. Never "the X we discussed" — it must work pasted into a fresh session.
- Do not encode second-level timing constants (e.g. 270 / 300 / 1200 / 3600) in a self-paced prompt — the model picks the delay at runtime within the tool's clamp.
Craft checklist — what makes the emitted command PERFORM
The condition/prompt quality is the product. A weak one wastes the whole run.
/goal (a separate small judge reads only the transcript each turn):
- Literal success predicate — quote the exact command + exact pass string/exit (
`pnpm test` exits 0 with 0 failures), never "it works".
- Proof artifact — tell the working model what to paste into the transcript (test summary,
tsc output, grep count). No surfaced proof → the judge can never confirm → burns turns to the cap.
- Side-effect guard — when the task mutates code, add "and no test file is modified" / "nothing outside
src/ changes" so it can't be met by cheating.
- Right-sized turn cap — mechanical ≈ 6–10, multi-file migration ≈ 15–25. Not a fixed default.
/loop (each tick re-reads fresh):
- Cadence — pin an interval ONLY when the user states one ("every 5 minutes") or there is a true fixed external rhythm. When the loop should stop the instant a state resolves (poll CI until it's done, watch for an event), self-pace — do not invent an interval; a fixed clock just polls a resolved state. Default to self-pacing when unsure.
- One idempotent action per tick, with the exact command.
- Explicit stop / omit-the-next-wakeup condition — the #1 cause of zombie loops is no exit. Omitting the wakeup MEANS stop — only use "omit the next wakeup" on the done/terminal branch. The keep-going branch must say "report and wait for the next tick", never "omit the wakeup and check again" (self-contradictory — it would end the loop).
- Hard bound beyond the ~1-week auto-expiry when open-ended ("stop at end of day", "after 20 checks").
Full skeletons per verdict: prompt-blocks.md.
Red Flags — STOP Immediately
Resources
- decision-table.md — full mechanics of both commands, the classification matrix, and worked examples per verdict.
- maintenance.md — drift note:
/goal and /loop are built into the Claude Code binary; their constants and parsing can change between versions. The decision logic is the durable part.
- prompt-blocks.md — fill-in skeletons for /goal, /loop cron, /loop self-paced, and sequence.
scripts/check-emission.sh — asserts a candidate emission obeys the hard rules (fence holds only the command, /loop interval is first token, stop affordance present).
1---2name: goal-or-loop3description: Decides between the Claude Code /goal and /loop commands for a rough task, then emits a copy-paste-ready command block. Use when the mechanism is NOT yet chosen, for asks like should I use /goal or /loop, is this a goal or a loop, what is the best way to run this until it is done, set this up to run autonomously until X, or keep working on this unattended until it converges. Picks /goal (verifiable end-state provable from the transcript), /loop (cadence or waiting on an external clock), BOTH in sequence (terminal deliverable plus ongoing watch), or NEITHER (one-shot, needs human judgment, or unobservable). Triggers on keywords goal, loop, autonomously, until done, unattended, converge. Does NOT claim plain set up a recurring task / cron / poll every N minutes (that is loop-patterns) or schedule work that survives the session (that is schedule); and does NOT fire once the user has already typed /loop or /goal.4---56# Goal or Loop78Pick the right autonomy primitive for a task, then hand back a command the user9can paste cold into a fresh session.1011`/goal` and `/loop` look interchangeable ("run this until it's done") but fail in12opposite ways when mismatched. This skill teaches the decision, not the constants.1314## When to Use This Skill1516Use this skill when the user has a task they want to run autonomously but has17**not yet chosen the mechanism** and asks things like:1819- "Should I use /goal or /loop for this?"20- "Is this a goal or a loop?"21- "What's the best way to run this until it's done / until it converges?"22- "Set this up to run autonomously / unattended until X is true."23- "Keep working on this until done."2425Do **not** use this skill when:2627- The user already typed `/loop` or `/goal` (the choice is made — help them with that command directly).28- The ask is plainly "set up a recurring task / poll every N min / watch-mode" → that is the `loop-patterns` skill.29- The ask is "schedule a task that survives the session closing / runs in the cloud" → that is the `schedule` skill (`/schedule`).3031## The Two Commands (what makes them differ)3233| | `/goal <condition>` | `/loop [interval] <prompt>` |34|---|---|---|35| Core idea | Work turn-after-turn until a condition **verifies** | Run a prompt on a **cadence**, or wait on an **external clock** |36| Who decides "done" | A separate small **judge** model reads the transcript each turn | Cadence fires, or the model **omits the next wakeup** to stop |37| What the judge can see | **Transcript text only** — cannot run commands or read files; can be **spoofed** by a fabricated success string | n/a |38| Run shape | Single continuous run, context grows; runs **unattended**, no mid-run approval | Interval mode = session cron; self-paced = model picks delay at runtime |39| Lifetime | Ends on verify / impossible / max-turns cap / `/goal clear` | Session-scoped (dies when session closes); auto-expires after about a week |40| Best for | "Keep going until X is objectively, **transcript-provably** true" | Polling / watch-mode / waiting on something that changes on its own clock |4142Full mechanics and the constants that can drift: see [decision-table.md](references/decision-table.md)43and the drift note in [maintenance.md](references/maintenance.md).4445## The Decision Procedure4647Run the gates in order. Stop at the first one that resolves.4849### Gate 0 — Does this even need autonomy?5051Recommend **NEITHER** and name the better primitive when the task:5253| Situation | Better primitive |54|---|---|55| Completes in a single turn / one-shot | Just prompt normally |56| Needs human judgment mid-run | Plan mode, or interactive work |57| Is a bounded delegate-and-return job | A subagent |58| Is cadence work that must **survive the session ending** | `/schedule` (not `/loop`) |59| Is destructive AND would run unsupervised | Interactive work with approval |60| Is **watching for an event** that can be streamed/pushed (a log line, a CI result) | the **Monitor tool** (streams output, no polling) or **Channels** (CI pushes the event in) — often more token-efficient than a polling `/loop` |6162Do not force a fit. A function to write, a question to answer, a refactor you'll63review as it goes — none of these want `/goal` or `/loop`.6465**Before recommending `/goal`, note its requirements** (it is a session-scoped66Stop hook): a **trusted workspace**, and hooks must be enabled — `/goal` is67unavailable if `disableAllHooks` (any settings level) or `allowManagedHooksOnly`68(managed settings) is set. If you know the environment blocks hooks (e.g. a69locked-down/CI/managed setup), say so and prefer `/loop` or a manual approach.7071### Gate 1 — Adaptive interview (only when underspecified)7273If the input already names a clear **done-signal** or a **cadence**, skip this gate.7475Otherwise ask a short batch (max ~3 questions) covering only the gaps:7677- What is the objective, concretely?78- What is the done-signal (or the cadence)?79- Will you keep this session open? (session-scoped vs survives-close)80- Does it mutate state — writes, deletes, deploys?8182Ask only what is missing. Do not interrogate a well-specified task.8384### Gate 2 — Classify8586| The task is... | Verdict |87|---|---|88| A verifiable end-state, provable **from the transcript alone**, no waiting on an external clock | **/goal** |89| Cadence-driven, OR satisfying it requires **waiting on an external clock** (even if a clean end-state exists) | **/loop** |90| Has BOTH a terminal deliverable AND an ongoing watch/maintenance clause | **SEQUENCE** (/goal then /loop) |9192**External-clock precedence:** when the work must wait on something that changes93on its own schedule, cadence wins regardless of end-state. "Poll the build until94it goes green" has an end-state ("green") but you are **waiting on CI's clock** →95that is `/loop`, not `/goal`.9697**Actor-vs-clock test (apply before invoking external-clock precedence).** Ask:98*who makes progress between ticks — an external system, or the agent?*99100- **External system advances it** (CI is compiling, a deploy pipeline you don't101 control is rolling out, a queue drains itself) → genuine external clock → `/loop`.102- **The agent advances it** (the agent itself runs `./deploy.sh`, reads the103 failure, fixes it, re-runs) → there is **no external clock**; this is iterative104 convergence → `/goal` (fragile if the proof is world-state). "Run until the105 deploy succeeds" where the agent runs the deploy is a **fragile /goal**, not a106 /loop — the agent is the actor, not a waiter. Do not mislabel agent-driven107 retry-and-fix as external-clock waiting.108109### Evidence-source check — gate before emitting ANY /goal110111Classify how the done-condition would be **proven**:112113| Evidence source | Example | Verdict |114|---|---|---|115| Self-validating in-transcript | test runner pass/fail, a diff, a grep count, a file the model wrote then re-read | `/goal` is **safe** |116| World-state relayed | deploy status, DB migrated, remote API behavior | `/goal` is **fragile** — the judge cannot verify and can be spoofed |117| Unobservable from text | "looks clean", "feels fast", "code is good" | `/goal` is **wrong** |118119- **Fragile** → require the condition to include **verbatim command output**, and warn the user to **spot-check**. (Or route to `/loop` / interactive.)120- **Wrong** → refuse `/goal`. Route to NEITHER / interactive work and say why.121122## Output Format (strict)123124Emit exactly this shape. The fence must be self-contained and paste-cold-ready.1251261. **Rationale** — 1-2 lines, plain text, **above** the fence. Name the pick and why. NEVER an in-band comment. Do not restate the command in prose above the fence, and do not write two rationale blocks — one tight reason, then the fence. (The craft lives *inside* the condition, not in a longer preamble.)1272. **Fenced block** — the **literal command ONLY**. No comments, no prose, no `#` line, nothing else inside the fence.1283. **Stewardship note** — plain text, **below** the fence: how it terminates, how to **stop** it, where to see it is still running, and its cost/duration **shape** qualitatively (no fabricated dollar figures).129130For a **SEQUENCE**, emit two ordered fenced blocks with a plain-text note:131"run block 1; when it ends, run block 2."132133Copy-paste skeletons for each verdict: [prompt-blocks.md](assets/prompt-blocks.md).134Validate any emission against the hard rules: run `scripts/check-emission.sh`.135136### Rules the fenced block MUST obey137138- **The block contains ONLY the literal command.** `/loop` reads the **first whitespace token** to choose interval-vs-self-paced; a leading comment (`/loop # note\n5m foo`) silently misparses into self-paced mode. Neither command has comment syntax. Put nothing before or inside the command.139- **Self-contained.** Name the repo / branch / files / acceptance criteria **inline**. Never "the X we discussed" — it must work pasted into a fresh session.140- **Do not encode second-level timing constants** (e.g. 270 / 300 / 1200 / 3600) in a self-paced prompt — the model picks the delay at runtime within the tool's clamp.141142### Craft checklist — what makes the emitted command PERFORM143144The condition/prompt quality is the product. A weak one wastes the whole run.145146**/goal** (a separate small judge reads **only the transcript** each turn):147148- **Literal success predicate** — quote the exact command + exact pass string/exit (`` `pnpm test` exits 0 with 0 failures ``), never "it works".149- **Proof artifact** — tell the working model what to **paste into the transcript** (test summary, `tsc` output, grep count). No surfaced proof → the judge can never confirm → burns turns to the cap.150- **Side-effect guard** — when the task mutates code, add "and no test file is modified" / "nothing outside `src/` changes" so it can't be met by cheating.151- **Right-sized turn cap** — mechanical ≈ 6–10, multi-file migration ≈ 15–25. Not a fixed default.152153**/loop** (each tick re-reads fresh):154155- **Cadence** — pin an interval ONLY when the user states one ("every 5 minutes") or there is a true fixed external rhythm. When the loop should **stop the instant a state resolves** (poll CI until it's done, watch for an event), **self-pace** — do not invent an interval; a fixed clock just polls a resolved state. Default to self-pacing when unsure.156- **One idempotent action per tick, with the exact command.**157- **Explicit stop / omit-the-next-wakeup condition** — the #1 cause of zombie loops is no exit. **Omitting the wakeup MEANS stop** — only use "omit the next wakeup" on the *done/terminal* branch. The *keep-going* branch must say "report and wait for the next tick", never "omit the wakeup and check again" (self-contradictory — it would end the loop).158- **Hard bound** beyond the ~1-week auto-expiry when open-ended ("stop at end of day", "after 20 checks").159160Full skeletons per verdict: [prompt-blocks.md](assets/prompt-blocks.md).161162## Red Flags — STOP Immediately163164<rationalization_defense>165| Thought | Reality |166|---|---|167| "It says 'until it's good' — I'll set a /goal." | Unobservable from text. The judge sees transcript only and will loop forever or be spoofed. Refuse → NEITHER. |168| "It has an end-state ('until green'), so /goal." | If reaching it means **waiting on an external clock** (CI, a deploy), cadence wins. Use /loop. |169| "I'll drop a `# poll every 5m` comment in the block so it's clear." | `/loop` parses the first token; a leading comment misparses it into self-paced mode. Rationale goes ABOVE the fence, never inside. |170| "I'll reference 'the tests we discussed' to keep it short." | The block must paste cold into a fresh session. Name files/branch/criteria inline. |171| "The deploy goal is fine, the judge will read the output." | World-state is relayed, not verified — spoofable. Require verbatim output + a spot-check warning, or route away. |172| "They want it recurring forever, so /loop." | If it must survive the session closing, /loop dies with the session. Route to /schedule. |173| "This one-liner should run as a /goal to be safe." | One-shot tasks need neither. Just prompt normally. Don't force a fit. |174| "I'll skip the stop note, they'll figure it out." | Every emission needs a stop/status affordance outside the fence — unattended runs are hard to kill blind. |175</rationalization_defense>176177## Resources178179- [decision-table.md](references/decision-table.md) — full mechanics of both commands, the classification matrix, and worked examples per verdict.180- [maintenance.md](references/maintenance.md) — drift note: `/goal` and `/loop` are built into the Claude Code binary; their constants and parsing can change between versions. The decision logic is the durable part.181- [prompt-blocks.md](assets/prompt-blocks.md) — fill-in skeletons for /goal, /loop cron, /loop self-paced, and sequence.182- `scripts/check-emission.sh` — asserts a candidate emission obeys the hard rules (fence holds only the command, /loop interval is first token, stop affordance present).