harness.json

Every key of the runs settings file (harness.json), where it is read from, how it is decoded, and each key's type, default and meaning, with the nested shapes.

harness.json is the runs settings file: the models, presets and roles for every run, and the tools, formatters and servers they use.

01where it is read from#

The file is the --harness-config flag, else the desk.json harness_config value, taken from the project when relative. There is no default path: with neither set, no file is read. Each linked project still launches with its own record's slug, workspace and checks and smith's defaults for the rest; without a linked project the desk's own harness launches nothing. See desk-json.

02how it is decoded#

decodeHarnessConfigWarn decodes it strictly. An unknown key, a second JSON value or a null file stops the core. A model registry or preset that does not validate is refused at decode.

Every key in this file applies live: a saved change is read without a restart. Only the choice of which file is read (harness_config) is a restart setting.

03roles#

Every role can change runtime. The work role takes claude or codex; intake, plan, review and close take claude, codex or grok. An empty runtime means claude. The reviewer must differ from the worker. A pinned model wins over the role's tags, and a pin that belongs to another runtime is skipped.

04keys#

project_slug

type default meaning
string none The project the config is for.

workspace

type default meaning
string, a path none (each project's scope brings its own) The workspace folder runs work in. It must be a directory when set.

team_project

type default meaning
string none The project the run belongs to, by registry name; the desk lays it in. The run's persona reads that project's team notes under the install's.

work_runtime

type default meaning
string: claude or codex claude The CLI that does the work. The settings page row is "worker runs on".

intake_runtime

type default meaning
string: claude, codex or grok claude The CLI that reads the ticket in.

plan_runtime

type default meaning
string: claude, codex or grok claude The CLI that writes the plan.

review_runtime

type default meaning
string: claude, codex or grok claude The CLI that grades the work.

close_runtime

type default meaning
string: claude, codex or grok claude The CLI that closes the ticket.

intake_model

type default meaning
string none: picked by the role's tags A pin for the intake role's model. It wins over the tags.

plan_model

type default meaning
string none: picked by the role's tags A pin for the plan role's model.

work_model

type default meaning
string none: picked by the role's tags A pin for the work role's model.

review_model

type default meaning
string none: picked by the role's tags A pin for the review role's model. It must differ from the worker's.

close_model

type default meaning
string none: picked by the role's tags A pin for the close role's model.

role_tags

type default meaning
object of role to list of tags intake: code, fast; plan: reasoning; work: code; review: review; close: fast, cheap The tags a role asks the model registry for. A role left out keeps its default. Tags: reasoning, code, review, creative, fast, cheap, long-context.

model_registry

type default meaning
object: runtimes, add, override none: the shipped pool as it is Trims, extends and re-tags the shipped model pool. It is validated at decode.

model_registry runtimes

key type default meaning
runtimes list of claude, codex, grok empty: keep all Keeps only the shipped entries on those runtimes.

model_registry add entries

key type default meaning
add[].runtime string none The runtime that launches the model.
add[].model string none The model id.
add[].tags list of tags none What the model is good for.
add[].rank number not checked How strongly it is preferred; higher wins.

model_registry override entries

key type default meaning
override[].runtime string none Names the pool entry with model.
override[].model string none The model id of the entry to change.
override[].tags list of tags unset: keeps the entry's tags Replaces the entry's tags.
override[].rank number unset: keeps the entry's rank Replaces the entry's rank.

memory_context

type default meaning
list of strings none Memory context handed to the run's providers. Not checked in detail.

memories

type default meaning
list of strings none Memories handed to the run's providers. Not checked in detail.

personas

type default meaning
object of role (*, plan, work, review, close) to a persona none Who a role is. A persona is a built-in persona name, memory:<body>, none, or a declaration object (source, options).

knowledge

type default meaning
list of {source, options} none Context sources declared for runs.

knowledge entries

key type default meaning
knowledge[].source string none The context source's name.
knowledge[].options object none The source's options.

role_kits

type default meaning
object of role to object none A project's own text, model and tools for the roles it overrides. The desk lays them in from the project's settings.

checks

type default meaning
list of check objects none What must pass before a gate. Fields the other check fields (id, executable, args, timeout and shot) are on checks.

checks entries

key type default meaning
checks[].area string none Marks an area's check by the area's name.
checks[].paths list of globs none The check runs only when a changed file is claimed by these globs; ! leaves a file out.

Every check also needs an id and an executable, and a timeout must parse as a duration. A preset's checks may name only configured ids.

areas

type default meaning
list of area objects none The project's areas as the desk read them at launch, in config order. Their checks are in checks. The area brief is on projects.

areas entries

key type default meaning
areas[].name string none The area's name.
areas[].paths list of globs none The files the area claims.
areas[].fence string none The area's fence. Not checked in detail.

checks_cpu_percent

type default meaning
number all cores but two, never below 200 percent The checks node's cpu quota. See checks.

checks_require_containment

type default meaning
bool false Refuses to run checks on a host that cannot seal them off. See checks.

checks_shard_packages

type default meaning
list of package folders none: nothing is split See checks.

checks_shards

type default meaning
number 6 when 0 See checks.

checks_shard_min_tests

type default meaning
number 100 when 0 See checks.

presets

type default meaning
list of preset objects none: the shipped quick, balanced, thorough, max, lean and heavy A preset of a shipped name replaces that preset; any other name is added. Each is validated at decode.

presets entries

key type default meaning
presets[].name string none The preset's name.
presets[].level.floor number 0 The lowest registry rank a role's model may have.
presets[].level.ceiling number 0: no ceiling The highest rank.
presets[].level.prefer highest or lowest highest Whether the strongest or the cheapest model in the band wins.
presets[].level.effort low, medium, high or max none The effort asked of claude and codex.
presets[].pins object of role to model none A model for a role; it wins over the level.
presets[].role_tags object of role to tags none Replaces the tags a role asks for under this preset.
presets[].routes.challenge off, on or auto off The step before the plan. The old key research loads as this.
presets[].routes.review off, on or auto off The first model review.
presets[].routes.second_review off, on or auto off A further review by a different model.
presets[].max_revise_loops number not checked The revise-loop cap.
presets[].checks list of check ids nil: run them all Narrows the check set; it can never empty it.
presets[].budgets.max_output_tokens number 0: no budget The output-token budget.
presets[].budgets.max_searches number 0: no budget The search budget.
presets[].limits object of role to limits none: the template's own Per role: max_output_bytes, max_memory_bytes, active_deadline (a positive duration) and max_attempts. A zero field keeps the template's.
presets[].max_asks number 3 How often the work node may ask a stronger model; 0 turns the ask tool off.

The shipped lean is level prefer lowest and resolves intake claude-sonnet-5-5, plan claude-opus-5-5, work claude-sonnet-5-5, review claude-opus-5-5 and close claude-haiku-4-5-20251001. The shipped heavy is lean with role_tags work [code, reasoning]: work claude-opus-5-5, and review claude-fable-5-1 because review must differ from work. Both have challenge, review and second_review off and max_revise_loops 2, and pin nothing. balanced stays the default.

max_parallel

type default meaning
number 1 How many writer runs go keeps live at once, each in its own worktree. Not the scheduler's options.max_parallel.

mcp_servers

type default meaning
list of server objects none External MCP servers a role may be granted as mcp:<id>. A project's entries replace the global ones with the same id.

mcp_servers entries

key type default meaning
mcp_servers[].id string none Lower-case letters, digits, _ and -; cannot start with smith; unique.
mcp_servers[].command string none A stdio server smith spawns. Exactly one of command or url.
mcp_servers[].args list of strings none Only with command.
mcp_servers[].secrets object of env name to env:NAME none Only with command; the name cannot be PATH or HOME.
mcp_servers[].url string none An http(s) server smith connects to.
mcp_servers[].headers object none Only with url; a value is an optional literal prefix and one trailing env:NAME.
mcp_servers[].tools list of strings nil: every tool the server lists The allowlist.
mcp_servers[].mutating list of strings none Tools that access: read hides; each must be in tools when that is set.
mcp_servers[].access read unset read hides the mutating tools.

tools

type default meaning
list of tool objects none Commands that tool nodes run, by id. Only this file declares them, never a template or a model. A project's local half replaces them whole.

tools entries

key type default meaning
tools[].id string none Letters, digits, ., _, -; unique.
tools[].command string none Required.
tools[].args list of strings none
tools[].timeout duration string not checked Must be positive when set.
tools[].env object none A token-shaped value is refused.
tools[].secrets object of env name to env:NAME none A secret reaches a tool only as a ref.
tools[].output_schema string, a path none Absolute or ~/.
tools[].retries number 0: none Cannot be negative.
tools[].workspace read or empty empty: a scratch folder read makes the run's workspace the tool's working folder.

format

type default meaning
list of formatter objects none Run on the worker's changed files just before the work is sealed. Every project's scope inherits it.

format entries

key type default meaning
format[].id string none Required; unique.
format[].executable string none Required.
format[].args list of strings none The changed files are appended.
format[].match string empty: every changed file A path.Match pattern on a changed file's base name.
format[].timeout duration string not checked Must parse as a duration.