What Hermes Taught Me About Loop Engineering
I use Hermes every day as a local agent runtime. Its goals, schedules, durable board, sessions, and approval gates taught me to see a useful loop as a set of clocks, records, judges, and stops.
One morning I opened the agent board and found a useful contradiction: scheduled work had run, while a queue of durable tasks was sitting still. Nothing was broken. One loop had a trigger. The other had state, but no dispatcher.
That was a better lesson in Loop Engineering than another architecture diagram.
I use Hermes Agent every day as a local agent runtime. It sits behind a desktop app, several role-based profiles, a messaging gateway, scheduled jobs, a durable work board, local tools, and a private knowledge connector. It remembers sessions, delegates work, waits for long-running processes, and can keep a goal alive after one answer would normally end.
On a good day, it feels less like chatting with a model and more like operating a small system.
On a bad day, it exposes exactly where the system is not yet a loop.
This is an applied account of what using Hermes taught me after writing the Loop Engineering fundamentals series: where the theory is already real, how the machinery achieves it, and what still has to change before I would call the whole thing a complete, governed loop platform.
I have removed machine paths, credentials, profile names, private service names, and client-specific details. The behaviour is real; the identifying configuration is not the point.
The first lesson: a loop is spread across the system
I used to picture an agent loop as one piece of code:
while not done:
agent.step()
Hermes made that picture feel too small.
The repeat is distributed across several components:
- a goal that remains active after the agent’s first answer;
- a judge that decides whether the goal is done, should continue, or should wait;
- a scheduler that creates work because time or a cadence says it is due;
- a durable board that holds tasks when no worker is currently running;
- a session store that lets a fresh process reconstruct the conversation;
- a breaker that limits turns, time, repeated failures, and dangerous actions;
- a human gate for decisions the loop should not take alone.
No single component is “the loop.” The loop appears when those parts agree on the same goal, state, and stopping conditions.
This is the same distinction I made in Part 1: The Repeat is the Product. The model does the visible work, but the repeat belongs to the surrounding system.
Hermes achieves that repeat in more than one way.
Persistent goals replace “keep going”
The clearest Loop Engineering feature in Hermes is its persistent goal mode.
I can give it an objective once, including:
- the outcome;
- the verification that proves it;
- constraints it must preserve;
- boundaries it may not cross;
- the condition that should stop the run and ask me.
After each turn, a lightweight judge reads the goal and the agent’s latest result. It returns one of three useful decisions:
donecontinuewait
If the answer is continue, Hermes appends a normal user-role continuation and runs the next turn. I do not have to type “continue” or “keep going.” If the agent is genuinely waiting on a build, deployment, or watcher, the judge can park the goal instead of wasting turns asking whether the process is finished.
The goal and its completion contract survive a later resume. Time-based waits can survive too. A process-based wait clears when the watched process has died, which prevents a stale process ID from wedging the resumed session.
That small detail matters. A useful loop needs a state between running and failed. Waiting is work with an unresolved dependency, not a failure.
Hermes also gives the goal a turn budget. When the budget is exhausted, it pauses and returns control instead of quietly granting itself unlimited attempts.
That is a real maker-checker-breaker structure:
- the main agent is the maker;
- the goal judge is the checker;
- the turn budget, wait state, pause controls, and approval rules form the breaker.
The pattern is recognisably the control structure from Part 2: Maker, Checker, Breaker, even though its default checker posture can be tightened.
There are three clocks, and they solve different problems
My daily setup uses three different kinds of repetition. Confusing them creates bad automation.
1. The conversation clock
A persistent goal asks: does this same objective need another turn?
It is useful for a bounded piece of work such as fixing a test suite, completing a migration, or investigating a fault. The state belongs to one session and the loop advances through judged continuations.
2. The schedule clock
A scheduled job asks: is this work due again?
It is useful for recurring briefs, maintenance, monitoring, and collection. The schedule owns the next fire time, work directory, model or profile choice, and output record.
3. The queue clock
A durable board asks: is there ready work that an eligible worker can claim?
It is useful when work crosses roles, survives restarts, waits for humans, or depends on another task. The task is a durable row, not a promise living inside one agent’s context.
The contradiction I saw that morning came from this distinction. The schedule clock was alive. The queue had durable state. But its dispatcher was intentionally disabled, so no queue clock was advancing the tasks.
What looked like a contradiction was an operating-state problem: one clock was live and another had been deliberately left without a dispatcher.
A fully designed loop can still sit idle. The trigger, dispatcher, worker, and breaker all have to be live.
How Hermes makes the state durable
The implementation choice that matters most is where the truth lives; the wording of the judge prompt comes later.
Hermes stores session history and metadata in SQLite rather than relying on the model’s context. The database uses write-ahead logging so the gateway and local clients can read while one writer advances state. Goal contracts, subgoals, wait barriers, model settings, and message history survive process restarts.
The model context is built from that durable state, but it is not the state itself.
As a session grows, Hermes compresses older conversation into a bounded working view. The recent exchanges remain detailed; older material is summarised. The full durable record and the model’s current context are treated as separate concerns.
That directly matches the lesson from Part 3: State, Recovery and the Right to Continue:
Preserve the record. Compact only the view.
The same idea appears in the durable work board. Tasks, dependencies, comments, status, ownership, retries, and artifacts live in a database. A worker can crash, another worker can reclaim the task, and the handoff remains inspectable.
Scheduled jobs use their own durable store and keep outputs by run. Different loop, same principle: the next process should not need the previous process’s private memory.
The honest gap: a judge is not automatically independent
Hermes has a checker role, but by default that checker resolves to the same main model that did the work.
The roles are separated in software while the underlying judgment may remain correlated.
The goal judge sees a smaller prompt and has a stricter output contract, which helps. It can require explicit verification evidence before returning done. But if the same underlying model produced the work and judges the explanation, correlated mistakes remain possible.
The checker can be routed to a different auxiliary model. In a stricter setup, I would do that and order the evidence like this:
- deterministic checks first;
- a stable rubric second;
- an independent model only where judgment is needed;
- a human for reserved consequences.
There is another honest compromise: if the goal judge itself errors, Hermes continues rather than wedging the goal. The turn budget is the final backstop.
That usability choice suits a personal agent, while higher-consequence loops need a fail-closed checker posture. A research draft may continue safely after a judge error. A production change should not.
Breakers exist, but configuration decides whether they bite
Hermes has several breaker mechanisms:
- maximum turns and iterations;
- child-agent timeouts;
- approval prompts for destructive actions;
- repeated-tool-failure detection;
- caps on runaway search and delegation;
- pause, stop, wait, and human-response states;
- failure limits on durable queued work.
Operating it taught me to inspect the active configuration instead of trusting the feature list. Repeated-tool detection can be present while the runtime is configured to warn rather than halt. The mechanism exists; the operating posture still depends on the switch.
Some controls are warnings by default. Some hard stops are opt-in. Some automated dispatchers can be disabled. Checkpoints can exist as a feature while remaining off in configuration.
The useful Loop Engineering question is: which breaker is active for this loop, at what threshold, and what state does it leave behind?
The answer belongs in the loop definition rather than an operator’s memory.
Where Hermes is already strong
After using it this way, I think Hermes is strongest in five areas.
Persistent intent
Goals and subgoals survive turns and resumes. The objective does not disappear because one response ended.
Durable handoffs
Sessions, scheduled outputs, and queued tasks live outside the model context. A fresh process can recover the work.
Multiple trigger types
Conversation continuation, time-based schedules, messaging events, and durable queue readiness are separate primitives rather than one overloaded mechanism.
Human interruption
A person can pause a goal, answer a clarification, approve an action, unblock a task, or take over without pretending the loop cleanly succeeded or failed.
Prompt-cache discipline
Continuation is appended as a user message instead of rebuilding the system prompt or swapping toolsets mid-conversation. That preserves the cached prefix and keeps long-running work economically sane.
These quiet controls are the pieces that make an agent usable after the demo.
Where the potential is
The next step is to make the loop contract explicit and consistent across every surface before granting more autonomy.
One loop manifest
Every loop should expose the same fields:
goal
trigger
maker
checker
record
breaker
handoff
Today those facts can live across a goal contract, schedule, board task, profile config, and approval rule. A single inspectable manifest would make the operating posture obvious.
Independent checker presets
The checker should be selectable by consequence. Routine work can use a cheap judge. High-consequence work can require deterministic evidence plus a separate model or human.
Hard stops enabled by policy
Repeated failure and no-progress detection should move from warning to halt for unattended loops. Interactive sessions can stay gentler.
Idempotency for side effects
The durable board already supports deduplication concepts, and the gateway protects some deliveries. The broader gap is universal: every consequential tool action needs a stable intent key or a status lookup before retry.
Outcome-gated learning
Hermes has memory, skill usage, and curation. The missing general contract is:
attempt -> checker evidence -> real outcome -> learning
Do not reinforce a tool because it was called or a source because it was retrieved. Reinforce the path only after an independent outcome says it helped.
What changed in my day-to-day use
The biggest day-to-day change is the order of questions I ask.
I no longer start with, “Which model should run this?”
I start with:
- What fact should trigger another pass?
- What is the durable object that owns the work?
- What evidence can the maker not grade for itself?
- What does waiting look like?
- What survives a restart?
- What stops the loop?
- Which exact action needs a person?
Then I choose the Hermes surface that matches the clock:
- a persistent goal for one objective across several turns;
- a schedule for work that becomes due again;
- a durable board for work that crosses roles or waits on dependencies;
- a plain conversation when no loop is needed.
That last option matters. Not every task deserves a loop.
Hermes taught me to judge Loop Engineering by whether the reason to continue is inspectable, not by how long the agent stays busy.
The platform already has most of the organs: goals, judges, schedules, queues, state, recovery, approvals, and budgets. The potential is in making them behave as one explicit control plane, with independent evidence and consequence-aware defaults.
That is when the loop stops being an automation trick and becomes an operating system for work.
The practical test: take one recurring agent task you use today and write down its goal, trigger, maker, checker, record, breaker, and handoff. Any blank field is not missing documentation. It is missing engineering.