Appearance
Persistent goals
/goal gives Hermes a standing objective that survives across turns. After each turn a lightweight judge model checks whether the goal is satisfied; if not, Hermes automatically feeds itself a continuation prompt and keeps working, until the goal is achieved, you pause it, or the turn budget runs out. It is Hermes' take on the "Ralph loop."
This is the feature for tasks where you would otherwise have to say "keep going" three times.
When to use it
- "Fix every lint error in
src/and verifyruff checkpasses" - "Port feature X from repo Y, including tests, and get CI green"
- "Build a small CLI to rename files by their EXIF dates, then test it against the photos/ folder"
A one-turn task doesn't need /goal. An iterate-until-done task is exactly where it shines.
Quick start
/goal Fix every failing test in tests/ and make sure the suite passesWhat you'll see:
⊙ Goal set (20-turn budget): Fix every failing test ...
... Hermes works ...
↻ Continuing toward goal (1/20): 3 of 5 tests still failing.
... Hermes works ...
✓ Goal achieved: All tests pass.The first turn kicks off immediately, you don't send a separate message.
Commands
| Command | What it does |
|---|---|
/goal <text> | Set (or replace) the standing goal and start working |
/goal draft <text> | Have Hermes expand a one-liner into a structured completion contract, then set it |
/goal or /goal status | Show the current goal and turns used |
/goal pause / /goal resume | Pause the loop / resume (resets the turn counter) |
/goal clear | Drop the goal |
/subgoal <text> | Append an extra acceptance criterion mid-loop |
Completion contracts (sharper goals)
A vague goal makes for vague judging. You can attach a structured contract, the cleanest way is to let Hermes draft it:
/goal draft Migrate the auth service from session cookies to JWTOr write fields inline:
/goal Migrate auth to JWT
verify: pytest tests/auth passes
constraints: keep the /login response shape unchanged
boundaries: only touch services/auth and its tests
stop when: a DB schema migration is requiredWith a contract, the judge marks the goal done only when the verification criterion is met with concrete evidence (a command result, test output), which kills the most common failure mode of stopping too early.
How the loop terminates
- Turn budget: default 20 continuation turns (
goals.max_turns). When hit, the loop auto-pauses:⏸ Goal paused, 20/20 turns used./goal resumeresets the counter so you can continue in measured chunks. - Fail-open judge: if the judge model errors, the verdict defaults to
continue, so a broken judge never wedges progress, the budget is the real backstop. - You always preempt: any real message you send takes priority over the continuation loop.
Parking on long-running work
If a goal is gated on something slow (CI, a long build, a backgrounded process), the judge can return a wait verdict and the loop parks, no wasted "is it done yet?" turns, then resumes the instant the process finishes. You can also park manually with /goal wait <pid>.
Local-model notes
The judge runs once per turn and is small (~200 output tokens). On a local setup you can keep it on your main model, or route it to a cheaper/faster model to save inference time:
yaml
# ~/.hermes/config.yaml
goals:
max_turns: 20
auxiliary:
goal_judge:
provider: custom
model: qwen3.5:7b
base_url: http://localhost:11434/v1TIP
The continuation prompt is just an appended user message, it does not mutate the system prompt or toolsets, so a 20-turn goal is as cache-friendly as 20 normal turns. Goal state persists in the session, so you can /resume tomorrow and the goal is still standing.