Learn Hermes Agent v0.18: The Judgment Release Completion Contracts: Defining Done Before You Start

Completion Contracts: Defining Done Before You Start

Advanced 🕐 13 min Lesson 5 of 13
What you'll learn
  • Write a completion contract with all five fields populated correctly for a realistic coding task
  • Use /subgoal to add acceptance criteria mid-loop without resetting the goal
  • Configure a pre_verify hook to inject custom checks before the judge can declare completion

The Contract Metaphor

A completion contract formalizes the agreement between you and the agent about what done looks like. Before you delegate work, you define: what state the world should be in when the task is finished, how to prove it, what must not be broken in the process, which files or systems are in scope, and when the agent should stop and ask for your input rather than continuing autonomously.

This sounds like overhead. In practice it takes thirty seconds for a typical task and eliminates the most common class of goal-loop failures — the agent producing plausible output that looks done but isn't actually verifiably done. The contract is the difference between a judge that guesses at completion and a judge that checks for it.

The Five Contract Fields

A completion contract has five optional fields. You can populate any or all of them — more specificity means tighter evaluation.

outcome — the required end state, described in terms of observable facts. Not "the auth module is improved" but "the auth module uses JWTs and all existing token-related tests pass." The judge checks the outcome against the conversation history and available evidence.

verification — the specific command or test that proves the outcome. This is the most powerful field. When a verification step is present, Hermes runs it ��� not asserts that it would pass, but actually executes it — and records the output as evidence. A passing npm test -- auth.spec.ts is proof. A passing lint check is proof. The agent cannot claim completion unless verification produces the expected result.

constraints — what must not regress or change. If you are refactoring a module, you might constrain that the public API surface must not change. If you are updating a dependency, you might constrain that the existing test suite must remain green. Constraints give the judge a negative check to run alongside the positive verification.

boundaries — files, directories, or systems that are in scope. This limits the agent to working within a defined area and protects the rest of the codebase from unintended side effects. Useful when your repository has production and staging paths that should not be conflated.

stop_when — conditions that should cause the loop to pause and ask for your input rather than continuing autonomously. Examples: "if the migration requires a schema change, stop and ask me before executing it," or "if an external API call would be required, stop and confirm." Stop-when conditions protect you from the agent taking irreversible actions without your awareness.

Using /goal draft to Generate a Contract

Manually writing a contract from scratch is not necessary for most tasks. /goal draft <text> asks Hermes to generate a contract from your description. The agent reads the current working directory context, understands what kind of task you are describing, and proposes values for each field.

The draft is presented to you for review before it is set. This is not a formality — the draft often contains assumptions worth examining. Does the verification command actually run in your environment? Does the boundary match the scope of the work? Is the stop_when condition specific enough? Reviewing the draft takes less than a minute and the contract it produces is far more reliable than a vague goal text.

/subgoal: Mid-Loop Criteria Addition

You discover mid-task that a requirement was missed. Adding it to the goal would normally mean clearing the goal, rewriting it, and starting over. The /subgoal command avoids this. You append additional acceptance criteria to the running goal without resetting the turn counter or the judge's current evaluation state.

/subgoal the new token format must also pass the legacy compatibility tests in /tests/legacy/

The judge now must satisfy both the original goal criteria and every subgoal before marking completion. You can add multiple subgoals over the course of a long session. The subgoal list is visible with /subgoal (bare command), and individual subgoals can be removed with /subgoal remove <N> or cleared entirely with /subgoal clear.

The pre_verify Hook

The pre_verify hook lets you inject custom checks into the completion verification step. Before the judge can mark a goal complete, Hermes runs your hook and includes its output as additional evidence. If the hook exits with a non-zero status, the goal cannot be marked complete regardless of what the judge evaluates from the conversation.

This is primarily useful for team environments. A platform team might configure a pre_verify hook that runs a security scanner, a compliance check, or a deployment dry-run against staging before any goal related to infrastructure changes can be considered done. Individual developers might use it to run integration tests that are too slow for every turn but essential for completion.

The hook is configured in config.yaml and receives the goal text and current session context as environment variables. It should return a short human-readable summary of what it checked and what it found — this summary is included in the evidence ledger that the judge reads when making its final evaluation.

The Evidence Ledger

v0.18 introduced a verification evidence ledger for coding work. When a goal completes, Hermes records the evidence: the verification command output, the pre_verify hook result, the test summary, lint output, coverage report — whatever was run as part of the completion check. This ledger is stored in the session database and is accessible after the session ends.

The practical value is auditability. When a colleague asks why you trusted an agent to make a change autonomously, you can show the evidence ledger: the specific tests that passed, the exact verification output, the timestamp of each check. Claimed completion backed by no evidence and claimed completion backed by a test run are different things.

Key takeaways
  • A completion contract has five fields — outcome (the required end state), verification (the command that proves it), constraints (what must not regress), boundaries (files in scope), and stop_when (conditions requiring user input) — all optional but each adds evaluability.
  • The verification field is the most powerful — when present, Hermes actually executes the command and records output as evidence; the agent cannot assert its way past a failing verification step.
  • /subgoal appends additional acceptance criteria mid-loop without resetting the turn counter — the judge must satisfy both the original goal and every subgoal before marking completion.
  • The pre_verify hook runs before the judge can declare completion — a non-zero exit prevents completion regardless of judge evaluation, making it the right place for team-level security scans or compliance checks.
  • The evidence ledger records test output, lint results, verification command output, and hook results at completion — claimed completion backed by a recorded evidence ledger is auditable; assertion-based completion is not.