Hankweave reads an optional hankweave.json file from the working directory to pick up runtime settings: which port the server binds, whether a run starts automatically, which model codons use by default, and similar operational choices. This page is the lookup reference for that file. It lists every key the schema accepts, states the type, default and constraints for each, and marks whether the setting actually does anything, because a handful of accepted keys are silently ignored or overridden by another layer.
If the file being looked for is the program file that defines codons and prompts, that is hank.json, covered under Hank configuration. This page covers only the runtime configuration file.
How to read this page#
Two sources define what hankweave.json can contain. The published JSON Schema is the file-shape contract: it lists the allowed keys, their types and their constraints. The runtime's DEFAULT_CONFIG block supplies the values used when a key is omitted. Both appear below, and they answer different questions: the schema says what may be written, the defaults block says what happens when nothing is.
Each key entry is marked effective or non-operative, with the relevant constraints, defaults and precedence rules. A few keys carry dated history lines, marked with a [since …] tag. Output excerpts throughout the page are captured fixture output, normalized per the fixture manifest.
The full key table from the published schema:
| field | type | default | required | constraints | description |
|---|---|---|---|---|---|
port | integer | no | > 0 | WebSocket server port | |
autostart | boolean | no | If true, run immediately on client connect | ||
showCosts | boolean | no | If true, display cost data in the TUI | ||
withoutProxy | boolean | no | Bypass internal LLM proxy | ||
model | string | no | minLength 1 | User's preferred default model. Can be a short name like 'sonnet' or 'opus', a Gemini model like 'gemini-2.0-flash', or any model supported by the configured providers. Validation happens at runtime via LLMRegistry. | |
anthropicBaseUrl | string | no | Custom Anthropic API base URL (for corporate proxies) | ||
outputDirectory | string | no | Where to put results (relative to CWD) | ||
executionBaseDir | string | no | Where to create temp execution environments | ||
logParsingInterval | integer | no | > 0 | Interval for parsing Claude log files (milliseconds) | |
dataHashTimeLimit | integer | no | > 0 | Time limit for hashing directories (milliseconds) | |
idleTimeout | integer | no | min 0; max 255 | Idle timeout for WebSocket and proxy servers in seconds (0-255). This is the maximum amount of time a connection is allowed to be idle before the server closes it. A connection is idling if there is no data sent or rece… | |
shimIdleTimeout | integer | no | > 0; max 1800 | Default shim idle timeout in seconds. Max time between agent events before the shim aborts. Per-codon and hank override settings take precedence. | |
dietOnFinalize | boolean | no | If true, compress a finished run's event journal at shutdown (large file bodies move to a per-run content-addressed store; restore with hankweave --restore-journal). Only runs after the run reached a terminal state (com… | ||
journalDietThresholdBytes | integer | no | > 0 | Minimum file-body size (bytes) extracted to the content-addressed store by the journal diet. Fixed default of 4096; not intended as a tunable. | |
ignoreRigFailures | boolean | no | If true, ignore all rig setup failures (useful for resume workflows) | ||
sentinel | object | no | Sentinel system configuration | ||
telemetry | object | no | Telemetry configuration | ||
budget | object | no | |||
$schema | string | no | JSON Schema URL for editor support |
export const DEFAULT_CONFIG: Omit<
HankweaveConfig,
| "cwd"
| "readOnlySourceDataPath"
| "executionPath"
| "agentRootPath"
| "rigArchivePath"
| "dataPathInExecutionDir"
| "dataHash"
| "isNewExecution"
| "isResuming"
| "linkType"
| "codons"
| "outputDirectory" // Now optional - outputs stay in execution dir by default
> = {
port: 0, // 0 = OS-assigned dynamic port (avoids collisions on multi-instance runs)
version: PACKAGE_VERSION,
// Note: outputDirectory is now undefined by default
// Outputs stay in the agent workspace ({executionPath}/agentRoot) unless explicitly configured
// Informational only — nothing consumes this field. The actual root is resolved
// at call time by getManagedExecutionsRoot() in utils.ts (env var HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR).
executionBaseDir: path.join(os.homedir(), ".hankweave-executions"),
lockFile: ExecutionLayout.RELATIVE_LOCK_FILE,
socketLogFile: ".hankweave/logs/websocket.log",
serverLogFile: ".hankweave/logs/server.log",
logParsingInterval: 1000, // Check for new log entries every second
autostart: true, // Default to current behavior
showCosts: false, // Only show cost data in TUI when HANKWEAVE_RUNTIME_SHOW_COSTS is set
dataHashTimeLimit: 5000, // 5 seconds for directory hashing
toolResultTruncateLength: 2500, // Default truncation length for tool results
withoutProxy: true, // Proxy disabled by default (enable with --proxy)
handshakeHistoryLimit: 50, // Maximum recent events to include in handshake response
idleTimeout: 0, // 0 seconds idle timeout (ie no timeout) for WebSocket and proxy servers (0-255)
dietOnFinalize: true, // Compress finished runs' journals at shutdown (events.jsonl diet P4); restore with --restore-journal
journalDietThresholdBytes: 4096, // Fixed threshold for CAS extraction; not documented as tunable
sentinel: {
enablePersistence: true,
healthCheckGracePeriodMs: 2000, // 2 seconds
waitForAllHealthChecks: false,
},
};
The schema table has no values in its defaults column: defaults live in the runtime, not in the schema. The defaults block above also contains internal fields that are not file settings: version, lockFile, socketLogFile, serverLogFile, toolResultTruncateLength, and handshakeHistoryLimit. These appear in DEFAULT_CONFIG because the runtime uses one object internally, but none of them can be set through hankweave.json; the handshake's 50-event history limit, for instance, is an internal default, and a client needing more reads history through history.sync. (TUI in the table means terminal user interface.)
The codon lifecycle itself is documented on Events; this page covers only the runtime keys that shape it.
Where the file lives and what happens on errors#
hankweave.json is an optional JSON object at <cwd>/hankweave.json. A missing file contributes {}, so every setting falls through to the other configuration layers and the defaults. The loader reads this file only from the current working directory; no runtime-config path or CLI flag selects another one. When nested objects appear in more than one layer, they merge key by key rather than replacing the whole nested object.
The shipped artifact does not create this file. Running --init scaffolds hank.json (the program file), prompts, data, and a README, not hankweave.json. Automatic $schema insertion likewise applies only to hank.json.
The runtime configuration object is strict at the top level: an unrecognized top-level key fails the whole parse with Invalid runtime config file: followed by the validation errors. The budget and sentinel sub-objects are also strict, while unknown keys inside telemetry are stripped rather than rejected. A model value is additionally checked against the model registry: a name the registry does not recognize fails with a not found in registry error, though a close typo can resolve to a nearby model by fuzzy match.
What happens on failure is the part that surprises people. These failures are caught by the file-layer loader, and an existing invalid file is silently ignored: no warning, no log line. The run proceeds on the other layers and defaults as if the file were not there. The only observable is a setting that seems to have had no effect.
The $schema key deserves special attention because the tooling pulls in opposite directions. The published editor schema lists $schema as an allowed property, but the runtime parser does not. Putting $schema inside this file therefore invalidates the entire file and silently drops its other settings. Associate the schema in the editor instead, using the published URL:
| Schema | URL |
|---|---|
hankweave.json | https://unpkg.com/hankweave@0.11.0/schemas/hankweave.schema.json |
The same schema can be referenced locally from node_modules/hankweave/schemas/ when Hankweave is installed as a dependency. In VS Code, the association looks like this:
{
"json.schemas": [
{
"fileMatch": ["**/hankweave.json"],
"url": "https://unpkg.com/hankweave@0.11.0/schemas/hankweave.schema.json"
}
]
}
One exception to the all-or-nothing failure behavior: telemetry is read directly from the file, separately from the validating load, so the raw telemetry object can still be honored when another part of the file fails validation. The parsed telemetry field still deep-merges into the effective config on a successful load. Telemetry defaults and opt-out precedence belong to Telemetry. To keep the two files straight: the published schema above is an editor contract for hankweave.json; the allowed and required root keys of hank.json belong to Hank configuration, not this page.
The captured variants below show concrete file values and their observable effects, so a written file can be compared against what the runtime did. {"port":47391} binds the configured port, {"autostart":false} leaves the server waiting for commands, and {"model":"sonnet"} shows up in the plan summary. A $schema key, as described above, takes the whole file down with it and is silently ignored.
Valid-minimal runtime configuration; output=v0.11.0.
{
"port": 47391
}
Autostart-disabled runtime configuration; output=v0.11.0.
{
"port": 47392,
"autostart": false
}
Model-override runtime configuration; output=v0.11.0.
{
"model": "sonnet"
}
Invalid-schema runtime configuration; output=v0.11.0.
{
"$schema": 123,
"port": 47393
}
Schema-key runtime configuration; output=v0.11.0.
{
"$schema": "https://unpkg.com/hankweave@0.11.0/schemas/hankweave.schema.json",
"port": 47391,
"autostart": false
}
The startup captures below correspond to those files. Both displayed startup probes end with Autostart disabled, waiting for WebSocket commands... and no auto-started codon; neither alone shows a completed run. The valid-minimal capture demonstrates the port setting: the server binds the configured port and reports it in the Listening on line:
Valid-minimal startup capture; output=v0.11.0.
╭────────────────────────────────────────────────────────────────────╮
│ Hankweave v0.11.0 │
│ linux x64 • node v22.23.2 │
╰────────────────────────────────────────────────────────────────────╯
Created new execution directory: ~/.hankweave-executions/<exec-id>
New execution: <exec-id>
Source → data
Exec → ~/.hankweave-executions/<exec-id>
SDKs → Claude node_modules ✓
╭──────────────────────────────────────────────────────────────────────────────╮
│ Runtime config: valid-minimal v1.0.0 │
│ 1 codon • 0 loops │
╰──────────────────────────────────────────────────────────────────────────────╯
└─ [1] write-line (Write one line)
model: haiku │ mode: fresh │ prompts: 1 (2 lines)
checkpointedGlobs: 1
══════════════════════════════════════════════════
Hankweave Server Started
WebSocket: ws://localhost:<port>
══════════════════════════════════════════════════
Running in headless mode on port <port>
Autostart disabled, waiting for WebSocket commands...
➜ Listening on: http://localhost:<port>/ (all interfaces)
exit=0
The autostart: false capture is another disabled-startup observation, on a different configured port:
Autostart-disabled startup capture; output=v0.11.0.
╭────────────────────────────────────────────────────────────────────╮
│ Hankweave v0.11.0 │
│ linux x64 • node v22.23.2 │
╰────────────────────────────────────────────────────────────────────╯
Created new execution directory: ~/.hankweave-executions/<exec-id>
New execution: <exec-id>
Source → data
Exec → ~/.hankweave-executions/<exec-id>
SDKs → Claude node_modules ✓
╭──────────────────────────────────────────────────────────────────────────────╮
│ Runtime config: autostart-false v1.0.0 │
│ 1 codon • 0 loops │
╰──────────────────────────────────────────────────────────────────────────────╯
└─ [1] write-line (Write one line)
model: haiku │ mode: fresh │ prompts: 1 (2 lines)
checkpointedGlobs: 1
══════════════════════════════════════════════════
Hankweave Server Started
WebSocket: ws://localhost:<port>
══════════════════════════════════════════════════
Running in headless mode on port <port>
Autostart disabled, waiting for WebSocket commands...
➜ Listening on: http://localhost:<port>/ (all interfaces)
exit=0
The schema-key capture shows the silent-ignore failure mode in action: the file configured a port and autostart: false, but because $schema invalidated the file, the server binds a dynamic port and autostarts anyway, with no diagnostic:
Schema-key startup capture; output=v0.11.0.
╭────────────────────────────────────────────────────────────────────╮
│ Hankweave v0.11.0 │
│ linux x64 • node v22.23.2 │
╰────────────────────────────────────────────────────────────────────╯
Created new execution directory: ~/.hankweave-executions/<exec-id>
New execution: <exec-id>
Source → data
Exec → ~/.hankweave-executions/<exec-id>
SDKs → Claude node_modules ✓
╭──────────────────────────────────────────────────────────────────────────────╮
│ Runtime config: valid-minimal v1.0.0 │
│ 1 codon • 0 loops │
╰──────────────────────────────────────────────────────────────────────────────╯
└─ [1] write-line (Write one line)
model: haiku │ mode: fresh │ prompts: 1 (2 lines)
checkpointedGlobs: 1
══════════════════════════════════════════════════
Hankweave Server Started
WebSocket: ws://localhost:<port>
══════════════════════════════════════════════════
Running in headless mode on port <port>
➜ Listening on: http://localhost:<port>/ (all interfaces)
exit=0
Finally, the validation capture for the invalid-schema variant shows what --validate reports. Validation checks the hank.json program configuration, not the runtime file, so it passes even though the sibling hankweave.json would be ignored at startup:
Invalid-schema validation capture; output=v0.11.0.
╭────────────────────────────────────────────────────────────────────╮
│ Hankweave v0.11.0 │
│ linux x64 • node v22.23.2 │
╰────────────────────────────────────────────────────────────────────╯
Calculating data signature for validation...
> Validating configuration: <workspace>/fixtures/scenarios/runtime-config/invalid-schema/hank.json
Data source: <workspace>/fixtures/scenarios/runtime-config/invalid-schema/data
Execution path: ~/.hankweave-executions/validation-<id>
✓ Configuration is valid!
╭──────────────────────────────────────────────────────────────────────────────╮
│ Runtime config: invalid-schema v1.0.0 │
│ 1 codon • 0 loops │
╰──────────────────────────────────────────────────────────────────────────────╯
└─ [1] write-line (Write one line)
model: haiku │ mode: fresh │ prompts: 1 (2 lines)
checkpointedGlobs: 1
╭─ GOOD TO RUN! ─────────────────────────────────────────────────────╮
│ 1 codons • 1 prompts • 0 system prompts • 0 rigs • 1 checkpoints │
╰────────────────────────────────────────────────────────────────────╯
Run it: hankweave hank.json <data_path>
See also Hank configuration for the hank.json contract and Hanks for layer order and model precedence.
Server behavior keys#
These keys control the server process itself: which port it binds, when a run starts, how idle connections are declared, and what happens to the event journal at shutdown.
port#
Selects the WebSocket (browser/server connection) port. The file value is an integer > 0; when omitted, the default 0 asks the operating system for a port, avoiding collisions between instances. The bound port is reported at startup and persisted to .hankweave/runtime.lock. Status: effective.
The configured-port row in the assertions excerpt below reports Listening on: http://localhost:47391 and compares the same setting arriving from the environment and CLI layers: all three land on the configured port. See Execution directory for the lock file.
autostart#
Controls whether the server starts immediately when a client connects. It is a boolean with default true. In --headless mode the server autostarts without waiting for a client; false leaves it waiting for WebSocket commands. Disable it with --no-autostart or autostart: false in the file or environment: those are the only two spellings, and there is no positive --autostart flag. Status: effective.
The captured autostart: false variant reports Autostart disabled, waiting for WebSocket commands... and exits with status 0.
withoutProxy#
Controls the internal LLM proxy. It is a boolean with default true, so the proxy is disabled by default. Enable the proxy with --proxy; when it runs, it prefers port + 1. Status: effective. See LLM proxy for proxy behavior.
idleTimeout#
Declared as an integer from 0 through 255 seconds with default 0. Non-operative. The file field, the --idle-timeout flag and HANKWEAVE_RUNTIME_IDLE_TIMEOUT are all parsed and accepted, and the published help and schema wording says a connection idle past the value is closed, but the merged value bounds no idle limit: the WebSocket serve call omits it and both proxy constructions omit it, so neither idle timeout changes. The wired idle setting for codon harnesses is shimIdleTimeout (below). See CLI and Environment variables.
showCosts#
Requests cost display and is a boolean with default false. Non-operative in the file. The TUI reads HANKWEAVE_RUNTIME_SHOW_COSTS directly; no consumer reads the merged file field. The environment variable is the operative cost-display control. Cost display through that variable is [since 0.5.7]. See Environment variables.
The assertions excerpt below summarizes the observed startup behavior across the port and autostart variants, including the environment-variable and CLI spellings of the same settings:
Observed runtime-configuration startup assertions; output=v0.11.0.
hankweave.json {"port":47391}: Listening on: http://localhost:47391 (the configured port) · 1 'Autostart disabled' line(s) · 0 'Auto-starting codon' log line(s)
HANKWEAVE_RUNTIME_PORT=47391 (file also present): Listening on: http://localhost:47391 (the configured port) · 1 'Autostart disabled' line(s) · 0 'Auto-starting codon' log line(s)
--port 47391 (file also present): Listening on: http://localhost:47391 (the configured port) · 1 'Autostart disabled' line(s) · 0 'Auto-starting codon' log line(s)
hankweave.json {"autostart":false}: Listening on: http://localhost:<dynamic port — NOT 47391> · 1 'Autostart disabled' line(s) · 0 'Auto-starting codon' log line(s)
--no-autostart (file also present): Listening on: http://localhost:<dynamic port — NOT 47391> · 1 'Autostart disabled' line(s) · 0 'Auto-starting codon' log line(s)
dietOnFinalize#
Gates the finalize-time journal diet. It is a boolean with default true. With it on, shutdown compresses a finished run's events.jsonl only when two further conditions hold: the run reached a terminal state (completed or failed), and the runtime can still prove it owns runtime.lock. Otherwise it logs Journal diet skipped: … and leaves the journal in place for the offline --diet-journal. Status: effective. The journal format and diet contract belong to Event journal; the maintenance flags to CLI.
Model and API keys#
model#
Selects one global model for codons. It is a non-empty string with no file default. Shortcuts, Gemini spellings, and provider models are checked by the LLM registry. The normal order is CLI > HANKWEAVE_RUNTIME_* environment > hank.json overrides.model > this file's model > defaults; hank.json overrides.model is itself a global override, applied to every codon, including codons inside loops. The resolved value is stamped onto the hank before schema validation, and startup identifies it as applying to all codons. The override takes effect when a plan is built; model-change recipes and resume behavior belong to Hanks and Model resolution. Status: effective.
The captured {"model":"sonnet"} configuration shows the effect in the plan summary: the codon that would otherwise run on its configured model reports model: sonnet, and validation exits with status 0.
Model-override validation capture; output=v0.11.0.
╭────────────────────────────────────────────────────────────────────╮
│ Hankweave v0.11.0 │
│ linux x64 • node v22.23.2 │
╰────────────────────────────────────────────────────────────────────╯
Calculating data signature for validation...
> Validating configuration: <workspace>/fixtures/scenarios/runtime-config/model-override/hank.json
Data source: <workspace>/fixtures/scenarios/runtime-config/model-override/data
Execution path: ~/.hankweave-executions/validation-<id>
✓ Configuration is valid!
╭──────────────────────────────────────────────────────────────────────────────╮
│ Runtime config: model-override v1.0.0 │
│ 1 codon • 0 loops │
╰──────────────────────────────────────────────────────────────────────────────╯
└─ [1] write-line (Write one line)
model: sonnet │ mode: fresh │ prompts: 1 (2 lines)
checkpointedGlobs: 1
╭─ GOOD TO RUN! ─────────────────────────────────────────────────────╮
│ 1 codons • 1 prompts • 0 system prompts • 0 rigs • 1 checkpoints │
╰────────────────────────────────────────────────────────────────────╯
Run it: hankweave hank.json <data_path>
anthropicBaseUrl#
Provides a URI for the Anthropic upstream used by the internal LLM proxy when that proxy is enabled (withoutProxy: false; enable with --proxy). The proxy forwards to this value, defaulting to https://api.anthropic.com when unset. The runner receives the proxy's own URL, not this file value directly, so with the proxy disabled the key has no effect; the Claude Agent SDK separately passes through an ambient ANTHROPIC_BASE_URL, and an enabled proxy URL takes precedence there. It is not a universal Pi or Bedrock gateway setting. Status: effective when the internal proxy is enabled. See LLM proxy and Authentication and models.
Resource and limit keys#
These keys control where outputs and executions live and how long various operations may run. Two of them, executionBaseDir and dataHashTimeLimit, are accepted by the schema but not consumed, so read their entries before relying on them.
outputDirectory#
Selects where output copies go. It is a string with no default. When unset, outputs stay in the agent workspace at {executionPath}/agentRoot; a file value is resolved relative to the original current working directory, and CLI -o takes precedence. There is no hankweave-results default. Status: effective. See Runbook.
executionBaseDir#
Names a managed execution base directory as a string, but has no operative file-layer effect. The managed root is resolved at call time from HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR, or from ~/.hankweave-executions when that variable is absent. Non-operative in the file.
HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR is the effective way to move the managed root. In contrast, -e/--execution selects a particular execution directory for a command; it does not make this file key operative. See Environment variables, Execution directory, and CLI: -e, --execution <path>.
logParsingInterval#
Sets how often codon log parsers check for new entries. It is an integer greater than 0 milliseconds, defaulting to 1000 milliseconds. Status: effective.
dataHashTimeLimit#
Sets a positive integer hashing time limit in milliseconds, default 5000. Non-operative in the file. Both hashing call sites use the DEFAULT_CONFIG constant rather than the merged file field.
journalDietThresholdBytes#
An integer greater than 0, default 4096: the minimum file-body size the finalize-time journal diet (dietOnFinalize, above) extracts to the per-run content-addressed store. The value is passed to the diet call, but the schema marks it a fixed default rather than a tunable. Status: effective.
shimIdleTimeout#
Sets a harness idle limit: a positive integer of at most 1800 seconds, with no single file default. The fallback is harness-specific: 180 seconds for the Claude Agent SDK harness and 120 seconds for the embedded Pi harness. Per-codon and hank.json override settings take precedence. Status: effective. Note that this key has no working environment spelling (see How hankweave.json combines with the other four layers). See Authentication and models and Hank configuration.
ignoreRigFailures#
If true, makes rig setup failures ignorable. It has no schema or DEFAULT_CONFIG default; the effective fallback is false. The file key is combined with a per-operation allowFailure, and it can also be set through HANKWEAVE_RUNTIME_IGNORE_RIG_FAILURES or --ignore-rig-failures. Status: effective. See Rigs, Troubleshooting, and Environment variables.
overwriteOutput#
There is no file spelling for output-conflict behavior. This key is not in the file schema; rename-versus-overwrite is controlled by the CLI --overwrite-output flag. Non-operative as a file key. See CLI.
How budget ceilings combine#
budget#
Sets persistent ceilings for hank runs. It is a strict object with maxDollars: number > 0 and maxTimeSeconds: number > 0; neither has a default. The budget block is [since 0.6.1].
Runtime-file and hank-override ceilings combine as min(runtime, hank). An explicit CLI --max-cost or --max-time then replaces that combined ceiling outright. Runtime environment variables do not currently support budget settings. This budget merge is separate from per-codon model selection and persisted execution plans. Status: effective. See CLI budgets and Hanks.
Sentinel settings#
sentinel#
Configures the runtime sentinel system. It is a strict object with enablePersistence: boolean defaulting to true, healthCheckGracePeriodMs: integer > 0 defaulting to 2000 milliseconds, and waitForAllHealthChecks: boolean defaulting to false. All three are consumed at server start. Per-sentinel *.sentinel.json properties and output paths belong to Sentinel configuration. Status: effective.
Telemetry settings#
telemetry#
Contains enabled: boolean, endpoint: URI, and debug: boolean in a non-strict sub-schema. The resolved default is enabled, debug defaults to false, and the endpoint defaults to https://hw-telemetry.southbridge.ai. The object is read directly from the file rather than through the merged validating load, which is why it can survive validation failures elsewhere in the file, as noted above. Opt-out precedence and privacy details belong to Telemetry. Status: effective.
HANKWEAVE_RUNTIME_TELEMETRY_*#
There is no flat runtime-environment spelling for this object. Because the strict runtime schema has no flat telemetry* key, a HANKWEAVE_RUNTIME_TELEMETRY_* variable causes a startup error instead of configuring telemetry. Invalid, not a telemetry setting. Use the file object and the controls documented by Telemetry and Environment variables.
How hankweave.json combines with the other four layers#
The entries above repeatedly refer to "other layers" winning or losing against the file. For normal runtime fields, the high-to-low order is CLI arguments, HANKWEAVE_RUNTIME_* environment variables, hank.json overrides, hankweave.json, and defaults. Nested objects merge by key. The source comment below records the same order:
* Configuration layers (in order of precedence, highest to lowest):
* 1. CLI arguments (passed as cliArgs parameter) - highest priority
* 2. Environment variables (HANKWEAVE_RUNTIME_*)
* 3. Hank file overrides (hank.json > overrides)
* 4. Runtime config file (hankweave.json)
* 5. Default configuration (DEFAULT_CONFIG) - lowest priority
This is the runtime-settings merge only; per-codon model selection and persisted execution plans have their own ownership on Hanks.
File keys generally map to HANKWEAVE_RUNTIME_<SNAKE_CASE> variables: the prefix is stripped, the remainder becomes camelCase, and nested sentinel keys use HANKWEAVE_RUNTIME_SENTINEL_*. Booleans parse true or 1, and the result is re-checked against the same strict schema. Only six numeric keys convert (port, logParsingInterval, dataHashTimeLimit, healthCheckGracePeriodMs, idleTimeout, journalDietThresholdBytes); any other number-typed key, shimIdleTimeout included, stays a string, so a non-empty HANKWEAVE_RUNTIME_SHIM_IDLE_TIMEOUT fails validation and startup aborts with Invalid environment variable configuration. Budget settings have no environment keys, and telemetry uses its direct file read instead. The mapping sketch below shows the pattern:
* Load configuration from HANKWEAVE_RUNTIME_* environment variables.
*
* Parses environment variables with the HANKWEAVE_RUNTIME_ prefix and converts them
* to the runtime config structure. Handles type conversions and nested paths.
*
* Environment variable mapping:
* - HANKWEAVE_RUNTIME_PORT -> port (number)
* - HANKWEAVE_RUNTIME_MODEL -> model (enum: "sonnet" | "opus")
* - HANKWEAVE_RUNTIME_AUTOSTART -> autostart (boolean)
* - HANKWEAVE_RUNTIME_SHOW_COSTS -> showCosts (boolean)
* - HANKWEAVE_RUNTIME_SENTINEL_ENABLE_PERSISTENCE -> sentinel.enablePersistence (boolean)
The full variable table belongs to Environment variables.
Keys that are accepted but do nothing (yet)#
Several entries above are marked non-operative or invalid. This table collects them in one place, with the working alternative for each:
| Key or spelling | Status | Effective alternative |
|---|---|---|
showCosts | Non-operative in hankweave.json | HANKWEAVE_RUNTIME_SHOW_COSTS |
executionBaseDir | Accepted but not consumed | HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR |
idleTimeout | Parsed and accepted; bounds no WebSocket or proxy idle limit | shimIdleTimeout for the harness idle limit |
dataHashTimeLimit | Merged field is not read by hashing consumers | No file-key alternative is identified here |
HANKWEAVE_RUNTIME_TELEMETRY_* | Invalid flat runtime key; causes a startup error | Use the telemetry file object and telemetry controls |
The detailed entries above remain the primary contracts; this table is a summary, not a substitute. The schema-key startup capture earlier on the page shows the related $schema failure mode: the file uses a dynamic port and autostarts instead of applying its configured port and autostart: false values.
Avoid common configuration mistakes#
When a setting seems to have no effect, the cause is usually one of these distinctions:
outputDirectoryhas no default; when it is unset, outputs remain inagentRoot, nothankweave-results.executionBaseDiris accepted but non-operative; useHANKWEAVE_RUNTIME_EXECUTION_BASE_DIRfor the managed root, and use-e/--executionto select a particular execution directory.- The file default for
autostartistrue; disabling uses--no-autostartor the false file/environment value, and there is no positive--autostartflag. $schemabelongs in editor-sidejson.schemasconfiguration, not insidehankweave.json, because the strict runtime loader omits that property.
See also CLI, Execution directory, Environment variables, and Upgrading.