Trust Is Not a Property of the Model: The Strategic Case for Harness Engineering
Trust is not a property of the model. It is a property of the system around it.
The wrong question
When a company starts integrating AI coding agents into its development process, the first question that surfaces is usually this: can we trust the code the AI produces?
It is the wrong question.
Large language models are non-deterministic by nature. They do not truly understand code; they generate it on statistical probability. They are not familiar with your business context or your team’s conventions, and they have no organizational memory. This is not a defect; it is a fundamental property of the technology. To ask whether such a system can be trusted is to ask the wrong question twice — once about the model, and once about trust itself.
Software engineering has long known that quality is not achieved by an inspection at the last moment, but through systematic feedforward control and feedback correction. Applying that principle to AI agents is what harness engineering is. Our work is not to make the model trustworthy. Our work is to build confidence on top of a reality that will not change — systematically.
The loop beneath the equation
In the world of AI agents there is a compact equation: Agent = model + harness.
The model is the brain. The harness is every constraint, guide, and monitor built around it — the system prompt, the code retrieval mechanism, the orchestration systems, and above all the external controls we build for a particular system and context. A well-designed external harness has two explicit goals: raise the probability that the agent gets it right the first time, and establish a self-correction loop, so that as many problems as possible are resolved before they reach human eyes. The end benefit is threefold: lower human review cost, higher system quality, and less token consumption wasted along the way.
The operating logic comes from control theory, and it runs in two directions.
A guide is feedforward control. Architecture documents, coding standards, runbooks, custom skills — they define expected behavior in advance, so the agent moves in the right direction on the first attempt. A sensor is feedback control. Automated tests, static analysis, code review agents, runtime monitoring signals — they observe the moment the agent produces something and hand it a signal to self-correct. Sensors are especially powerful when their output is optimized for LLM consumption: a custom linter message with self-correction instructions embedded in it is essentially prompt injection in the constructive direction.
The key insight is an old one. With feedback alone, the agent repeats the same mistakes; with feedforward alone, you never learn whether the rules actually work. Both have to be present.
Controls come in two execution types, and the strategic principle is equally old: if it can be solved computationally, do not solve it inferentially. Computational controls — linters, type checking, structural tests, CLI scripts — are deterministic, millisecond-scale, and cost close to nothing; they should be deployed everywhere. Inferential controls — AI code review, LLM judges, semantic duplication detection — run on GPU/NPU, cost more, and are non-deterministic by nature; they handle the high-value cases that require semantic judgment. An inferential sensor raises confidence considerably when it uses a model suited to the task at hand.
And controls must be placed where the lifecycle demands them. Before commit, immediate sensing — linters, a fast test suite, a basic code review agent — has to complete within seconds to support the agent’s self-correction loop. After integration, deep sensing belongs in the CI pipeline: mutation testing, broader review that takes in the larger system picture, architectural fitness checks. And some degradation accumulates gradually, needing continuous drift monitoring — dead code detection, test coverage quality analysis, dependency scanning, agents watching SLOs for degradation trends, an AI judge sampling response quality and flagging anomalies in the logs.
The human role in this loop is to steer: every time a problem occurs more than once, the corresponding guide or sensor should be improved, until the probability of that problem recurring drops — or is eliminated. Notably, the steering loop itself can be accelerated with AI. Coding agents make it cheaper to build more custom controls and static analysis — an agent can help write structural tests, draft rules from observed patterns, scaffold a custom linter, or produce a runbook from archaeology on the codebase.
The three dimensions of regulation
The harness plays the role of a cybernetic governor, combining feedforward and feedback to regulate the codebase toward its desired state. Distinguishing the dimensions of that desired state gives us more precise technical language. There are three.
A maintainability harness regulates internal code quality. This is the easiest type to build today, because a great deal of existing tooling can be used directly. Computational sensors reliably catch structural problems: duplicated code, cyclomatic complexity, insufficient test coverage, architectural drift, style violations — cheap, proven, deterministic. Inferential sensors partly address the problems that require semantic judgment: semantically duplicated code, redundant tests, brute-force fixes, over-engineered solutions — more expensive, probabilistic, and therefore not for every commit. And there is a class of problems neither catches reliably: misdiagnosed issues, over-engineering, misread instructions. If a person never stated the requirement clearly to begin with, correctness itself falls outside what any sensor is responsible for.
An architectural fitness harness regulates the characteristics of the application as a whole — in essence, a concrete implementation of fitness functions. Performance requirements as a feedforward skill; performance regression tests as a feedback sensor, so the agent knows whether it improved or degraded performance. Coding conventions for observability as feedforward — logging standards, for instance — plus debugging instructions that ask the agent to reflect on the quality of its own logging. This layer ensures the agent does not merely write code that works, but code that matches the architectural vision.
A behavioral harness regulates whether the application does what it is supposed to do. This is the most central and most challenging area: how do we guide and sense functional behavior? Current practice — where coding agents are given a high degree of autonomy — tends to look like this: functional specifications as feedforward, from a short prompt to a multi-file description; and feedback that checks whether the AI-generated test suite is green and coverage is reasonable, with some teams adding mutation testing and manual testing.
Why the behavioral harness is the linchpin
That last paragraph deserves a second look, because it contains the whole problem. This approach places a great deal of trust in AI-generated tests, and that is not sufficient. The approved fixtures pattern has shown good results in certain domains, but it is not a complete answer to the test quality problem. The tests are written by the same non-deterministic system they are meant to constrain; the sensor and the thing sensed share a single point of failure.
Candor is required: finding a good harness for functional behavior — one strong enough to reduce supervision and manual testing — remains a frontier that needs a lot of exploration. The maintainability harness and the architectural fitness harness regulate how the code is written. The behavioral harness regulates what the code does — and what the code does is what the user experiences. It is the reason any of this matters.
Harnessability, and what Ashby’s law tells us
Not every codebase lends itself equally to a harness. A codebase written in a strongly typed language has type checking as a built-in sensor; clearly definable module boundaries suit architectural constraint rules; a framework like Spring abstracts away details the agent does not have to handle, implicitly raising its probability of success. In systems without those properties, these controls cannot be built at all.
One concept worth naming: ambient affordances — the structural properties of an agent’s environment that make it more harnessable. Legible. Navigable. Tractable.
Greenfield projects and existing systems differ fundamentally here. A greenfield team can build harnessability in from day one: technical decisions and architectural choices determine how governable the codebase will be later. Teams with existing systems, especially applications carrying a lot of technical debt, face a paradox — the place where a harness is needed most is often the place where it is hardest to build.
Ashby’s Law of Requisite Variety offers the theoretical lens. A regulator must have at least as much variety as the system it governs, and it can only regulate what it has a model of. An LLM-based agent can produce almost any code — that space is enormous. Adopting predefined topologies and harness templates is, in effect, a strategic narrowing of the problem space that makes comprehensive governance attainable. Defining a topology is itself an act of variety reduction.
The service topologies of most enterprises reduce to a handful of patterns covering 80% of the need — business services exposing data through an API, event processing services, data dashboards. In mature engineering organizations these have long been codified as service templates. The next step in that evolution is harness templates: a bundle of preconfigured guides and sensors that tether a coding agent to the structure, conventions, and stack of a particular topology. In future, teams may choose their stack and structure partly on the basis of which harnesses are already available. Harness templates will of course face the same versioning challenge as service templates: once a team instantiates them, they begin to drift out of sync with upstream improvements — and non-deterministic guides and sensors make testing harder, which may make that problem more acute.
The human role
As human developers, we bring our own skill and experience to every codebase as an implicit harness: absorbing conventions and good practice, feeling the cognitive load of complexity, knowing our name is on the commit. We carry organizational alignment — knowing what the team is trying to achieve, which technical debt is tolerated for business reasons, and what “good” looks like in this particular context. We move in small steps at a human pace, which leaves room for that experience to be triggered and applied.
A coding agent has none of this. No social accountability. No aesthetic aversion to a three-hundred-line function. No instinct for “that is not how we do it here.” No organizational memory. It does not know which convention is load-bearing and which is merely habit, nor whether the technically correct solution fits the team’s direction.
A harness is an attempt to externalize and make explicit what a human developer’s experience brings — but it only goes so far. Building a coherent system of guides, sensors, and self-correction loops is expensive, so it has to be prioritized with a clear goal in mind: a good harness should not aim to eliminate human input entirely, but to direct it where it matters most.
Where the boundaries are collapsing and what comes next
The mental model set out here describes techniques already happening in practice, and gives a frame for discussing what still needs to be worked out. Several practices are worth watching: enforcing layered architecture with custom linters and structural tests, plus periodic “garbage collection” passes that scan for drift and let an agent propose fixes; pre-push hooks that run the relevant linters based on heuristics, bringing feedback into the agent workflow as early as possible; a revival of mutation testing and structural tests as computational feedback sensors; integrating LSP and code intelligence into coding agents as computational feedforward guidance; handling architectural drift with agents combining computational and inferential sensors.
Plenty remains unresolved. As a harness grows, how do we keep it coherent — guides and sensors in sync rather than contradicting each other? When instructions and feedback signals point in different directions, how far can the agent be trusted to make a sensible trade-off? If a sensor never fires, is that a sign of high quality or of inadequate detection?
We need something for harnesses like what code coverage and mutation testing are for tests: a way to assess their coverage and quality. Feedforward and feedback controls are currently scattered across the delivery steps, and there is real potential in tooling that helps configure, synchronize, and reason about them as one system.
Trust, in the end, is not a property of the model. It is a property of the system around it — and the system around it is built, not found. Building this external harness is becoming a continuous engineering practice, not a one-time setup. The model is the brain; the harness is the discipline. And discipline is where confidence comes from.