On this page
Goals
A goal is an objective the agent keeps working on, turn after turn, until it is done. You agree what "done" means first, and the agent can only finish by showing evidence for each point. Use it for work that takes many steps, such as "migrate the tests to the new runner and get them green".
Set a goal
/goal Ship and verify the migration- The agent proposes two to five completion criteria, or asks you a question first if the objective is unclear.
- Tick the ones you want with Space, or type your own, then press Enter. The agent does not start the work until you answer.
- The agent works. When a turn ends with the goal unfinished, it carries on by itself.
- When it believes it is done, it must cite evidence for every criterion: a command's output, a file, a test result. If it cannot, the goal stays open.
The goal shows at the top of the sidebar while it runs. An objective can be up to 4,000 characters. Setting a new goal replaces the current one.
Check, pause or stop a goal
Run /goal on its own to see the goal's status and its controls. Or type the control directly:
| Command | Does |
|---|---|
/goal status |
Show where the goal stands |
/goal pause |
Stop carrying on by itself. Progress is kept |
/goal resume |
Allow it again; your next message continues it |
/goal edit |
Put the objective in the prompt to change it |
/goal complete |
Mark it done yourself |
/goal block |
Mark it blocked yourself |
/goal clear |
Remove it, after you confirm |
Only these exact words are controls. /goal pause the old cron jobs is a new objective, so you
cannot clear or pause a goal by accident while describing one.
To stop the turn that is running right now, press Esc twice as usual. The goal stays set.
When does a goal stop by itself?
| It stops when | Then |
|---|---|
| Every criterion has evidence | It is complete. Choose to edit it, start a new one, clear it or dismiss |
| It has carried on 20 times without you | It pauses. Send a message or /goal resume |
| It has used its token budget | It pauses |
| The same blocker came back on three separate turns | It reports itself blocked |
| It needs an answer from you | It waits for your message |
| You have not agreed on its criteria | It pauses, waiting for you to agree on them |
| The Haarness server restarted | It waits for your message instead of carrying on unseen |
Set limits
In your configuration, haarness.json:
{
"experimental": {
"goal_harness": {
"max_turns": 20, // turns it may take by itself after your message
"token_budget": 400000 // optional; leave it out for no token limit
}
}
}The token count includes input that was not served from cache, plus output. Both values must be greater than zero.
Run a goal from a script
haarness run --goal "Ship and verify the migration"The criteria are settled without asking you, and the command exits successfully only if the goal was achieved. See Headless runs.
Next
- Reasoning and ultracode: give hard goals more thinking and child agents