Part 1 of 9Harness Engineering

Harness Engineer: From Test Harnesses to Agent-First Engineering

How test harnesses, CI, tool-using agents, and feedback systems evolved into the emerging discipline of harness engineering.

A hand-drawn timeline tracing harness engineering from test harnesses to agent-first systems

A powerful model dropped into a repository with no map, tests, or observable runtime is like a new engineer given keys but no orientation. It may produce code, yet it cannot reliably tell where the boundaries are, whether a change is correct, or when the job is done.

The hard part of a coding agent therefore does not live only inside the model. It lives in the environment around it: context that explains intent, tools that make action possible, and feedback that lets the system correct itself.

A seven-stage timeline showing the harness expanding from test execution through CI, AI pair programming, tool-using agents, and harness engineering.
Figure 1The scope of the harness expands from controlling a test run to organizing the entire environment in which an agent works.

That lineage matters. “Harness” is not a fashionable word attached to AI after the fact. Software engineering has been building harnesses for decades—first around code, then around delivery pipelines, and now around agents. Model capability expands what can be attempted. Harness quality determines what can be repeated, inspected, and trusted.

1. Test harnesses created a small, controllable world

A test suite contains questions. A test harness creates the conditions under which those questions can be asked the same way, many times, with results that humans and machines can read.

In a basic harness, a fixture prepares inputs and initial state. A driver invokes the system under test in the way a user or another component would. Stubs and fakes replace dependencies that are expensive, unavailable, or unstable—networks, clocks, databases, and external services. An oracle compares what happened with what should have happened, turning a difference into evidence.

The ISTQB glossary defines a test harness as a test environment made up of the stubs and drivers needed to execute a test suite. The definition is compact, but it contains the idea that runs through this entire history: reliability comes not only from the logic being tested, but from an environment that makes behavior repeatable and observable.

A test harness flow where fixtures and a driver feed the system under test, a stub controls dependencies, and an oracle produces pass-or-fail evidence.
Figure 2A traditional harness arranges the world, triggers behavior, controls dependencies, and converts comparison into evidence.

This is why “we have tests” is not the same as “we have good feedback.” If setup is not reproducible, dependencies still drift, or failures do not point toward their cause, the harness adds noise. A good harness narrows the world enough to connect a change to an outcome. It does not prove that software is perfect; it produces evidence close enough to the change that correction is practical.

2. CI turned feedback into shared infrastructure

A harness running only on one developer’s machine is limited by that person remembering to run it and by the peculiarities of their environment. Continuous integration moved the same verification logic into a shared reference environment. A change could trigger a build, tests, and agreed checks, then return the result to the team.

The important shift was not the number of tools. It was the distance between change and evidence. Batch integration collects many changes before failure appears; by then, the search space is larger and rework must travel backward through several handoffs. A short CI loop creates a signal after each small integration, keeping a failure closer to its cause.

In their original 2000 article, Martin Fowler and Matthew Foemmel emphasized a fully automated, reproducible build that includes testing and runs many times per day. Fowler’s current guide still places an automated build and rapid feedback at the center.

A comparison between delayed batch integration before CI and a short repeatable loop from commit through build, tests, evidence, and correction.
Figure 3CI replaces delayed, batched failure with a repeatable loop in which evidence appears near the change that produced it.

At this point, the harness stopped being a local testing utility and became shared delivery infrastructure: triggers, reference environments, quality gates, artifacts, and a history of results. That pattern becomes a direct bridge to coding agents. An agent also needs test failures, lint errors, screenshots, logs, and review comments to return soon enough to change its next move.

3. AI pair programming expanded the task boundary

When GitHub introduced Copilot as an “AI pair programmer” in June 2021, the product drew context from the code being edited and suggested lines or whole functions. The interaction was local and easy to supervise: the developer remained at the keyboard, saw the suggestion, and chose whether to accept it.

Chat then widened the boundary from the current cursor to a question. Repository retrieval widened it again. Edit modes crossed from advice into file changes. Tool use allowed the system to search, run commands, inspect failures, and act across a repository. An autonomous task finally crossed into workflow scope: the system could plan several steps and continue without approval at every line.

A rising staircase from code completion to autonomous tasks, with task scope, agency, and harness requirements increasing at every step.
Figure 4As agency and task scope grow, the harness must supply more context, control more effects, and define stronger completion criteria.

This progression is often described as model improvement, but the product boundary changed just as much as the model did. A suggestion needs cursor context. A repository edit needs a trustworthy diff and review surface. Tool use needs permissions and readable observations. Autonomous work needs a goal, durable state, budgets, verification, and a stop condition. More agency increases the surface that must be made legible and safe.

4. Reason and act closed the loop with the environment

Generating code is not the same as operating a workflow. The conceptual break came when language models could interleave decisions with actions and use observations from the outside world to update what happened next.

