Skip to main content

Command Palette

Search for a command to run...

Tests Are the Verification Layer: Proving Agent Generated Changes

The coding agent reports that the feature is complete. The project compiles. Four tests pass. The fifth was deleted because it represented legacy behavior. This is one way to achieve a green build.

Updated
•5 min read•View as Markdown
Tests Are the Verification Layer: Proving Agent Generated Changes
A
AI Architect. I design the boring control plane plumbing that keeps your impressive demos from quietly setting themselves on fire in production.

🗓️ Last updated: September 2026

The coding agent reports that the feature is complete. The project compiles. Four tests pass. The fifth test was deleted because it represented "legacy behavior." This is one way to achieve a green build, in the same sense that removing the battery improves a smoke alarm's noise profile.

Generated code does not need a new definition of correctness. It needs a stronger and more explicit path to the definition the system already has.

Verification is not model evaluation

An LLM evaluation asks whether a model or agent behaves acceptably across a set of tasks. Software verification asks whether this particular change preserves the required behavior of this particular system. Series 3 covered the first problem. This article is about the second.

The distinction prevents a common mistake. A strong benchmark score does not make an individual patch correct. A weak benchmark score does not make a passing, reviewed patch incorrect. The unit of evidence is the change and the repository around it.

Build a verification ladder

Every task should climb a known sequence of checks. The exact tools vary, but the layers are stable.

  1. Formatting and generated file checks

  2. Compilation and static analysis

  3. Focused unit tests

  4. Contract and integration tests

  5. End to end behavior where the risk requires it

  6. Security, compatibility, and performance checks for affected surfaces

Run cheap, local checks first so obvious defects return quickly. Run broad checks before merge. The task contract should identify which layers are required. The agent may discover that additional checks are prudent, but it may not decide that required checks feel unnecessary today.

Protect the oracle

A test is useful only if its expected result comes from an independent requirement. When an agent changes production code and rewrites the failing assertion to match, the build may become green without the software becoming right.

Treat changes to existing tests as a separate review concern. Require an explanation that ties the changed expectation to a contract, requirement, approved behavior change, or corrected defect in the test. A test update is not suspicious by default. An unexplained test update is.

For defects, prefer a regression test that fails before the implementation change and passes after it. For new behavior, connect acceptance criteria to observable tests. For refactoring, require existing behavior to remain stable and use characterization tests where coverage is weak.

Verify more than the happy path

Coding agents are very good at satisfying the example placed directly in front of them. Production defects often live one input beyond that example. Include boundary values, invalid state, cancellation, retries, concurrency, authorization, serialization, and partial failure according to the domain.

Use property based or generative tests when invariants matter more than individual examples. Use contract tests for service boundaries. Use snapshot tests carefully; a large snapshot approved without inspection is simply a text file that has learned to say yes.

Make hidden checks legitimate

Some acceptance checks should remain outside the agent's immediate edit surface. This prevents the implementation and its only judge from being produced by the same reasoning process. Hidden checks are common in benchmarks, but the production equivalent is broader: contract suites owned by another component, policy tests, compatibility checks, or independently maintained acceptance tests.

Hidden does not mean mysterious. Engineers should know the categories of behavior being protected. Surprise requirements are poor governance. Independent evidence is good verification.

Record the evidence

The pull request should state exactly which commands ran, their results, and which checks could not run. Continuous integration remains the authoritative execution environment. Local success is useful feedback, not a substitute for clean execution on the target platform.

Store test reports and relevant artifacts. For a UI change, retain screenshots or visual comparisons where appropriate. For an API change, retain contract results. For a migration, retain forward and rollback evidence. "Tests passed" is less useful than it sounds when nobody can identify the tests.

Failure modes

The first failure is compile driven development. Compilation proves that the compiler accepted the program. The compiler has never claimed to understand the business.

The second is test laundering. The agent modifies the test until the implementation passes, with no external evidence that behavior should change.

The third is flaky acceptance. Repeated reruns eventually create a green check. Fix or quarantine the flaky test under an explicit policy; do not convert probability into proof.

The fourth is broad change with narrow verification. A shared package changes, but only the local unit suite runs. Verification scope should follow impact, not convenience.

