Saulo Valdivia

The harness doesn't replace the SDLC. It replaces the QA loop inside it.

· The harness era

There’s a word going around QA circles that I couldn’t shake this year: harness. Not the test-harness you already know — the old xUnit “harness” that just means “the thing that runs your tests.” A different, bigger idea, and one that’s quietly rearranging what the job is.

The loud version of it is wrong: “AI replaces QA.” The quiet version is more interesting, and it’s the whole post: the harness doesn’t replace the software lifecycle. It replaces the manual, full-suite, release-gated QA loop that sits inside it — and in doing so it moves the QA person up a level, from writing the tests to owning what “correct” means and whether to trust the machine’s calls.

Let me start with where the word even comes from, because the name is doing real work.

Wait — what’s a “harness”?

The term didn’t start in QA. It came out of the agent-engineering world, where a harness is the runtime container that wraps an AI agent — the code that gives it tools, feeds it context, enforces its boundaries, and runs its loop. The counter-intuitive thing people building production agents kept discovering is that the agent is the small part. One analysis of Claude Code’s codebase making the rounds put it starkly: reportedly ~98% of the code is harness — lifecycle, sensors, safety, memory — and only a sliver is the actual “AI decision” layer. (I say reportedly because I haven’t verified that exact number, but the direction is the point, and the direction isn’t controversial: the model is the easy part; the cage you run it in is the engineering.) The idea traces back to the “build the scaffolding around the model, not just prompt the model” school — the same lineage as Anthropic’s Building Effective Agents.

The person who dragged that idea into QA specifically is Yusuf Tayman, in a piece called “The Harness Era of QA Has Started.” His reframe is the one line this whole post hangs on:

“Give the agent freedom inside a fence. The fence is the harness.”

His argument: the shift isn’t adding AI to existing QA processes — it’s rebuilding QA processes around agents. You stop being the person who writes and hand-maintains the test suite; you become the person who builds the harness — the guides, sensors, memory, and safety rules — that an agent operates inside. A related slogan from Sergey Tselovalnikov gets quoted a lot in the same breath: “We are all QA Engineers now” — because once agents write the feature code, a human’s primary output shifts to the harness that proves the feature works.

Two quick disambiguations so nobody gets confused later. “Harness engineering” (the discipline) is not the same as Harness.io (a CI/CD vendor whose name collides with it) — I mean the discipline. And a QA harness is not a test framework with a chatbot bolted on; the difference is who holds the judgment — in classic automation I write every assertion, in a harness the agent decides what to check inside a fence I designed. That distinction is the whole reason any of the following matters.

Infographic titled "Anatomy of an Agentic QA Harness": a central AI-agent icon inside a rounded boundary labeled "the fence," surrounded by its four components — Guides (how the agent should work), Sensors (deterministic ground-truth signals: console, HTTP status, DOM, visual diff), Memory (version-controlled, learns across runs), and Safety rules / the fence (what it must not do: read-only, scoped, no destructive actions). A caption reads: classic automation, I hold all four; harness engineering, the environment holds all four, so an agent can stand where I stood.

So a harness has four parts, and it’s worth naming them once because the rest of the post leans on them:

In classic automation, I am all four of those — I hold the procedure, decide the assertions, remember what’s flaky, and avoid prod. Harness engineering externalizes all four into the environment so an agent can stand where I stood. That’s the move. Now — what it does to the loop.

The classical loop, and the thing everyone actually hates about it

Infographic titled "The Classical SDLC — the QA loop inside it": a left-to-right pipeline of five connected stages — Dev → QA environment → Manual QA + full regression → UAT → Prod — with the "Manual QA + full regression" stage highlighted as the focal point. A callout below lists four things that quietly eat the week: release cadence (tests run on a release train or nightly, not when the change was made), full suite every deploy (the whole regression runs every time; it only gets slower), human-gated (someone signs off by gut; trust is tribal and unlogged), and hand-maintained (every UI restyle breaks selectors; a human fixes them each sprint).

The lifecycle you know: dev writes code → it lands in a QA environment → QA runs a pass → UAT → prod. Mine is the small-team version of exactly this: once a change is ready I test it in QA, then again in UAT before it ships. And when you’re the only QA, that shape has a failure mode — you become the bottleneck. The release has to go out, so you start quietly skipping the tests you’re least worried about just to keep up. It taxes automation too: I’d be heads-down testing one feature, then pulled straight onto the next, so the suite never got the attention that would have kept it from rotting.

