Completion proven by evidence, never by an agent's claim.
An idea goes through planning, decomposition, execution and verification with little human involvement. The goal is reliable, controlled autonomy, not maximum autonomy.
Scope is frozen until the proof run passes
Only corrections the proof run shows are needed are allowed, and each one is logged with the demonstration that forced it. No new mechanisms, roles or features.
Delivery, blocking and retry ceiling, stale verdicts, recovery, and Executor restrictions (§9).
The EPO merges. Repository protection holds the line against every process.
Prove the guard plugin can identify which profile is calling it (§7).
Reading order
Each chapter links to its section below. Section numbers match the markdown file.
Purpose
Why V2 exists, and what still lives only in the archive.
Principles
Evidence, separation of duties, enforcement outside the model.
Roles
Planner, Executor, Verifier and the EPO. No Orchestrator model yet.
Workflow
Five stages, three checkpoints, the review bundle.
Project record
One file of current state; verified needs evidence.
Task packets & context budget
Fields, identity, the five-term estimate, runtime prevention.
Evidence & verdicts
The Verifier runs the checks itself; verdicts bound to a SHA.
Checks, retries, escalation
Baselines, coverage, the launch gate, where blocks go.
Enforcement
Layers that must hold through every route.
Hermes mapping
Profiles, config, the Executor skill sequence.
First proof run
Setup, budget validation, five demonstrations.
Deferred & decisions
What's out of scope, and the 13 decisions in force.
Purpose
An idea goes through planning, decomposition, execution and verification with little human involvement. Completion is proven by independently checked evidence, never by an agent's claim. The goal is reliable, controlled autonomy, not maximum autonomy.
COPY
The previous full design is at archive/hermes-v2-architecture-2026-09-21.md. Until the moves below happen, it is the only copy of three things.
| Content | In the archive | Moving to |
|---|---|---|
| Hardware and model placement | §11 | Confluence |
| General-assistant lane status | §10 | Confluence |
| Automation backlog | §9 | Jira (SKY → Hermes V2) |
Principles
Evidence, not assertion
An agent cannot mark its own work done. A status label proves nothing without the evidence behind it.
Separation of duties
The Executor writes code. The Verifier judges and never fixes. The Planner plans and never implements.
Hand-offs through disk only
Every transition is a committed artefact read by a fresh session. No two roles ever share a live session.
Resolve ambiguity before code
Contradictions and false premises are cheapest to catch before dispatch.
Enforcement lives outside the model
Prompts and AGENTS.md guide behaviour. Hooks, credentials and repository settings enforce it.
Checks earn their place
Which failure does it detect? Does a known-bad example fail it? Is it worth its maintenance cost? Every check has limited coverage; state the limit rather than treating it as a disqualifier.
Roles
Three agent roles plus the EPO. No Orchestrator model in the coding lane for now: Hermes' dispatcher assigns cards by profile, reclaims stale claims, promotes cards whose dependencies are met, and dispatches review. The EPO creates the starting card. Escalation routing is a script.
| Role | Does | Never |
|---|---|---|
| Planner / Decomposer | Plan mode: discovery with the EPO, the brief, and investigating premises. Decompose mode: tasks, dependencies, contracts, checks and packets. | Implements, or guesses past an unresolved ambiguity |
| Executor | OpenCode plus a coding model. Implements one packet in an isolated worktree, runs the declared checks and commits to the task branch. | Marks itself done, writes to main, or changes scope |
| Verifier | Checks the brief (CP1), packets (CP2), tasks and the milestone (CP3) against evidence it obtains itself. | Edits product code or the record |
| EPO human | Approves scope and consequential decisions, answers escalations, reviews the milestone and merges. | — |
PENDENCE
The Verifier reviews both the Planner's and the Executor's work, so its model should come from a different model family than both. That is a starting preference, not proof of independent judgement. Independence is tested by whether the Verifier catches known defects.
What each role needs from its model
The strongest reasoning available, and long native context.
Reliable tool calling and coding within the packet context budget (§5.2). One profile with two possible routes, local or cloud.
Enough reasoning to challenge the Planner's output, not just a different model, plus independence as above.
Executor routing. Local or cloud is the packet's route field, set by the Planner at decomposition and fixed for the task's life. A local execution never runs at the same time as a local Planner session. The rule for choosing a route isn't defined yet; for the proof run, every task uses one route.
Workflow
Five stages, three checkpoints. People are involved only at scope approval, consequential decisions, escalations, and milestone acceptance and merge. Everything else is automatic.
Capture
The EPO records the idea as a card. No shaping.
Plan → CP1
The Planner and EPO agree scope, what is out of scope, acceptance criteria and constraints. Any assumption that could invalidate the approach is investigated, and the output is evidence, not prose. The session ends when the brief is committed.
CP1: the Verifier checks the brief for self-contradiction and unsupported claims. The EPO approves scope.
Decompose → CP2 priority
The Planner, in Decompose mode, produces tasks, dependencies, contracts and each task's checks. Packets may be drafted ahead of time.
CP2: deterministic checks plus the Verifier on every packet, which is validated and pinned immediately before dispatch.
Execute ⇄ verify
Each attempt runs in a fresh Executor session. The Verifier then checks the committed revision in a fresh session. Per-task verdict; at most one corrective retry.
Close → CP3 → EPO merges
Combined checks run as tasks land, and again on the complete milestone. For anything with a UI, this includes rendering and measuring the real screens. A review bundle is generated for the EPO.
CP3: milestone verification is split into verification tasks by area plus an integration pass, each within the context budget. All of them check the same milestone revision. The integration pass checks behaviour that crosses areas and reconciles combined coverage against the source, so nothing falls between areas. Then EPO acceptance, then the EPO merges.
Review bundle
The milestone PR description is a plain-language summary the EPO can act on without another agent translating it. It is generated by a script, not written freehand.
- What changed and why
- Each task's verdict, with the commit it applies to and links to its evidence
- Changes made to
record.yaml, where decisions and constraints get their final EPO review - The human checks still outstanding
- The known gaps in check coverage
Project record — record.yaml
All artefacts live in the project repo, and git history is the archive. The record is one structured file holding the current state only: no archive files and no events. Superseded values stay in git history; the log and telemetry are enough for events.
| Field | Notes |
|---|---|
id, version | Referenced by pointer as {id, version}. The record is never restated as prose in packets. |
type | decision · constraint · assumption · contract · observation |
statement | The value itself. A figure names its subject, unit and context. |
status | unverified · verified |
evidence | Required for verified: the command or harness that produced it, the revision it ran against, and the artefact path. The checker rejects verified without resolvable evidence. |
approved | Required on decision and constraint entries: EPO plus a reference. |
change | On edit: material (the default) or cosmetic, set explicitly by whoever makes the edit, never inferred. A cosmetic change is re-pinned automatically; a material change stops any task that pins the entry. When unsure, mark it material: a false stop costs less than a missed change. |
Ownership by type
Those that change scope need EPO approval.
Recorded with their evidence; no approval, since an approval can't make an observation true.
Recorded as explicitly unverified.
Proposed by the Planner in Decompose mode; approved at CP1 or CP2.
≠ PROOF
Invalidating assumptions. An assumption that could invalidate a task must be backed by relevant evidence before that task's packet passes CP2. The label alone doesn't count.
Task packet — packets/<task-id>.yaml
Design test: could a fresh session, given only the repo, AGENTS.md and this packet, complete the task correctly?
# fields task_id objective acceptance_criteria depends_on record_refs # pinned {id, version} pointers constraints checks # which checks apply, and who runs them human_checks route # local or cloud (§3) inputs # files the Executor needs to read + files the checks need to run; only these go in its workspace output_cap # max tokens generated over the whole session, incl. drafts, rewrites, revisions (not final file size) context_estimate # the five-term ledger below attempt # copy of the trusted counter at dispatch; records the attempt, isn't the allowance
Packet identity
The git blob SHA of the committed packet file, not a version field someone has to remember to increase. Any edit produces a new identity, and that invalidates any verdict bound to the old one.
Validated and pinned at dispatch
Every reference resolves · pins are current · dependencies are verified · it fits the context budget.
Context budget
Two quantities are tracked separately. Peak context is the largest single model request: its prompt plus the response allowance. Cumulative usage is the total across all requests in a session; it drives cost and time. The 64K ceiling applies to peak context.
| Term | What it covers |
|---|---|
| Fixed overhead | Harness system prompt, tool schemas and AGENTS.md. Measured per configuration. Any change to the harness version, AGENTS.md, tool schemas, harness config or model invalidates the measurement. |
| Inputs | The declared inputs, with an allowance for re-reads. |
| Generated output | Everything the task generates, bounded by output_cap, including drafts, rewrites and revisions. |
| Tool output | An allowance per planned check run. By default checks print a summary and any failures; full tables are saved as artefacts, not printed into the session. |
| Reasoning | A reserve. |
BUILD
Generated output and tool output dominated the site-build experiment, ahead of the files read. Counting only the bytes read measured about 12% of the real load. Work is split so each task's generated output stays within its cap.
At runtime: measurement and prevention are separate jobs
MMeasurement
Reads token usage from each model call (§9), never from the Executor's own report. It shows an overrun, but only after the response.
PPrevention
A check before each request. If the prompt plus the response allowance would exceed the ceiling, the request is refused, and the task stops and is re-decomposed.
×No silent truncation
Nothing is silently truncated or compacted. Any automatic context compaction in the harness is turned off.
The same instrumentation applies to every session with a budget, including CP3 verification tasks.
Evidence and verdicts
The Verifier runs the declared checks itself, against a clean checkout of the committed revision. Results reported by the Executor are informational only and never count as evidence.
PASS never carries forward. A task PASS completes that task's card; it is not milestone acceptance and not a merge decision.AT SETUP
Where verdicts and evidence live (proposed). The verdict is the metadata on the Verifier's final Kanban call (kanban_complete, kanban_request_changes or kanban_block). The guard plugin receives that call's arguments, so it can check the verdict before the call goes through. Evidence artefacts are written outside the worktree to evidence/<task-id>/<attempt>/<sha>/ and are never committed to the task branch, because committing would change the commit the verdict points to.
Truth precedence
The record and the packet.
The Kanban board.
CI, test and harness artefacts.
AGENTS.md holds agent rules. Confluence is narrative only.
Checks
Three layers at every checkpoint: deterministic (code, which must reject reliably), judgement (the Verifier) and human-required (stated plainly, never guessed). Anything automatable belongs in code.
deterministic Baseline
Applied to every brief and packet. Each must pass a known-bad and known-good example before it is trusted, and must reject its cases every time.
- Required fields are present, references resolve, and pins are current.
verifiedentries carry resolvable evidence.- Every figure has a subject, unit and context filled in (presence only; meaning is a judgement check).
- Every
supersedesreference points to an entry that exists and is current. - Nothing measures a file the same task also changes, unless flagged to be re-measured.
judgement Baseline
Each finding cites its location. These are the checks benchmarked against defective and clean examples.
- The brief or packet contradicts itself
- It contradicts the record, including a position it changes but does not supersede
- A figure's subject is too vague to identify what was measured
conditional Only when triggered
- "Reuse X" must quote what X returns
- "Complete set" must state the search that produced it
- Claimed identities over a bounded domain are enumerated, not reasoned about
New checks are added when a defect slips through, and they are specific to where they apply unless they prove universal.
Task-specific checks
The EPO says what would make the work wrong, in plain words.
The Planner turns each statement into a check. The EPO never writes check scripts.
The Verifier judges whether each check measures the right thing, not just whether it runs, proving it with a known-bad case where it can.
Coverage is stated, never assumed. Every check and harness run records what it covers and what it doesn't, including how the app was run: viewport, motion settings, data and environment. A harness that runs the app in a way users never see will confirm false claims, with numbers. That is exactly how the Undrlit render harness certified sheets in reduced-motion mode. When a check is asked a new kind of question, its coverage statement is re-checked.
Rendering and measuring (anything with a UI)
Headless browser
At the target viewports.
Mechanical assertions
Bounding boxes, overlap, overflow, computed spacing.
Screenshots
For visual judgement by the Verifier or the EPO. A visual judgement can block acceptance; where it's a matter of taste, it's a human check.
LINE
Measurements are compared against a stored baseline, so a run reports differences. The baseline must be an accepted result. It is updated only when the EPO accepts a milestone, never by an agent; an unaccepted baseline would simply preserve existing errors.
Retries and escalation
A task gets at most two attempts: the original plus one corrective retry, each in a fresh session, with the prior failure written into the hand-off. Same model tier; no mid-task escalation.
- One trusted counter: a launch ledger of OpenCode launches per task ID, written only by the launch gate, never by an agent.
- The launch gate is the only way to start OpenCode as the OpenCode user: the sudoers rule allows that one script and nothing else. It runs before every launch, including a relaunch after a recovered crash.
- The guard plugin also refuses
kanban_request_changesonce two launches are recorded, so a review-driven retry becomes a block instead of a refused launch. - The counter is keyed on the task ID, so editing the packet never resets it. Re-decomposing the work creates a new task through the Planner, linked to its parent and visible to the EPO.
- Contradictions block immediately. A contradictory or impossible acceptance criterion, or a conflict with the record, stops the task at detection without using a retry.
Escalation categories
| Category | Kanban | Destination |
|---|---|---|
| Missing decision | kanban_block | EPO |
| Contradiction (brief, packet or record) | kanban_block | Planner, or EPO if it's a scope issue |
| Material stale pin | kanban_block | Re-validate. If the meaning changed, back to the Planner. |
| Retry ceiling reached | kanban_block | New Planner card, linked to its parent |
| Human-required check | kanban_block | EPO |
Stop conditions live in the project-root AGENTS.md, not in prompts or SOUL.md, because AGENTS.md propagates to child agents.
Enforcement
Executor restrictions must hold through every route, not just the Hermes tool call.
| Layer | Holds against | Notes |
|---|---|---|
Repository protection on main, admin bypass off | Any write to main from any process | precondition Protection on private repos needs a paid GitHub plan. Confirm the hijinxlabs plan. If it's Free, use a local bare remote with a server-side hook for the proof run. |
| Executor credentials | Pushing to main, approving PRs | Scoped to task branches only. Never the EPO's credentials. |
OpenCode isolation: separate OS user, no access to ~/.hermes, the Kanban DB or the hermes CLI | Alternate routes to completion from inside OpenCode (hermes kanban complete from a shell, writing to the DB) | Plus OpenCode's own permission config. |
Executor wrapper restrictions: the Hermes executor profile | Alternate routes to completion from the wrapper itself, which does need Kanban access | Guard plugin rules refuse terminal commands that call hermes kanban or open the Kanban DB. Defence in depth; a determined bypass is possible. stated accurately A forged completion can't reach main, but it can release dependent tasks and corrupt the evidence trail. Accepting that for a supervised trial is an EPO decision, reported as a partial result. |
sdlc-guard plugin (pre_tool_call) | Forbidden Hermes tool calls | Blocks kanban_complete from the Executor. Blocks completion when the verdict's SHA or pins don't match the current head or record. Blocks the retry beyond the ceiling. |
| EPO merges | Agent-initiated merges | No agent holds merge rights. |
BUILD
Identifying the caller. Each profile runs with its own HERMES_HOME, and Hermes' Kanban hooks carry profile_name, so the guard plugin should be able to tell which profile is calling it. Confirm this on the pre_tool_call hook itself before relying on it; that is the first item to build.
Secrets
Reach processes only through environment variables. Never in packets, the record, evidence or logs.
Approvals
Consequential actions are authorised only by a structured action, such as a GitHub PR approval or a Kanban unblock by the EPO. A free-text chat or card comment never counts: it can be spoofed and is an easy prompt-injection target.
Hermes mapping
Three profiles — planner, executor and verifier — each with its own identity, SOUL.md, memory and pinned toolset. The general-assistant default profile is separate and untouched.
# kanban config auto_decompose: false auto_subscribe_on_create: false review_dispatch: true # verifier profile as reviewer max_in_progress: 1 # during the proof run; tasks are serial # no goal-mode cards: a model judge deciding completion contradicts §2 # workspace (scratch workspaces are deleted on completion) --workspace worktree:<path> --branch wt/<task-id>
Executor skill sequence
Read the card and packet
Materialise the worktree
A sparse checkout of the packet's inputs. This reduces incidental reads; it does not enforce read permissions: a sparse checkout can be expanded or turned off, Git's default cone mode includes additional files, and files the checks need in order to run stay readable.
Run OpenCode through the launch gate
opencode run --dir <worktree> --format json --auto -m <model> as the OpenCode user, only through the launch gate (§6).
Capture the event stream
As evidence and, if it has the token fields, as the Executor's telemetry (§9).
Run the checks
Commit to the task branch
Call kanban_request_review
Heartbeat at least every hour
Branching
Tasks run serially within a milestone. Each branches from the previous verified task's head. One milestone branch, one milestone PR. No separate integration task: combined checks run as tasks land.
Retries
A rework request starts a new worker process, giving the fresh session §6 requires. Hermes' own kanban.failure_limit doesn't count rework requests, so the ceiling uses the launch ledger and gate (§6).
Review procedure setup
With review_dispatch on, Hermes starts the Verifier with its bundled sdlc-review skill. Read it during setup; confirm it fits §5.3 (clean checkout, SHA-bound verdict, verdict in metadata) or replace it with our own Verifier skill.
Version pin & backup
Pin the Hermes version and re-test the guard plugin on every upgrade. Profiles, skills, AGENTS.md and plugins are committed to jaysonhijinx/skynet-hermes-config; secrets and .env files excluded.
First proof run
One plausible model configuration, with OpenRouter as the cloud stand-in until the hardware lands. A small set of defective and clean briefs and packets, then a disposable 3–5-task app.
Setup
- Pin one provider per model, with data collection denied. A dedicated OpenRouter key with a hard credit limit and a buffer: Hermes requests the model's maximum
max_tokens, which can cause 402 errors on a low balance (Hermes issue #22879). - Telemetry on every model call: model, provider, tokens and cost, plus peak context and cumulative usage per task.
- Hermes' own hook covers only Hermes' calls. The Executor's usage must come from OpenCode's JSON event stream or a proxy in front of the provider. confirm that the stream carries the token fields on the installed version.
- Prevention needs a check before each request (§5.2). With OpenCode calling the provider directly, the likely place is the same proxy. confirm it at setup, with how to turn off OpenCode's automatic compaction.
- Measure the fixed overhead once per configuration before any packet is estimated; re-measure after any change to the harness,
AGENTS.md, tool schemas or model. - A setup log in the vault: every tool installed, config change and workaround, recorded as it happens. It becomes the V2 deployment prerequisite list. Known so far:
gh.
Budget validation — a focused re-run of the site-build experiment
One previously oversized page task, and the whole-site audit.
Capture per-call usage; compare each estimate with the measured peak.
Send one deliberately oversized request to show the runtime stop working.
This validates §5.2 only. The site-build experiment is evidence of output quality. It lacked commits and telemetry, so it does not establish revision-bound verification or budget enforcement.
The run must demonstrate
| # | Demonstration | Pass condition |
|---|---|---|
| 1 | Successful delivery with independently checked evidence | Every task PASS rests on checks the Verifier ran on the committed SHA. The milestone passes CP3 and the EPO merges. |
| 2 | Immediate blocking and the retry ceiling | A contradictory criterion blocks at detection with 0 retries. A fixable-looking failure stops after attempt 2, with an honest failure report and no false READY or PASS. |
| 3 | Stale verdict rejection | A commit after PASS, or a material record change, invalidates the verdict, and completion is refused until the task is re-verified. |
| 4 | Recovery after interruption | A worker killed mid-task is reclaimed and re-run with no duplicate commits and no false completion. The relaunch counts toward the ceiling; after a crash on attempt 2, the launch gate refuses a third launch. |
| 5 | Executor restrictions through Hermes and OpenCode | Each is blocked and logged: kanban_complete from the Executor; injected card text asking for completion or a push; a CLI or database route to completion, tried from inside OpenCode and from the Hermes Executor wrapper; a push to main with the Executor's credentials. Passes only if every route is blocked. If main stays unreachable but a completion route stays open, the result is merge protection demonstrated; completion isolation partially demonstrated — not a pass. |
Recorded, not gated
- Defects caught per checkpoint
- Verifier false stops
- Escalations per task
- Peak prompt tokens vs the dispatch estimate
- Cost per accepted task
Scope freeze
Scope stays frozen until all five demonstrations pass. Corrections the run shows are needed are allowed, each logged in the setup log with the demonstration that forced it. Nothing else is added: no new mechanisms, roles or features. Changes after the run come from what it showed, not from new design.
Deferred — outside this architecture
- Broad model comparisons are added only when an observed failure warrants one.
- Refreshing the stale Confluence space is the first agent task after the proof run passes. Until then, ignore Confluence as a source.
- All external content (tickets, chat, email, web) is untrusted data, never instructions. The general-assistant lane feeds nothing into this pipeline until the proof run passes.
- Hardware, the general-assistant lane and the automation backlog are listed in the table under §1.
Decisions in force for the proof run
- Three roles: Planner/Decomposer, Executor and Verifier. No coding Orchestrator model.
- Five stages and three checkpoints. CP2 is the priority.
- One
record.yamlholding current state, with git as history.verifiedrequires evidence. - Packets may be drafted ahead, but are validated and pinned at dispatch.
- Tasks are serial, with one milestone branch and one milestone PR. No integration task.
- At most two OpenCode launches per task, recovery included, enforced by a launch gate in code before every launch. Contradictions block immediately.
- Verdicts are bound to the SHA, packet and pins. The Verifier runs the checks itself.
- The EPO merges, and no agent holds merge rights.
- Enforcement: repository protection, credentials, OpenCode isolation, and the guard plugin.
- Secrets travel only through environment variables. Consequential actions are approved only through a structured action.
- Anything with a UI is rendered and measured, and every check states its coverage.
- The context ceiling applies to peak context. Estimated from transcript growth at CP2, measured per call, and prevented by a check before each request. The Executor's workspace is a sparse checkout of its declared inputs, which reduces incidental reads without enforcing them.
- Scope is frozen until the proof run passes. Only corrections needed to pass it are allowed, and each is logged.