The architect's checklist

  1. Define a standard verification ladder for the repository.

  2. Tie required checks to the task's risk and affected surfaces.

  3. Review changed expectations separately from implementation changes.

  4. Require regression evidence for defects and contract evidence for interfaces.

  5. Run authoritative checks in a clean continuous integration environment.

  6. Preserve named commands, reports, and unresolved failures in the handoff.

The agent can write the patch and some of its tests. It cannot be the sole author of reality. That position remains occupied by the system's contracts, users, and occasionally production at three in the morning.

Sources

  1. SWE-bench repository and benchmark documentation

  2. Anthropic on evaluating AI agents

B

Context windows are not free memory. Stuffing every log into the prompt slows the loop and hides the signal. I summarize tool output hard before the next turn.

A
Alen Joy16d ago

Agreed, dumping raw logs into the prompt mostly buries the one line that matters. The catch from a verification angle is that a summary can hide exactly the thing you needed to see. "Tests passed" can quietly mean one was skipped or a warning got dropped along the way.

What I'd do is keep two copies. A tight summary for the agent's next turn, and the full output stored as an artifact that CI and the reviewer can check. I'd also make the summariser keep failures, skips and warnings word for word, and only compress the passing noise.

P

Code reviews consume more hours than writing the actual code. Engineering time shifts entirely toward verification now, and the bottleneck slows down every single release.

A
Alen Joy16d ago

Writing code was never really the expensive part. Deciding what it should do and checking that it does was always the hard bit. Agents just made that impossible to ignore.

So review time has to be protected. Anything a machine can check should be checked before a person opens the PR. Changes stay small. Reviewers spend their attention on changed test expectations and on whether the intent is right, not on rereading every line.

If the agents still produce more than the team can get through, slow the agents down. A pile of unreviewed PRs looks like progress but isn't.

Engineering With Coding Agents

Part 5 of 6

Four series of The Pragmatic Stack have explored the architecture and operation of LLM-powered systems: the discipline inside the agent, the systems around it, the operational practices that keep those systems running in production, and the .NET runtime used to implement them. All four series focused on systems that contain agents or agents that serve users. Series 5 examines a different kind of agent: one that opens your repository, understands your codebase, makes changes, and commits code. Coding agents are more than a new developer experience. They are a new actor in the software delivery system. Most delivery systems, including repositories, task backlogs, branching strategies, test suites, review processes, and deployment pipelines, were designed around human authors. Introducing automated authors changes the assumptions behind those systems. Some of those assumptions will need to evolve. Engineering With Coding Agents is a six article series focused on what needs to change and how engineering teams can adapt. This is the fifth series in The Pragmatic Stack. Series 1, Architecting Agents, covered the discipline inside an agent. Series 2, System Design, Reimagined, covered the systems around the agent. Series 3, Shipping AI Systems, covered how those systems are operated in production. Series 4, AI for the .NET Architect, covered what all of the above looks like in .NET. Series 5, Engineering With Coding Agents, covers what your software delivery system needs to handle agents as authors. What You Will Learn By the end of the series, you will have: A framework for making any repository legible to a coding agent without creating an extensive instruction manual. A task contract format that prevents vague intent from becoming production code faster than the team can identify and correct it. An isolation model for parallel coding agent work based on one branch, one worktree, and one environment per task. A six layer verification ladder that distinguishes software correctness from LLM benchmark performance. A code review approach designed for generated diffs at scale, with an emphasis on risk, provenance, and test evidence. A seven stage delivery loop that produces accepted, verified, and reviewable changes rather than raw generated output. The Articles 1. The Repository Is the Prompt: Preparing a Codebase for Coding Agents 2. The Ticket Is the Contract: Specifying Work for Coding Agents 3. One Agent, One Worktree: Isolation and Concurrency for Coding Agents 4. Tests Are the Verification Layer: Proving Agent Generated Changes 5. Reviewing Code Nobody Typed: Human Judgment in an Agentic Workflow 6. The Pull Request Is the Product: A Delivery System for Coding Agents Read the articles in order if you are building an agent ready delivery system from the ground up. If your organization has already begun adopting coding agents, start with the article that addresses the constraint you are currently encountering. The agent writes the code. The delivery system determines what reaches production.

Up next

One Agent, One Worktree: Isolation and Concurrency for Coding Agents

Three coding agents start from the same checkout and finish in the filesystem they happen to inherit. Parallel coding is not primarily a coordination problem. It is first an isolation problem.