The phases aren’t the problem. The problem is the QA loop inside them, and it has four properties that quietly eat your week:

That’s not a knock on anyone. It’s the structure. And it’s exactly the structure the harness rebuilds.

The core shift, in one line

Classical QA is release-cadence, full-suite, human-gated, human-maintained.

The harness is commit-cadence, change-scoped, deterministically-gated, self-maintained.

Infographic titled "The Agentic-Harness SDLC — the QA loop, rebuilt": a closed loop that fires on every code change, with six stages — Trigger, Select, Run, Sense + judge (which branches to "heal the locator and stay green" on drift, or "leave it red, never mask the bug" on a regression), Verify + gate, and Memory. Trigger and Verify + gate are marked with dashed borders as deferred plumbing. A side legend titled "the shift" contrasts classical (release-cadence, full-suite, human-gated, human-maintained) with harness (commit-cadence, change-scoped, deterministically-gated, self-maintained).

Here’s the same idea as a table. The right-most column is the part that keeps this honest — it names which harness component does the work, so you can see this isn’t magic, it’s the four parts above doing specific jobs:

QA concernClassical SDLCAgentic harnessWhich part does it
When testing runsOn a release train / nightly; a deploy gateOn every push/PR, scoped to the diff(a CI trigger — the plumbing)
Which tests runThe whole regression suite, every deployThe impacted subset; full-suite only on risky changesGuides + the agent’s reasoning
Who decides what to skipA human smoke-tests by gut, or you run everything to be safeA cheap deterministic rule + the agent, judged on escape rate — skipping is measured safeSensors (to measure) + fence
Maintenance when the UI movesQA hand-fixes broken selectors every sprint (selector rot)The loop self-heals drift — re-point the locator when the value’s still right, log itSensors + memory
Who triages a red buildA human reads the failure, guesses drift vs. real bugSensors tag the failure; the harness classifies drift vs. regressionSensors
How a failure is trusted”QA said it’s fine” — tribal, unloggedSensor-backed evidence; every heal/skip is logged, diffable, revertableMemory
The merge gateManual QA sign-offAn anti-cheat verify gate: a real red blocks; a lying green can’t passThe fence
Suite growthMore tests → slower every deploy → pressure to skip / deleteMore tests → selection keeps per-change cost flat; the suite can grow safelyGuides + agent
Failure mode to fearA rushed manual pass ships a bug; or slowness kills velocityThe selector escapes — skips a test that’d have caught the bug — so it becomes the measured metricSensors

The shape of the change: the harness takes the four things that made the classical loop a grind — release cadence, full-suite runs, gut-feel gating, hand maintenance — and inverts each one, using the four harness parts to do it.

Why this is more than “just more automation”

Fair objection: classical automation already runs tests without a human. Playwright suites run in CI today. So what’s actually new?

Two capabilities, and neither exists in a classical suite no matter how good it is:

1. It maintains itself. A classical suite rots. The app restyles, a class name changes, a card moves — and selectors that asserted nothing wrong break anyway. A human gets paged and fixes the test. The harness instead heals the drift: when the value is still correct and only the locator moved, it re-points the locator, confirms the value didn’t change, logs the repair, and moves on. When the value is wrong, it does the opposite — leaves the test red and never touches it. That single judgment — did the app move, or did it break? — is the thing a scripted suite structurally cannot make.

2. It reasons about relevance. A classical suite is all-or-nothing: run everything, or hand-pick by gut. Picking a safe subset means understanding coupling — including coupling that no import graph encodes. A template rendered by a route. A data fixture three tests depend on. The agent supplies that reasoning, and — this is the part that makes it QA and not vibes — the harness measures whether the reasoning was safe, by running the tests it would have skipped and checking that nothing slipped through.

Self-heal, and judgment-under-a-fence. Those are the two genuinely new things. Everything else is the scaffolding that makes them safe to trust.

The one principle I’d tattoo on this

Here’s the load-bearing idea of the whole approach, and it’s the one that surprised me most:

Harness engineering is not “use agents as much as possible.” It’s: agents where judgment is needed, deterministic code everywhere else — especially to check the agent.

The instinct, when you’re excited about agents, is to route everything through the LLM and scaffold it so hard it behaves. That’s backwards. An LLM is a powerful but non-deterministic, expensive, hallucination-prone component — so good harness engineering surrounds it with deterministic scaffolding and reserves it for the decisions a rule genuinely can’t make. Two consequences fall out of that:

