Less Harness, More Test

July 30, 2026

A river running through an abandoned wooden scaffold toward a single glowing gate in a vast valley

The word harness entered the agent vocabulary as scaffolding: the wrapper of prompts, constraints, retries, and guardrails that kept early agents stable through long-running work. It was necessary. Left alone, weak models drifted, looped, and broke things.

Our engineering practice grew the same scaffolding for the same reason. Style docs so the agent would not invent conventions. Lint rules to catch what the model missed. Design reviews before code, code reviews after, checklists in between.

Then the models got better, and something uncomfortable happened: the harness stopped paying for itself. The constraints we wrote to prevent yesterday's failure modes now mostly slow down a system that no longer fails that way. Every rule hard-coded into the process is a bet that the model will stay weak in exactly that way—and lately that bet keeps losing.

So an aggressive idea is circulating, and I have felt its pull myself: throw away the harness entirely. Stop reviewing the process. Ship, let problems surface in real usage, and fix them there. Iterate on outcomes only.

I think this idea is half right, and the half that is wrong is wrong in an instructive way. Information theory—of all things—helps locate the boundary.

The thesis

The bottleneck of an AI-heavy project is human review bandwidth. The fix is not to remove verification but to change its form: kill every constraint a human must verify, keep every constraint a machine can verify, and spend the freed human attention on defining what counts as correct.

"Less harness, more test" is not a call for recklessness. Tests are a harness too. The distinction that matters is not constrained versus unconstrained—it is who does the verifying.

A Shannon view of shipping software

Here is the framing that made this click for me.

Think of a project as a communication channel. On one end is intent: what we actually want the product to be. On the other end is the delivered experience. Everything in between—design docs, architecture diagrams, code, pull requests—is an encoding of that intent, and every encoding is lossy relative to the thing that finally ships.

Human review is sampling from this channel, and every reviewer chooses a position:

  • Read every line of code, and you lose little—at enormous cost in attention.
  • Skip the code but review the architecture, and you lose more, cheaper.
  • Review nothing, and you lose the most, for free.

People argue about which position is right. But notice what all three positions share: as long as a human sits in the verification path, project throughput is capped by human review bandwidth. Models can generate ten times more; the human channel does not widen. You can move the reviewer around, but you cannot make the channel bigger by relocating it.

That is the real content of the anti-harness argument, and it is correct. Any process that routes artifacts through human judgment inherits the ceiling of human judgment. The teams that feel slow right now are not slow at generation. They are saturated at review.

There is no loss-free place to stand

Here is where the aggressive version—review nothing, only watch outcomes—overreaches.

Reviewing outcomes is lossy too. The code is the complete specification of the product's behavior; the "final experience" you observe is a sample of that behavior space. Test twenty paths and the twenty-first path's information is simply gone. Dijkstra said it fifty years ago: testing shows the presence of bugs, never their absence.

So the choice was never between a lossy process review and a lossless outcome review. Both are lossy. Upstream review is lossy compression; downstream review is lossy sampling. There is no vantage point from which you see everything.

Once you accept that, the question changes shape. It is no longer where should the human stand to see the most. It is: for every bit of human attention spent, how many bits of assurance do we get back?

That is an encoding problem, and encoding problems have known solutions.

Rows of analog dials and switches on a vintage control panel

Two kinds of harness

Sort every constraint in your process by who has to verify it, and the pile splits cleanly.

Human-verified constraints: style documents, design review meetings, line-by-line code review, written conventions, approval gates. Each one consumes the bottleneck resource every single time it fires. Their cost scales with output volume, which means they get more expensive precisely as the models get more productive.

Machine-verified constraints: type systems, test suites, evals, invariant checks, schema validation, production monitors. Their verification cost is near zero and they replay infinitely. A test written once verifies every future change for free, at three in the morning, without an ounce of anyone's attention.

This is why the "docs and lint felt like a waste of time" instinct is right for the wrong reason. The problem was never that constraining a model is useless. The problem is that those particular constraints billed their enforcement to humans. A lint rule that runs in CI is fine. A convention that lives in a document a human must remember to check is a tax.

So the slogan sharpens: less harness, more test really means migrate every constraint from human-verified form to machine-verified form. What cannot be migrated should be questioned. What can be migrated is not "harness" anymore in the pejorative sense—it is infrastructure.

Spend human bits on the highest-entropy symbols

Information theory has a second thing to say. Optimal codes spend their bandwidth on the symbols with the most uncertainty. Predictable symbols get short codes; surprising ones get the budget.

Apply that to a project. The lowest-entropy part, increasingly, is the implementation: given a clear specification, a strong model produces correct code with boring regularity. Reading that code line by line is spending your scarcest resource on the most predictable symbol in the stream.

The highest-entropy part is intent: what we actually want, which trade-offs are acceptable, what "correct" even means for this feature. No model can verify that, because the answer exists only in your head until you externalize it.

This explains the migration every experienced team is already living through. First you stop writing the code. Then you stop reading every line and trust the tests. Eventually you stop inspecting individual changes and review only behavior, exceptions, and outcomes. The human loop is not disappearing—it is climbing the entropy gradient, from implementation up to intent, acceptance criteria, and evals.

The endpoint of "review nothing" is mislabeled. The stable endpoint is review only whether intent was satisfied—and put real effort into making intent checkable.

The precondition nobody states

Now for the boundary the radical version ignores.

"Let problems surface in real usage, then fix them" rests on an assumption so convenient it usually goes unstated: that failure is cheap, observable, and reversible. Where the assumption holds, the strategy is genuinely great. UI logic, copy, layout, internal tools—if it is wrong, you see it, you regenerate it, nobody is harmed. Models made rewrites cheap, so pre-verification of easily-reversed work is increasingly pure waste.

But some failures do not get cheaper as models get stronger, because their cost lives outside the code:

  • A schema migration that quietly corrupts data you cannot recompute
  • A security hole that gets exploited before it gets noticed
  • A published API contract that external systems now depend on
  • Anything that spends user trust, which does not roll back

Refactoring is cheap now. Unhappening is still impossible. The blast radius of these failures is unchanged by model capability, and "expose it in production" means exposing users to it. For this category, upstream review remains positive-expected-value no matter how good the models get.

So the honest version of the strategy comes with a precondition attached: outcome-only iteration applies exactly where failure is cheap and reversible. And deciding which parts of the system those are is itself a high-entropy judgment—one of the few that still genuinely requires a human.

Concrete spillway channels of a dam stepping down toward calm water

The harness that remains

Follow the argument to the end and you do not arrive at zero harness. You arrive at a different harness, pointed in a different direction.

The old harness constrained the process: how the agent works, what steps it follows, which conventions it obeys. That one is dying, and deserves to.

The harness worth building constrains the feedback loop: it exists to make each iteration of ship-observe-fix fast, cheap, and bounded in damage. Observability, so failures are seen rather than silently absorbed. Staged rollouts and canaries, so failures are small. Rollback, so failures are short. Sandboxes and permission boundaries, so agents can be aggressive inside a container. Evals, so "does this satisfy intent" is a query rather than a meeting.

Shannon again, one last time. When a channel is noisy, you have two options: have a human proofread every message—retransmission, the expensive path—or add error-correcting codes so mistakes are detected and fixed without anyone re-reading anything. Tests, types, monitors, and rollback are error correction for software. The redundancy is not overhead. The redundancy is what lets you stop proofreading.

Closing thought

The bottleneck was never the harness or its absence—it was the human in the verification path. Compile your judgment into constraints machines can check, reserve your own attention for deciding what counts as correct, and keep the old-fashioned review for the one category that earns it: mistakes that cannot be undone.