Keep proto working toward a goal
Set a completion condition with /goal and proto keeps working across turns until the condition is met. After every turn the configured model (Config.getModel()) checks the transcript against your condition; if it isn’t satisfied yet, proto starts another turn instead of returning control. The goal clears automatically once the condition is met.
[!note] Today the evaluator uses the same model your main turns use. When protoCLI exposes a small/fast-model accessor, this will switch over so evaluations are cheaper. Token cost shows up under “eval tokens” in
/goalstatus.
Use a goal for 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
Set a goal
Run /goal followed by the condition you want satisfied.
/goal all tests in test/auth pass and the lint step is cleanSetting a goal starts a turn immediately, with the condition itself as the directive — you do not need to send a separate prompt. While the goal is active, the evaluator’s most recent reason is shown on /goal so you can see what proto is working toward.
[!note] One goal can be active per session. Running
/goal <new condition>replaces the previous one.
The condition can be up to 4,000 characters. To bound how long a goal runs, include a clause like or stop after 20 turns directly in the condition.
Write an effective condition
The evaluator only sees what proto has surfaced in the transcript — tool calls and the final assistant message. Write the condition so that proto’s own output can demonstrate it.
A good condition usually has:
- One measurable end state: a test result, a build exit code, a file count, an empty queue.
- A stated check: how proto should prove it, such as
npm test exits 0orgit status is clean. - Constraints that matter: anything that must not change on the way there, such as
no other test file is modified.
“All tests in test/auth pass” works because proto runs the tests and the result lands in the transcript for the evaluator to read. “The code is good” does not, because nothing in the transcript can prove it.
Check status
Run /goal with no arguments to inspect the current state.
/goalIf a goal is active, the status shows the condition, how long it has been running, how many turns have been evaluated, the tokens spent on evaluation so far, and the evaluator’s most recent reason. If no goal is active but one ended earlier in the session, the status reports the most recent outcome: a goal that was achieved (with how long it took) or one that was abandoned as impossible (with the reason it was deemed unachievable — see How evaluation works).
Clear a goal
Run /goal clear to remove an active goal before its condition is met. Any of stop, off, reset, none, and cancel are accepted as aliases for clear. Starting a new conversation with /clear also removes any active goal.
/goal clearHow evaluation works
Each time the main agent finishes a turn, the condition and the conversation so far are sent to your configured content generator for a one-shot evaluator call. The evaluator returns one of three verdicts and a short reason:
- Met — clears the goal and records the achieved entry on
/goal. - Not met — proto keeps working, passing the reason as guidance for the next turn.
- Impossible — the condition is genuinely unachievable in this session (it is self-contradictory, depends on a resource or capability that isn’t available, or every reasonable approach has been exhausted with no path forward). Proto stops the autonomous loop and records the goal as abandoned, rather than looping forever on something it can never satisfy.
The “impossible” verdict is deliberately conservative: the assistant claiming a goal is impossible counts as evidence, not proof, and the evaluator independently confirms it. Slow progress or temporarily missing evidence is treated as “not met”, not “impossible”.
The evaluator does not call tools, so it can only judge what proto has already surfaced in the conversation. If the evaluator can’t tell from the transcript, treat it as “not met” and ask for the missing evidence.
How /goal differs from /loop
| Trigger for next turn | /goal | /loop |
|---|---|---|
| When it fires | Previous turn ends | A time interval elapses |
| When it stops | The evaluator confirms the condition is met | You cancel it, or proto decides the work is done |
| Best for | Verifiable end states | Polling / babysitting on a cadence |
See Schedule prompts for /loop.
See also
- Schedule prompts — re-run a prompt on a time interval
- Use hooks — write your own Stop hook when you need custom evaluation logic