Goal mode turns a single objective into a self-driving session. Set a goal once with /goal <objective>, and after every turn omp injects a hidden continuation steer that re-submits the same objective. The loop stops when the model calls the goal tool with op: "complete" and proves each deliverable, when the token budget runs out, or when you pause or drop it.
It is the right tool when the next step is obvious but the total amount of work is not — long migrations, fan-out cleanup, “keep going until the test suite is green”. For one-shot drafting use /plan; for blindly resubmitting the same prompt N times use /loop.
Starting a goal
Goal mode is gated by the goal.enabled setting, which is on by default. Start one with:
/goal port the importer to streaming and update the call sitesomp pins the objective to the session, injects the goal tool into the active tool set, and submits the objective as your first turn. The text you pass becomes the literal <objective> block the model sees on every continuation, so write it like a brief: the deliverables, the success criteria, anything that disqualifies a shortcut.
Omit the argument and /goal opens a multi-line editor for the objective instead.
Subcommands
All operate on the current session’s goal. /goal with no subcommand opens an interactive menu against the active or paused goal.
| Command | Effect |
| ----------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| /goal set <objective> | Set or replace the objective. Refuses while a goal is paused; resume or drop it first. |
| /goal show | Print objective, status, tokens used / budget / remaining, and elapsed time. |
| /goal pause | Stop continuation steers. Usage accounting freezes; the goal record stays in the session. |
| /goal resume | Re-enable continuation and schedule the next steer. |
| /goal drop | Remove the goal record after a confirmation. Accumulated usage stays in the session log. |
| /goal budget <N\\ | off> | Replace the token budget. N is a positive integer of total tokens; off clears the cap. |
/goal while a goal is already active opens the management menu (Show details, Adjust budget…, Pause, Drop); against a paused goal the menu offers Resume first.
Budgets bound the loop
Without a budget, goal mode runs until the model decides it is done. That is rarely what you want for an unattended session. Cap it with /goal budget 200000; the model can also set its own cap by passing token_budget when it creates the goal via the goal tool.
The budget counts input, output, and cache-write tokens against the goal across every turn it stays active (cache reads are excluded — they’re reused prefix, not new work). When usage crosses the cap, the status flips to budget-limited and the next continuation steer is replaced with a wrap-up prompt: the model is told not to start new substantive work, to summarise progress, and to surface remaining work and blockers. Budget exhaustion is explicitly not completion — the model is instructed to leave the goal active rather than call complete to escape the cap.
Raise the budget with /goal budget <N> and the loop resumes. Set off to remove the cap entirely.
Inspecting and cancelling
/goal show is the read path. It prints the live objective, the goal status (active, paused, budget-limited, complete, dropped), tokens used against the budget, tokens remaining, and elapsed seconds.
To stop the loop:
-
Escaborts the current turn and pauses the goal;/goal resumere-enables continuations. -
/goal pausehalts continuations without losing the objective or its usage history. -
/goal dropends the goal entirely after a confirmation.
The goal survives session compaction and /branch / /fork. Switching working directory with /move keeps the goal attached to the session, not the directory.
How it differs from plain prompting
In a normal session, omp stops after each turn and waits for you. In goal mode, three things change while the goal is active:
-
A
<goal_context>block is injected ahead of every prompt with the objective and live budget numbers. -
A hidden
usersteer (suppressed from the visible transcript) is queued after every turn that does not callgoal({op:"complete"}). -
A
goaltool is forced into the active tool set. The model usesgoal({op:"get"})to read its own budget andgoal({op:"complete"})to end the loop after verifying every deliverable against current repo state.
The completion prompt is intentionally strict: the model is told to restate the objective as concrete deliverables, map each one to file or command evidence, and re-read the actual current state before claiming done. A narrow check does not prove a broad claim.
When to use which
-
/goalwhen the objective spans multiple turns and the model should decide when it is finished. Verifies completion. Budget-aware. -
/loopwhen you have one prompt that should re-submit a fixed number of times or for a wall-clock window. No objective, no completion semantics. Useful for “run my test suite five times and report flakes”. -
/planwhen you want a read-only drafting pass against the plan-role model before any edits happen. One turn, then a structured handoff to the executor.
You can combine them: start with /plan to scope the work, accept the plan, then /goal against the resulting brief for the long tail of execution.
Related
-
Plan mode — sandboxed drafting before execution.
-
Sessions — session lifecycle, branching, and where goal state lives.
-
Slash commands — the full
/-command reference.