AI coding assistants are genuinely useful. I use them daily. They are also, without structure, a source of regressions, hallucinated APIs, and decisions that nobody authorised.
The solution is not to use AI less carefully. The solution is to design a system around the agent that makes careless choices mechanically difficult. Here is what that looks like in practice.
The Problems a Harness Solves
An AI coding agent working without a harness will:
Rediscover the codebase on every session. The agent has no memory between sessions. It reads files to understand context. On a large codebase, it reads the wrong files, reads too many files, and misses the architectural decisions that are obvious to anyone who has worked in the project for more than a week. Token spend per task is high; accuracy is inconsistent.
Ignore conventions it was never told about. Your team has coding standards, naming patterns, architectural boundaries. They live in your heads and maybe in a README that nobody pointed the agent to. The agent does not know them and invents its own.
Make decisions it was not authorised to make. Agents are helpful. Helpfulness, without guardrails, means the agent will push to main, deploy to production, or delete a file it decided was unused. These are real incidents, not hypotheticals.
Write tests that do not test anything. Left to its own devices, an AI agent will write tests that pass by construction — mocking the entire dependency tree until there is nothing real being tested. The test is green; the code is still wrong.
What a Harness Actually Is
A harness is three things: a memory system, a policy gate system, and a test enforcement system. They interact.
Memory System
The memory system is a set of machine-readable documents that the agent reads at the start of every task — before it opens a source file. Each document describes something the agent needs to know: the architecture of a feature, the data model for a domain entity, known gotchas, how deployments work.
The documents are maintained by the agent as it works. When it builds a new feature, it writes the feature’s memory document. When it changes an interface, it updates the relevant memory. The documents are the agent’s long-term knowledge, persisted across sessions.
The practical effect: a task that previously required the agent to scan thirty files to understand context now requires reading three memory documents. Token spend per task drops significantly. Accuracy improves because the agent is reading curated, accurate information rather than inferring from source code.
The critical discipline: memory documents must be kept current. An outdated memory is worse than no memory — it is confident misinformation. The harness enforces this by gating task completion on memory updates.
Policy Gates
Policy gates are code-level checks that fire before an action happens. They are not prompts, not reminders, not guidelines. They block the action.
Examples:
- Pushing to a remote is blocked unless an explicit authorisation token is present — and the token is only valid if the operator granted permission for that specific push
- Arbitrary code execution shortcuts are blocked unconditionally — there is always a proper, auditable command
- Deploying to production is blocked unless a deployment flag is set — and the flag requires a named explicit authorisation
Gates live in a policy file that is checked by a hook on every shell command. The hook runs in milliseconds — imperceptible in practice, absolute in effect.
The agent cannot convince a gate to open. Gates do not read reasoning. They read the command string and the environment. This is the point.
Test Enforcement
The harness requires the agent to write a failing test before any implementation code. Not a mock test. A test that:
- Runs against the real execution path (no mocking the system under test)
- Fails for the right reason (the feature does not exist yet, not a missing import)
- Is committed before the implementation begins
This is enforced by the workflow state machine: the task transitions from “write test” to “write implementation” only when a test commit exists. The agent cannot skip the step.
The practical effect: regressions that a conventional code review would miss are caught by the test suite, because the test was written from the outside-in (what the feature should do) rather than the inside-out.
The Docs-First Pattern
“Read the documentation” is a vague instruction. “The first tool call on any task is a lookup in the memory system” is a mechanical rule.
On tasks I do with an AI agent in my own workflow, the first operation is always a memory lookup — not a file read, not a grep. The memory system returns a summary. If the summary is sufficient, the task starts. If it is not, the summary tells me which files to read.
This pattern inverts the default: instead of scanning the codebase to build context, the agent reads context that was built in advance, by the same agent, on previous tasks.
The amortisation is real. A memory document takes a few hundred tokens to write. It saves a few thousand tokens on every subsequent task that touches the same feature. Over a project with dozens of features and hundreds of tasks, the token budget impact is large.
What This Does Not Solve
A harness makes an AI coding agent more reliable and more auditable. It does not make it infallible.
Hallucinated APIs still happen. Gates and memory reduce frequency but do not eliminate it. Code review by a human is still necessary.
Poor architectural decisions are still possible. The harness enforces the conventions you have documented. If the conventions are wrong, the harness enforces the wrong conventions consistently. Documentation quality matters.
The harness itself requires maintenance. Policy files, memory documents, and workflow configurations are code. They need to be updated when the conventions change. A stale harness is a liability.
Is This Worth Building?
For a solo developer or a small team using AI coding assistance regularly: yes. The investment is a few days of setup for a system that pays back in reduced regressions, lower token spend, and more consistent code quality.
For a team that is not yet using AI coding assistance: probably worth building a lightweight version now, before the habits form. Retrofitting guardrails onto an established AI workflow is harder than building them from the start.
The alternative — using AI assistants informally, trusting the agent’s judgement, reviewing output for obvious errors — is a reasonable starting position. It is not a sustainable one as codebases grow and AI usage increases.