A Hankweave run takes a program file and a data directory, executes the program as a sequence of sealed agent tasks, and leaves behind outputs plus a complete record of what happened. This page follows one run through that lifecycle: what goes in, what the runtime does while it works, what it leaves on disk, and how a later invocation can resume, roll back, or replay it. Along the way we introduce each concept – hank, codon, rig, sentinel, checkpoint, budget, loop – at the point where the run first needs it, so the terms arrive with a job to do rather than as a glossary.
By the end you will know where to look when a run misbehaves and which reference pages own the details this page only sketches.
What enters a run#
A run begins with a single command. Use the version-pinned package runner so the command does not assume a globally installed binary:
bunx hankweave@0.11.0 hank.json data/
The command passes the hank path (the path to the program file) and the data path to the installed hankweave launcher. Everything else the run needs arrives through the environment.
A hank is the program: its hank array is the immutable sequence of logic, and the array requires at least one item. Before any work starts, the runtime loads and validates it.
The runtime also checks what the invocation named before it resolves anything. When an invocation names none of the sixteen inputs that leave the wizard path – no hank path, no data path, no -e, --init, --validate, --headless and the rest – it launches the welcome wizard and exits 0 without loading any hank. Flags alone do not help: -o, -m, -p, -n, -f and -y are not on that list, so bunx hankweave@0.11.0 -m opus still opens the wizard.
The data path becomes the run's workspace input. The workspace is agentRoot/, and data enters it as agentRoot/read_only_data_source. By default that path is a symlink (a filesystem link) to the source data. --copy copies the data instead, and a failed symlink falls back to a copy with a warning. The name is a convention the hank keeps, not an enforced read-only mount: the directory is presented as input and is always excluded from checkpoint tracking, so the data is an input, never part of the sealed state. Authentication credentials travel separately: they are passed through the process environment, not through the linked data directory.
Self-test behavior belongs to authentication and models, but one failure mode is worth seeing here because it stops the run before anything else happens. When authentication is missing, startup reports:
[<ts>] [ERROR] Self-test completed: FAILED
[<ts>] [ERROR] Self-test FAILED: Some checks failed
[<ts>] [ERROR] - authentication: ✗ No authentication found (set ANTHROPIC_API_KEY)
[ERROR] Server startup failed!
Error message: Self-test failed for 1 model(s):
- Claude Haiku 4.5 (latest) (anthropic/claude-haiku-4-5): Some checks failed
• authentication: No authentication found (set ANTHROPIC_API_KEY)
The run never reaches execution in this case: the self-test failure aborts startup and names the missing credential, which is why the error surfaces before any agent session exists.
What happens while it runs#
Once the inputs validate, the run needs somewhere to work and a way to keep its tasks isolated from one another. Execution directories, sealed sessions, and checkpoints provide both: they give us places to inspect the work and return to it. If a codon – one sealed agent task – fails, we can investigate that bounded task using the run's receipts and saved state rather than starting with one agent's entire conversation.
A managed run (one without -e/--execution) works under ~/.hankweave-executions/. With --start-new it creates a directory named <timestamp>-<random>-<dataHash6> and prints Created new execution directory:; without it, the run reuses the newest execution with the same data hash (printing Resuming execution in:) or creates one (Created execution directory:). The fixture below was captured with --headless --start-new:
Created new execution directory: ~/.hankweave-executions/<exec-id>
New execution: <exec-id>
Source → data
Exec → ~/.hankweave-executions/<exec-id>
SDKs → Claude node_modules ✓
That directory contains agentRoot/, rigArchive/, and .hankweave/. The last holds state, the event journal, logs, and checkpoints. Startup initializes these pieces in order: the git checkpoint system, the state manager at .hankweave/state.json, the event journal at .hankweave/events/, the sentinel manager, then the lock file (.hankweave/runtime.lock), and finally a WebSocket server on an automatically selected port.
With the directory in place, the hank's sequence begins. A codon is one sealed agent task in that sequence, and codons run in order: the sequence is the execution plan. Each codon declares its session mode in a required continuationMode field: fresh starts a new session, so nothing the agent remembers survives the codon unless it writes the memory to files, and continue-previous continues the predecessor's session. The shipped init template writes "continuationMode": "fresh" on all four of its codons, so fresh sessions are the usual shape of a run, but it is a choice the hank makes explicitly. On failure, a codon retries or aborts according to its policy.
Before the agent session starts, a rig (a setup operation) must complete its rigSetup operation; the rig executes first. By default a failed rig operation fails the codon, but an operation with allowFailure: true (or any operation in a run started with --ignore-rig-failures) may fail and setup continues. A failure that is not allowed marks the codon failed with a retriable reason, and the codon's onFailure policy then decides.
Codons do not run unobserved. A sentinel is a parallel observation agent. A sentinel observes the journaled event stream beside the codon and fires reports. Sentinel events are not routed back to sentinels, so they cannot observe themselves in a loop. When the agent finishes, completing-sentinels drains pending sentinel work before the codon closes. To choose where a report lands, see sentinel config and the two-line output-path rule in sentinels.
At each boundary, the run records its state. A checkpoint is sealed state captured at a run boundary. It seals that codon's checkpointedFiles in the dedicated git store at .hankweave/checkpoints/.hankweavecheckpoints, whose git metadata directory is named .hankweavecheckpoints, not .git. A checkpoint records one of four stored types: rig-setup, completed, error or skipped. (start and end are not stored types; they are selector values the rollback.toCodon command accepts, owned by checkpoints.)
Two more mechanisms bound what a codon can do. A configured budget allocates shares. When its cap trips, the runtime requests the codon's interruption, and the codon's onExceeded policy decides the recorded outcome: complete (the default) marks it completed with whatever it produced, fail marks it failed. Time caps are checked by a one-second watchdog and on every cost update. The two-party budget rules belong to budgets.
A loop is a repeating plan segment. It iterates lazily: only its first iteration expands up front. After that iteration completes, Hankweave adds the next one; a termination check decides when it terminates.
Throughout all of this, the runtime streams events over the WebSocket. Its journal persists server-state, agentic-backbone, and sentinel events; connection-state events such as server.ready, history.batch, and pong are not journaled. The default interactive mode uses the terminal UI (TUI) over that WebSocket; --headless runs without the TUI and autostarts execution.
The figure below gathers the whole lifecycle into one view: inputs enter, execution runs inside the execution directory, outputs and receipts leave, and persisted state supports later entry.
Figure: inputs enter, execution runs inside the execution directory, outputs and receipts leave, and state supports later entry.
Read the diagram as text
WHAT ENTERS WHAT RUNS — ~/.hankweave-executions/<id>/ (the execution directory) WHAT LEAVES
hank.json ───────────────▶ load and validate
data/ ──link─────────────▶ agentRoot/read_only_data_source ──▶ outputs in agentRoot/
keys ──environment────────▶ self-test and codon sessions + optional -o copy
┌──────────────────────────────────────────────┐
│ per codon: rig executes │──▶ receipts:
│ ▶ codon runs — continuationMode │ state.json · events.jsonl
│ (fresh | continue-previous), sealed │ server.log · agent logs
│ ▶ checkpoint seals │ checkpoints (git store)
│ sentinels observe & fire beside it │ checkpoints (git store)
│ .hankweave/: state·journal·logs·ckpts │
└───────────────────┬──────────────────────────┘
WHAT PERSISTS: resume · rollback · replay
The ASCII figure shows the same flow. Note the checkpoint seal after each codon run and the .hankweave/ directory collecting state, journal, logs, and checkpoints beside the work – those are the pieces the next two sections rely on.
What a run leaves behind#
When the sequence finishes, two kinds of results remain: the outputs the agent produced and the receipts the runtime kept.
Outputs stay in the execution directory's agentRoot/ unless an output target is configured. There is no default output directory; output-directory mechanics belong to the runbook. With -o/--output <path>, Hankweave copies each codon's outputFiles globs (file patterns) out of the execution directory when that codon completes.
The receipts live on disk alongside the outputs: .hankweave/state.json, the event journal at .hankweave/events/, the server log at .hankweave/logs/server.log, per-run agent logs under .hankweave/runs/<runId>/, and the checkpoint store. While a run is live, the journal is events.jsonl with an advisory events.meta.json sidecar. When a completed or failed run shuts down and the runtime can still prove it owns runtime.lock, finalization may compress the journal to events.jsonl.zst (restorable with --restore-journal); a skipped or failed diet leaves the plain journal in place. The journal's two forms and their conditions belong to the event journal. One further file, .hankweave/execution-meta.json, records the data and hank hashes, link type, Hankweave version, and host environment for the execution.
A finished headless run has two closing observables: a codon.completed event carrying its cost, then Shutdown: all codons completed (exit code: 0) in the server log. The event excerpt shows the first observable:
{"id": "<id>", "timestamp": "<ts>", "type": "codon.completed", "data": {"codonId": "summarize-notes", "success": true, "cost":"<n>", "duration":"<n>", "exitStatus": {"type": "success"}}}
The success: true field and the recorded cost and duration are what a monitoring client would key on; the matching shutdown line in the server log confirms the run closed cleanly rather than crashing.
What persists between runs#
The receipts above are not only records – they are the entry points for returning to a run. Hankweave supports four ways back in: resume, start-new, rollback, and replay.
A run resumes when you invoke it against an existing execution directory. Without -e, a managed rerun picks the newest execution whose recorded data hash matches and never reads the hank hash; when that execution has already completed, the runtime announces Resumed completed execution <id> — nothing to do. All codons already completed. Use --start-new to run fresh., runs no codon, and exits 0 – so exit 0 does not mean new work ran, and --start-new is how to run fresh. With -e <dir>, the runtime creates the directory when absent or resumes it when it holds .hankweave/, comparing the recorded data hash and then the hank hash; --force overrides both mismatches, and -y skips the changed-hank confirmation on that path without overriding a data-hash mismatch.
Use --start-new when the next run must never resume. For an existing execution directory, select it with -e <execution-dir> and combine --start-new --force: Hankweave backs up existing state as .hankweave.backup-{timestamp} and wipes agentRoot/. Add --no-wipe to preserve that workspace instead. The CLI page owns the full flag contract.
A run rolls back through TUI or other WebSocket client commands–rollback.toCheckpoint, rollback.toCodon, or rollback.toLastSuccess–rather than through a CLI rollback flag. The protocol documents these commands. Rollback opens a continuation run that re-executes from the selected checkpoint without losing history.
A run replays with --replay <execution-dir>. Replay re-emits the recorded codon logs from a past execution, so no codon makes a new model call, and it skips startup model self-tests, rig setup and sentinels. It is not provider-free: the runtime still runs its startup provider health checks, which can make billable calls when provider credentials are set, and it always starts fresh on a temporary copy of the execution directory. The stages replay runs and skips belong to resume, rollback, and retry; the flag's contract belongs to the CLI page.
Crash detection ties these paths together. On the next Hankweave startup, the lock-file check marks the current run crashed when its process ID is dead or its lock heartbeat has been stale for more than 2 minutes, and a separate probe checks serverPid for any other run still marked running, marking it crashed when its PID is dead.
You do not need the detailed procedures on a first read. When you have a run to operate, use resume, rollback, and retry. To inspect its files or journal, use execution directory and events. For the underlying concepts, continue with codons, checkpoints, sentinels, and budgets. Look up rigSetup in rigs and hank JSON, rigArchive in the execution directory, --no-wipe and --replay in CLI, and rollback commands in protocol.