Skip to main content
Beginner4 min read

Incremental Verification

Verify each unit of work as it is produced, not the whole batch at the end, so errors surface while they are cheap to fix and trivially attributable.

Signals

  • Test failures arrive in clusters spanning multiple modules at once
  • You spend more time finding which change broke something than fixing it
  • The agent reports "done" and verification is a separate phase you dread
verificationincrementalearly detectionerror attributionfeedback loop

Relationship Map

3.2Checkpoint …1.2Safety Net5.4Diff Review5.1Incremental V…

Problem

The finishes a 9-file refactor and reports success. You run the test suite. Forty tests fail. The failures span four different modules, and the stack traces point at code that looks correct in isolation.

Now you have a debugging problem that is strictly harder than the original task. You don't know which of the agent's edits introduced which failure. The first bad change may have caused the agent to "fix" downstream code in ways that made sense given the bug but are wrong without it. The errors are entangled because they were produced together and never checked apart.

This is the cost of batch verification: you defer all checking to the end, so every error arrives at once, stripped of the context that would tell you where it came from. An error caught one edit after it happened is a one-line fix. The same error caught forty edits later is an investigation.

Agents make this worse than human developers do. A human refactoring 9 files runs the tests out of habit somewhere in the middle. An agent optimizes for completing the request and will run for fifteen minutes without verifying anything unless the loop forces it to.

Solution

Verify every unit of work the moment it is complete, before the next unit begins. The unit is whatever change you can check in isolation — one function, one endpoint, one file.

The discipline is a single rule:

No new work until the last work is verified.

Everything else is mechanics. The mechanics that matter:

Make the agent verify its own work in the loop. State the check and the stop condition in your convention file so it happens without prompting:

After every file you change, before moving to the next:
1. Run: npm run typecheck
2. Run the tests for that file: npm test -- <file>
3. If either fails, fix it before continuing. Do not start the
   next file with a failing check outstanding.
Report the check result for each file as you go.

Scope the check to the unit, not the world. Verifying one function should take seconds, not a full CI run. A check that is slow gets skipped — by the agent and by you.

Unit changedVerification that fits the unit
One pure functionThe unit tests for that function
One API endpointA request against it + its integration test
One type/interfacetsc --noEmit on the package
One componentRender it; run its test; eyeball the story

Keep each unit attributable. The reason incremental verification works is not just early detection — it is attribution. When the check fails right after one change, the change that broke it is known with certainty. You spend the fix budget on fixing, not on bisecting.

When a unit fails, stop the line. A failed check is not a note to address later. It is a halt condition. Compounding a failure with more changes is how forty entangled failures happen.

Verification Is Not Review

Incremental verification answers "does this unit work?" — typecheck, tests, run it. It does not answer "is this the right design?" That is Diff Review and Adversarial Review. Run the cheap behavioral check continuously; do the expensive judgment review once, on the assembled whole. Confusing the two means either slow loops or unreviewed designs.

Signals

  • Test failures arrive in clusters spanning multiple modules at once
  • You spend more time finding which change broke something than fixing it
  • The agent reports "done" and verification is a separate phase you dread
  • Reverting one bad change cascades into reverting work that depended on it
  • You cannot answer "which edit caused this?" without git bisect

Consequences

Benefits:

  • Errors are attributable — the failing check names the change that caused it
  • Fixes are cheap because they happen one edit deep, not forty
  • Failures stay independent instead of entangling into a debugging session
  • The agent gets corrective signal while the relevant context is still loaded
  • Every verified unit is a known-good point you can safely build on

Costs:

  • Slower per-step throughput — verification has a fixed cost paid every unit
  • Requires a fast check; a slow suite makes the discipline collapse
  • The agent needs explicit instruction and a hard stop condition, or it batches anyway
  • Over-fine units (verifying every line) turn the loop into manual coding with extra latency