Repository navigation
Goal
This page tells how the goal slice of the core plugin claudetto works.
A user reads it to set a goal with /goal.
A contributor reads it before an edit of slices/goal/.
The slice replaces the built-in /goal with a goal engine.
A goal is a list of steps.
Each step has a title and a list of checks.
At the end of each turn, the engine runs the checks of the current step.
If a check fails, the engine starts the next turn with only the failing checks.
If all checks pass, the engine goes to the next step.
After the last step, the goal is done and the engine clears the state.
The built-in evaluator reads only the conversation, so it cannot run a check. The engine can run a command, read a file, or ask a small model.
The state is in .claudetto/goal.json of the project root.
/goal answers with no model turn.
The text after /goal is one of these:
| Text | Effect |
|---|---|
| A condition | Makes a goal of one step and starts the first turn. |
A name that ends in .md
|
Makes a goal from the steps of that plan file. |
status or nothing |
Shows the step, each check with its last result, and the limits. |
pause |
Pauses the goal. |
resume |
Resumes a paused goal from its current step. The counts of turns and cost restart. |
skip |
Skips the current step. |
step N |
Moves to step N, from 1 to the count of steps. |
clear |
Clears the goal. |
The typeahead and /help show the text of the goal engine for /goal.
| Kind | Passes when |
|---|---|
run |
The command exits with 0. The engine runs it with sh -c in the project root. |
file |
The file exists, and it holds the text when the check has one. |
judge |
A small model answers yes to the claim, with the answer of the turn as facts. |
A run check ends after RUN_TIMEOUT_MS (300,000 ms) and counts as failed.
The state keeps the last OUTPUT_TAIL_CHARS (1,500) characters of the output, because the error is at the end.
A judge check that fails to answer counts as failed.
- If the text has only code spans in backticks, with
,,;,and, or spaces between them, each span is aruncheck. - If the text starts with a code span, that span is a
runcheck, and the whole text is onejudgecheck. - Otherwise the whole text is one
judgecheck.
A heading of level 2 or 3 that starts with a number and a point is a step.
For example, ## 8b. Rewrite the page.
Each Check: line below the heading, with an optional - before it, gives the checks of that step by the rules above.
A plan file with no such heading gives an error.
Flags in the text after /goal set the limits.
A value must be a number above 0.
A limit that is left out is no limit, except --stall.
| Flag | Meaning | Default |
|---|---|---|
--max-turns N |
The goal stops after N turns. | None |
--budget $X or N%
|
The goal stops at a cost of X USD, or at N percent of a plan limit. | None |
--until TIME |
The goal stops at HH:MM (the next such time), a date, or a date and time. |
None |
--stall N |
The goal stops after N turns in a row with the same failing checks and output. | 3 (STALL_DEFAULT) |
Digits do not count when the engine compares the output of two turns, so a changed time does not hide a stall.
A stop pauses the goal, writes the reason to the log, and tells Claude the reason (max-turns, budget, until, or stall) and the step.
The user can fix the cause and run /goal resume.
- The hook denies the
ProposeGoaltool and tells Claude that the user sets a goal with/goal. - The
promptslice leaves out thegoal_statusattachment.
| Hook | Filter | What it does |
|---|---|---|
turn.complete |
None | Runs the checks and sets the next prompt. It ignores a subagent turn, a turn that is not an answer, and a paused goal. |
command.run |
/goal |
Answers the command. |
command.describe |
/goal |
Gives the text of the engine. |
tool.call |
ProposeGoal |
Denies the tool. |
The goal slice makes /goal run real checks.
A goal is a list of steps, and each step has checks, such as a command that must pass.
Claude keeps working until the checks pass.
claudetto
- Start
- Slices
- Add-Ons
- Reference
- Rationale
- Evidence
- Development
Claude Code