What the harness does not replace (the honest boundary)

If I only told you the wins you shouldn’t trust the rest of this. Here’s what the harness explicitly does not do — and these aren’t gaps to close later, they’re permanent human territory:

So what happens to the QA job?

This is the part people actually want to know, and the honest answer is: the work changes shape, not the headcount. The harness automates the mechanics of QA — running, selecting, repairing — so the person moves up the stack, not out of it.

The one-line version:

From author & maintainer of test mechanicscurator of intent + auditor of judgment. You own what correct means and whether to trust the machine. The harness owns running, selecting, repairing.

Three responsibilities replace the old grind:

1. Curate the source of truth — the expectations. The harness can re-point a moved locator, but it cannot invent the expected outcome. “PnL = value − cost.” “Allocations sum to 100%.” “This console warning is known noise; that 404 is not.” Those are domain judgments, and the heal loop is forbidden from touching them — by design, so it can never quietly weaken an assertion to force a green. So the expectations are yours. And “maintain” undersells it: because the loop only guards declared expectations, the real work is noticing what should have one and doesn’t, and authoring it for every new feature. Test authoring at the intent level stays human. Only the mechanics get automated.

2. Own coverage and the escape-rate discipline. The metric that matters is the escape rate — how often the harness skipped something that would have caught a bug. In production you don’t hand-maintain a per-change answer key; you sample the full suite periodically, and its red set is the truth. So the job becomes: watch the escape rate, and when the harness lets something through, feed that escape back as a new expectation or a flagged coverage gap. That number is yours to defend.

3. Audit and govern the harness’s judgment. This is the biggest new part, and it isn’t an artifact at all — it’s managing an autonomous system. Read the logs: is it healing what it shouldn’t? Skipping what it shouldn’t? Set the fence policy: what forces a full run — core files, risky changes, low confidence? Set the escape-rate bar: how safe is safe enough before you trust it to skip unattended? Decide when the agent is trustworthy versus when to fall back to deterministic. This is QA as manager of the harness — you own outcomes, not keystrokes.

Here’s the classical QA day, re-mapped:

Classical manual-QA taskIn the harness SDLC
Write / maintain test scripts & selectorsAutomated (heal) + elevated: you author expectations, not selectors
Fix tests that broke on a UI restyleAutomated — the loop heals drift, logs it; you audit the log
Decide what to smoke-test this releaseAutomated (selection); you set the fence and escape bar it obeys
Triage a red build — drift or real bug?Automated (sensor tag + classifier); you review the disputed calls
Manual regression pass before releaseAutomated per-commit; you sample the full suite to validate coverage
Sign off the releaseShifts to the verify gate; you own policy and the exceptions it escalates
(didn’t exist)New: curate expectations, govern fence/escape policy, audit agent judgment, hunt coverage gaps

The trade the harness makes: it takes the toil — rot-fixing, full-suite grinding, gut-feel selection — and hands back leverage — intent, coverage strategy, trust calibration. The work moves from repetitive mechanics that scale with the app’s size to judgment and governance that scale with the app’s risk. That’s a more concentrated job, not a smaller one. The grind was hiding the judgment; take the grind away and the judgment is all that’s left, standing in full view.

I’ll add my own read here, because this is the part I find genuinely exciting. I like what AI is doing to the classic SDLC. As a solo QA, the thing that sells me is the bottleneck problem I described up top — this is the first shift that actually addresses it. And I don’t think it stops at QA or dev; it lands on the whole team. If we are all QA engineers now, then I think the job transforms into something closer to a curator — a guardian of the app’s and the business’s knowledge — working with the team and the business roles to organize and maintain what’s expected and what’s true, instead of hand-maintaining code and tests.

What’s next

This post was part 1 — the theory: what harness engineering is, where the term came from, and how it rewrites the classical dev → QA → UAT → prod loop and the QA role along with it. My goal here was to lay out how this new approach works and how it might reshape the usual day-to-day SDLC.

Part 2 is the experiment. I didn’t want to leave this at the level of ideas, so I built a small harness against a real app and put the claims to the test — sense, self-heal, select, one stage at a time, each mapped to the harness component it’s meant to prove. The next post is those receipts: what actually worked, where the agent earned its cost and where it didn’t, and my honest impressions and learnings from building it. If this post is the argument, that one is the evidence.

References

The sources this post is built on, and what each one contributed.

The QA reframe (the core argument)

The agent-engineering lineage

Test selection / the deterministic baseline

← All posts