The ReAct work formalized this pattern by interleaving reasoning traces with task-specific actions. Actions connect the model to an external source or environment; observations bring new information back. For a production coding agent, the useful abstraction is not private chain-of-thought. It is the system-level control flow: intent, plan, action, observation, and update.

A closed agent feedback loop connecting intent, plan, action, observation, and update, constrained by policy, budget, and a stop condition.
Figure 5Action becomes useful only when an observation returns in a form that can change the next move.

A shell command that returns ten thousand irrelevant lines is technically an observation, but a poor one. A test that says only “failed” closes the loop, but weakly. A screenshot the agent cannot inspect may as well not exist. Good harness design therefore compresses the environment into actionable evidence: the failing assertion, the narrow log window, the DOM state, the changed file, or the approval that is actually required.

Without legible observations, autonomy becomes open-loop execution. The agent can continue doing things, but cannot reliably tell whether those things move it toward the goal.

5. In a coding agent, the model is only one component

A coding agent is better understood as a system than as a model with a terminal attached. The model sits inside layers that load context, preserve task state, expose tools, isolate effects, and evaluate outcomes.

Context and memory tell the model what matters now. A repository map helps it find deeper sources of truth without flooding the context window. Tools and runtime turn intent into effects. A sandbox and permission model limit the blast radius. Git and worktrees make changes inspectable and allow tasks to proceed in isolation. Tests, logs, screenshots, and review turn execution back into evidence.

OpenAI’s description of the Codex harness and App Server separates the core agent loop from thread persistence, configuration, authentication, sandboxed tool execution, MCP servers, and skills. That architecture is useful beyond one product: it shows why model quality is only one term in the reliability equation.

A layered agent system with the model inside context and memory, tools and runtime, then policy, verification, observability, and human checkpoints.
Figure 6Reliability emerges from the interaction among model, context, runtime, controls, verification, and human judgment.

A stronger model can improve planning and code generation, but it cannot recover information that the harness never exposes. It cannot obey a boundary that exists only in someone’s head. It cannot validate a UI it cannot open or inspect. It cannot safely use a destructive tool when the permission model has no distinction between reading and deleting. From the agent’s point of view, inaccessible context and invisible feedback do not exist.

6. Harness engineering turns failures into reusable capability

Prompting harder is a local correction. Harness engineering asks a different question: what was missing from the environment, and how can the correction become reusable?

A flaky setup may reveal the need for a deterministic fixture. An architecture violation may reveal that prose guidance should become a structural lint. A UI regression may reveal that the agent needs browser access and screenshot checks. A long task that loses direction may need smaller work units, persistent state, or structured handoffs.

Anthropic’s work on harnesses for long-running application development highlights decomposition, structured handoffs, and separation among planner, generator, and evaluator roles. OpenAI’s agent-first engineering report similarly describes repository knowledge as a system of record, agent-legible applications and observability, mechanically enforced invariants, and failures treated as signals of missing capability.

A flywheel turning failures into missing capabilities, encoded rules or tools, agent-readable feedback, and broader task boundaries.
Figure 7A failure becomes valuable when one correction is encoded into the environment and improves every later run.

This creates a flywheel. Failure identifies a missing capability. The team encodes that capability as a rule, tool, test, environment improvement, or better feedback. The agent can then operate across a broader task boundary. New failures appear at that boundary, and the cycle repeats. Human judgment is not removed; it moves upstream, from correcting every line to designing constraints and evidence that compound.

The Harness Engineer designs leverage

“Harness Engineer” is not yet a universal job title, and it may never settle into one standardized role. It is more useful today as a name for an emerging responsibility.

That responsibility sits between developer experience, platform engineering, quality engineering, and AI systems. It includes making repositories navigable to agents; defining safe tool surfaces and permission boundaries; turning product behavior into observable evidence; building evaluators that are separate from generators; preserving state across long tasks; and converting repeated review feedback into enforceable rules.

The center of gravity shifts from controlling each line to designing intent, boundaries, evidence, and learning loops. The engineer still decides what matters. The difference is that their judgment is captured once and applied repeatedly by the system.

The historical thread is now visible: test harnesses controlled the conditions of a test; CI standardized the feedback loop for a team; AI pair programming expanded the boundary of assistance; reason-and-act connected models to environments; coding agents assembled those parts into a runtime; and harness engineering made the runtime itself an object of deliberate design.

The model creates capability. The harness turns capability into work that can be observed, verified, and repeated.

Sources

Read more

All posts
  1. A hand-drawn map showing the Harness Engineer between developer experience, platform engineering, quality engineering, and AI systems
  2. A hand-drawn verification pyramid rising from deterministic checks to human judgment
  3. A hand-drawn stack of six harness layers from context and tools to feedback and verification
  4. A hand-drawn system map placing a model inside context, tools, runtime, task state, verification, and human control