harness.toml¶
The manifest declares what the resolver may try and what "best" means. hlock init writes
a starter one. Every section is optional, but a useful manifest has at least
[tasks], [candidates], and [objective].
[project]
name = "support-agent"
[target]
harness = "claude-code"
[tasks]
packs = ["./tasks"]
seeds = 3
[tasks.splits]
search = 0.7
[candidates.llm.planner]
any_of = ["reference:qwen-7b", "reference:qwen-32b"]
[candidates]
decision = ["none", "rules:default"]
harness = ["reference"]
[candidates.policy]
retries = [1]
[objective]
primary = "success-rate"
select = "min-cost"
[objective.constraints]
success-rate = ">=0.8"
cost-usd-per-task = "<=0.05"
[budget]
strategy = "grid"
max_trials = 200
max_spend_usd = 25.0
random_seed = 0
[backend]
target = "local"
[project]¶
| Key | Description |
|---|---|
name |
Project name, recorded as the lock's stack name |
[tasks]¶
| Key | Default | Description |
|---|---|---|
packs |
[] |
Paths to task pack directories |
seeds |
3 |
Runs per task per candidate |
splits.search |
0.7 |
Fraction of tasks in the search split. The rest is holdout. |
[candidates]¶
The search space. The resolver tries every combination.
| Key | Description |
|---|---|
llm.<role>.any_of |
Candidate models for a role, as "provider:model". v0.1 tunes the planner role. |
decision |
Candidate decision models, e.g. "none", "rules:default" |
harness |
Candidate harnesses: names, or tables with name, pattern, and config |
policy.<key> |
Policy values, e.g. retries = [1], temperature = [0.2]. resolve uses the first value. optimize searches retries and temperature itself. |
v0.1 ships the reference provider (models qwen-1.5b, qwen-7b, qwen-32b) and the
reference harness. Real providers run through the worker on the
devbox and cluster backends.
[objective]¶
| Key | Default | Description |
|---|---|---|
primary |
"success-rate" |
The metric being optimized |
select |
"min-cost" |
How to choose among stacks that pass: "min-cost" or "max-quality" |
constraints |
{} |
Hard limits, as a table of metric to comparison |
Constraint metrics are success-rate and cost-usd-per-task. Comparisons are >=,
<=, >, and < followed by a number. When no stack satisfies every constraint, the
resolver selects from the whole Pareto front instead of failing; see
Selection.
[budget]¶
| Key | Default | Description |
|---|---|---|
strategy |
"grid" |
Search strategy. v0.1 supports grid. |
max_trials |
Upper bound on trials | |
max_spend_usd |
Upper bound on spend | |
random_seed |
0 |
Seed for the search/holdout split |
[target]¶
| Key | Description |
|---|---|
harness |
The harness this lock is for: an id or alias from hlock harness list, or a [harnesses.<id>] table. resolve narrows [candidates] harness to it and check enforces it. See Harnesses. |
[harnesses.<id>]¶
A project harness: an agent built on a framework, or any executable. It accepts every harness profile field, plus these at the top level:
| Key | Description |
|---|---|
entrypoint |
Python module:callable |
command |
Executable and arguments; {prompt}, {model}, and {workspace} are placeholders |
framework |
A framework profile (pydantic-ai, deepagents, langgraph, openai-agents, claude-agent-sdk, google-adk, smolagents, crewai) whose packages are pinned |
packages |
Extra packages to pin, e.g. ["pypi:httpx"] |
python |
Interpreter for entrypoint (default HL_PYTHON, else python3) |
env |
Extra environment variables |
One of entrypoint or command is required.
[backend]¶
| Key | Default | Description |
|---|---|---|
target |
"local" |
local, devbox, or cluster. See Backends. |
Reserved sections¶
[tools], [skills], [instructions], [context], and [enforce] are parsed and
included in the manifest hash. They're placeholders for the peripherals described in
the design spec, and
the v0.1 resolver doesn't search over them yet.
The manifest hash¶
The lock records a SHA-256 hash of the manifest file exactly as written, comments and
whitespace included. hlock check compares it to the live file, so
any edit to harness.toml needs a fresh hlock resolve.