Skip to content

The harness ​

A harness is the structured execution environment around an agent: how it reaches tools, preserves state, observes feedback, and verifies progress. Long-horizon autonomy depends on it at least as much as on the model, because most failures are not reasoning failures — they are underspecified executions, where the agent lacked the abstractions and feedback to pursue a goal reliably.

Robot RL is an unusually good fit for this view. The MDP already gives you stable interfaces:

M=(S,A,P,r,ρ0,γ,T)

State and action spaces must match simulator observations and control interfaces. Dynamics are determined by assets, control frequency, and physical parameters. Every one of those is separately checkable — and simulators produce executable feedback for checking them.

HARBOR specializes the general harness pattern into five pieces:

HRL=(HA, C, M, G, K)

Agents ​

Context-isolated subprocesses assigned to bounded stages. Each operates on stage-local artifacts and retrieved knowledge, does its own implementation, and returns a compact summary to its caller.

Nine ship today, and each owns exactly one stage: dependency-generator (environment), benchmark-generator (sanity), rl-integration-generator (training stack), task-generator (§1–§5), reward-tuning-agent and reward-candidate-agent (§6), dr-generator (§7), task-cloner (isolation), and rl-tuning-agent (hyperparameters).

Isolation is the point. When a reward candidate fails a smoke test, the traceback, the log tail, and the failed frames belong to that candidate — not to the agent deciding what to try next. That separation is why reward-tuning-agent never writes reward code itself: it designs, and a worker implements, so implementation noise never enters the context making design decisions.

Dispatch depth is capped at two — main thread → orchestrator → worker — and exactly one agent, reward-tuning-agent, carries the ability to dispatch at all. Every other agent is a leaf that does its own delegated work. This is not a convention but an enforced invariant: a contract test fails the build if any other agent acquires the dispatch tool, because unbounded nesting is how an agent tree becomes impossible to reason about or to cancel.

Commands ​

Reproducible operations exposed to agents, from primitives like rl-run to composed loops like reward-tune. Twenty-three ship, grouped by filename prefix — env-*, probe-*/task-*, reward-*, rl-*, and top-level utilities — because a filename prefix is the only grouping mechanism the runtime actually offers.

The same surface is invocable by different agents with different artifacts and gates — and by you, directly, which is what lets you assemble a workflow HARBOR does not ship.

Composability is why almost every command stays model-invocable. rl-sweep calls rl-run; task-create calls reward-tune; test drives the whole chain. A command that Claude cannot invoke cannot be called by another command either, so gating a building block silently breaks every chain above it. Exactly one command is gated — reset-workspace, the only irreversible operation — and the chains that need its behavior read its body and execute it rather than invoking it.

Artifacts ​

Workflow state externalized into persistent, inspectable objects. They are the communication substrate between agents, which reduces reliance on transient context.

Three JSON specs carry the interfaces between stages — install_plan.json, benchmark-spec.json, rl-suite-spec.json — and each is written by one agent and read by everything downstream. Around them sit the per-run records: design histories, smoke verdicts, keyframes, metrics, checkpoints.

This is what makes long runs survivable. A tuning loop checkpoints its state every iteration; a killed agent, an interrupted session, or a resumed conversation picks up from the file rather than from memory. It is also what makes the system auditable: the artifact is the same thing you would have written by hand.

It has a second effect that is easy to miss. Because state is in files, an agent can be given a small view of it — the analysis without the validations, the verdict without the training log — which is what keeps a long loop's context from growing with its own history.

Gates ​

Executable checks that decide whether a stage may advance. See the gate catalogue →

Knowledge ​

Templates, references, scripts, human heuristics, and accumulated experience from previous runs. Knowledge constrains generation, encodes simulator- and algorithm-specific contracts, and gives later agents access to what earlier attempts learned.

It splits three ways:

Templates are rendered into your repository — training scripts, configs, the per-section smokes, the SLURM launchers. Rendering rather than generating is deliberate: a smoke that is authored fresh each run is a smoke whose failures are novel each run.

References are decision aids an agent loads only when it needs them. Twenty-five files, organized so an agent authoring the action space reads s2-actions.md and not the observation guide. Each task-section reference carries the same six headings — what it authors, the decisions to resolve, API pointers, its smoke, failure → diagnosis → fix, and traps — so an agent knows where to look inside a file it has never read.

Experiences are append-only ledgers that accumulate across runs: one per authoring agent, plus a task library of self-contained task specifications indexed by embodiment. The library is what a new task is adapted from — a task-design search runs before any design work begins, so a new task starts from the closest prior one rather than from nothing.

Beneath all three sits the tool layer: 27 deterministic scripts invoked with plain Bash rather than through a server, because the heavy operations are backgrounded GPU jobs whose state must survive a killed agent. Files and exit codes give you that; an in-process server does not.

The execution protocol ​

Every stage runs the same way:

  1. The main agent retrieves relevant knowledge and current artifacts
  2. It spawns a stage-local agent with bounded context
  3. That agent creates or edits artifacts through standardized commands
  4. Gates evaluate the result
  5. Pass → commit the artifact, write logs and metrics back into knowledge
  6. Fail → return the failed check, error message, and observed values to the stage agent for repair
  7. After a fixed retry budget, the stage is marked unresolved and you are asked to intervene

Step 6 matters more than it looks. The agent is handed a diagnosis — which check failed and what value it observed — not a stack trace to interpret.

Step 7's budget is bounded by progress, not attempts, wherever a measurement exists. The section smoke loop escalates after two consecutive attempts that fail to move the measured quantity, rather than burning ten identical retries — and still has a hard backstop at ten. An agent repeating itself is a signal, and spending the budget before reading it wastes both.

What this does and does not guarantee ​

HARBOR does not guarantee the semantic correctness of your final policy. No gate can prove the task you described is the task you meant.

What it does is turn a large class of RL engineering failures into observable gate failures, before they propagate downstream. A wrong action scale caught by an actuator tracking check costs ten minutes. The same bug caught after a twelve-hour training run costs a day, and is usually diagnosed as a reward problem.

The trade is not subtle, and it runs the direction people expect least: removing the gates makes the pipeline faster, and less reliable — a silent render-path defect ships undetected. Speed without verification is what produces the failure you find a week later.

Released under the Apache 2.0 License.