Skip to content

Harness reference

Every knob of a run, layer by layer. How to use them is on Harness tuning.

On gcp-0, 2026-10-18: harness v0.15.2, composed by crossplane-configuration v0.9.15.

StatusMeaning
live
Seen working on a real run
deployed
Configured, not yet exercised
off
Shipped, switched off
design
Specified, not built

Factory: tiers

config.tiers in tooling/base/agent-factory/helm-values-configmap.yaml. Triage fixes one tier per task; every run of the task inherits it.

deployed
, the USD cap
live

TierrunUSD / taskUSDrunMinutesrunTokens / taskTokens
light0.51 / 1.0220300 k / 600 k
standard2.55 / 5.10451.5 M / 3 M
frontier6.80 / 13.60904 M / 8 M
FieldWhat it doesBounds
modelThe logical model the run asks for. Every tier asks for agent-default today, so the tier changes caps, not the modelA logical name
runUSDThe meter revokes the run at this cost (BudgetExhausted, limit run-usd). Cache reads are priced at their own ratePositive; needs a meter.prices row
runTokensThe claim’s budget.maxTokens. Caps the run only when the meter cannot price it1 … 5 M
taskUSD, taskTokensThe whole task, every run and resume. A new run starts only if a whole run still fits≥ the run cap
runMinutesThe pod’s deadline. A kill at the deadline is PodFailed and never resumed1 … 480

A priced run is held to USD, not tokens: kk2egjta passed 12.5 M tokens against a 4 M maxTokens at $4.46 of $6.80, since 95% were cache reads. The gateway’s per-run budget B1 is the backstop (gateways).

Factory: templates and triage

config.templates: the roles that run, in order, on one branch.

deployed

TemplateRolesReview rounds
soloimplementer—
pairimplementer, reviewer2
trioimplementer, tester, reviewer2
investigatetriager: proposes an issue text, never writes—
  • maxReviewRounds: every revision or restarted review uses one. Out of rounds, the task escalates.
  • reviewerModel: the reviewer’s model whatever the tier says. Unset here: ADR-0058 keeps the public reviewer on the implementer’s model.

Triage picks the template from the class and the tier:

TaskTemplate
A RunLore findinginvestigate, forced internal
docs-linkssolo; pair on frontier
Any other classpair; trio on frontier

The tier would come from the complexity classifier, which is

design
: every task falls back to standard, except one in ten (triage.controlPercent: 10), the control group, on frontier. defaults.template and defaults.tier are read by nothing the deployed factory runs.

The reviewer runs on the other tier: frontier for a standard or light implementer, standard for a frontier one. It keeps the implementer’s maxTokens. The tester keeps the implementer’s tier.

Factory: caps, resume and suspend

KeyValue hereWhat it does
caps.activeTasks3Tasks worked at once
caps.concurrentRuns4Sandboxes at once
caps.tasksPerDay20Past it, a labelled issue is refused with a comment
caps.maxTextBytes14,336The longest task text accepted
caps.maxPendingMinutes30 (5 … 480)A run still Pending escalates as run_unschedulable
resume.maxPerTask2 (1 … 5)Runs lost to infrastructure are resumed; never a PodFailed one.
live
aws-0
sandbox.suspend.enabledtrue on gcp-0An attended run waiting on an approval gives up its pod after 5 min.
live
2026-10-18
budgets.*factoryDaily 25 M, humanDaily 5 MDaily caps; the per-person one counts in shadow

Run API: runs started by hand

task agent:run -- --role … --class … --task … asks the factory for one run.

FlagDefaultNote
--max-tokens2,000,000 (≤ 5 M)A hand-started run has no tier, so it is capped in tokens
--modelagent-defaultOne of the four logical names
--profilesnoneEgress profiles: pypi, npm, golang, crates
--minutes, --sizerefusedFixed at 120 min and small

AgentRun claim

The XRD agentruns.cloud.ogenki.io (definition). Only budget.maxTokens can change on a live run. The factory always writes size: small.

FieldDefaultEffect
rolerequiredimplementer writes and pushes; reviewer, tester, triager read only
dataClassrequiredpublic: Z.ai, GitHub egress. internal: Claude, read-only clone, no egress, cluster read tools, prompt caching
modelagent-defaultThe harness’s MODEL
budget.maxTokens2 M (1 … 5 M)The token cap when the run is not priced
budget.maxMinutes120 (1 … 480)The pod’s deadline and the TTL of its tokens
sizesmallsmall 1→2 CPU, 2→4 GiB; medium ×2; large ×4
egress.profiles[]Package registries on top of GitHub; refused on internal
roomRef—Adds the room-bridge sidecar and the room rules
suspendable—/workspace on a PVC, so the run can be suspended

Composition

apis/agentrun/kcl/main.k turns the claim into the pod. Nothing here is set per run.

SettingValue
Harness imageghcr.io/smana/agent-harness:v0.15.2@sha256:c49c…: a harness change reaches runs only through this digest
EnvironmentMODEL, DATA_CLASS, ROLE, LLM_BASE_URL, MCP_URL, TASK_FILE, RULES_FILE, tracing. LLM_REASONING_EFFORT is not set
rules.mdOne branch, one PR, never .github/workflows/, “a 429 means the budget is spent: stop”. Each rule is also enforced outside the sandbox
task.mdThe task text: the biggest driver of a run’s length
Egressgithub.com and its API, codeload and content hosts, plus each profile’s registries
Grace period30 s, 45 s with a room: checkpoint, final read, stop, revoke
Read-only MCP toolsFlux, VictoriaMetrics and VictoriaLogs reads and the room_* tools; any other needs an approval in a room

Harness

Set in agent_run.py and sitecustomize.py, or left at the SDK v1.49.6 defaults. None is a claim field.

KnobValueEffectStatus
reasoning_efforthighUnsent, GLM-5.3 thinks at maximum: 150 s per reply instead of 11 s
live
Model timeout300 s per callA timeout is not retried: it ends the run
live
Retries3 attempts, 10 s then 20 s apartOn a 503 or a reset. Never a 429 or a timeout
live
max_iterations500Past it the run ends error; the USD cap and deadline usually end it first
deployed
Stuck detectionlast 20 eventsEnds the run stuck on 4 identical cycles, 3 repeated errors or 3 messages with no action
live
Condenser80 events, keep first 4Summarises history with the same model, on the run’s budget
deployed
Event size30,000 charsA huge output is truncated, not refused
deployed
Toolsterminal, file editor, task tracker, MCPNo browser; MCP tools filtered per role by the gateway
live
Prompt cachingon for internal85% of input from cache: $0.48 instead of $2.13
live
autotitleoffSaves a model call per title
live
Step logevery 15 sLines arrive in batches
live
Progress notes5 milestones, ≤ 8 a runFixed texts in the room, nothing the model wrote
live
Checkpoint on SIGTERMimplementer onlyA reclaimed run’s work survives on its branch
live
aws-0
Tracingspan per model and MCP callNo prompt or output content
live
# One run's tokens by model and type, as the meter prices them
sum by (gen_ai_request_model, gen_ai_token_type) (
  max_over_time(gen_ai_client_token_usage_sum{ar_agent="system:serviceaccount:agents:xplane-run-<id>"}[1d]))