Skip to content

The harness engine

An agent does not do the work itself; it encloses an engine. You can write your own (Bring your own engine), but every agent already has one: the harness engine, the batteries-included runtime. chat, mission and runmission in the workspace all run on it, and so does every runner.

the binaryhexaeight-engine (the docs also call it hexaeight-harness-engine), installed with the agent under ~/.heia/runtime/harness/
started bythe agent, once per turn, inside the agent’s jail
modelnever holds a key — every call goes to the agent’s model route, and from there to the router
its datathe harness root: ~/.hexaeight-harness for your workspace agent; each runner has its own

Not the same as the harness entry you may see in the workspace’s session list — that is an older skills-based engine kept for sessions that already use it.

Memories. Searchable bodies of documents — see Documents it can search. A local memory is an index in the harness root (memories/<name>/); a served memory is a pointer (memories/<name>/remote.json) to another agent’s corpus or API, searched through service_call over the turn’s ticket and the agent’s policy. The engine searches both the same way.

Other agents, through one memory. Every harness root has connect-to-agent: memory_search("connect-to-agent", "<agent name> <question>") asks that agent — by name, over DDE — and returns its answer. A turn serving someone else does not relay unless switched on; the memory is kept exactly as shipped. See Two agents talking to each other.

Sessions. Each conversation has a transcript and resumes where it left off. Each session also gets its own working folder, so one conversation’s files never appear in another’s.

The tool loop. In a guided turn the model reasons, calls a tool (search a memory, run a skill, record state), reads the result and continues, until it can answer. Every model call in that loop goes through the agent’s route.

Missions. A written method the engine follows instead of improvising — see What a mission is:

  • guided — the model walks the mission’s map and cards, step by step;
  • direct — one card, one approved command: the engine writes the message to a file, runs the command, and returns what it printed, making no model call of its own. This is how framework runners work.

It also copies a mission’s own files (a framework’s runner.py, say) into each turn’s folder, fresh.

The command gate. A mission runs a shell command only if it is in the mission’s command set, sealed in the agent and pinned to the sha256 of the file it runs. Anything else is denied, not asked about. No command set means no shell at all.

The jail. Every turn runs with the agent’s identity folder masked, so a turn — and anything it launches — cannot read the identity files, even though it runs as the agent.

The model route and the turn’s ticket, handed on. A command the engine launches (a framework runner) receives the turn’s model route (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_MODEL) and the turn’s MCP ticket (HEIA_MCP_CONFIG), so it can use the model and reach shared memories and APIs — without a provider key, and under the same policy as the turn.

~/.hexaeight-harness/ the harness root (a runner: <runner>-frontdoor/harness-root)
memories/
<memory>/ a local memory: sources/ + its index
<memory>/remote.json a served memory: a pointer, nothing else
connect-to-agent/remote.json asks other agents (written and kept by the engine)
<mission>/ a mission: sources/ (map, cards, fence) + its files + index
sessions, projects, … conversation records

A runner’s root starts with its mission only; hexaeight-activate runner-memory --share decides what else it may see.

enginewhat it is for
chatconversation, with whatever memories you attach
missionbuilding a mission in the workspace — the cards take shape beside the conversation
runmissionrunning a mission you pick; per-model variants are made with hexaeight-activate engine --add runmission --model …
missionrun-externala runner’s engine: runmission sealed to one mission, for outside callers

They are the same binary with different instructions, sealed as entries in the agent’s engines.he.

The binary also works on its own, which is how you build and check memories outside the workspace:

Terminal window
E=~/.heia/runtime/harness/hexaeight-engine
$E --addmemory <name> --file <file-or-folder> --root ~/.hexaeight-harness # build or add to a memory
$E --memory-search <name> --root ~/.hexaeight-harness -p "<question>" # search it
$E --memory-refresh <name> --root ~/.hexaeight-harness # re-read changed sources, drop removed ones
$E --connector-relay status --root ~/.hexaeight-harness # on | off: may it ask agents for someone else

How it fits with your own engine and frameworks

Section titled “How it fits with your own engine and frameworks”
the harness engineyour own enginea framework as a sealed mission
who does the workthe built-in runtimeyour processyour framework, launched by a direct mission
memories, sessions, tool loopbuilt inyours to providethe framework’s own loop; HexaEight’s memories via the ticket
policy, identity, model routethe agentthe agentthe agent
how you add itnothing to addBring your own enginehexaeight-activate enable <framework>