Section 6Verify — review without reading every line

Agents produce more code than you can read. So don't review by reading — review by watching and by evidence. This is the single technique that makes the whole workflow scale.

Section 5 set this up deliberately. The blackbox behaviour tests you insisted on there — launch the real app, press the button, see the status change — aren't just the most refactor-proof kind of test. They're also the only kind of test a person without a programming background can watch. A unit test passing is a line of green text that means nothing to anyone outside the code; a behaviour test passing is the salon's booking page actually refusing to double-book a chair, on screen, in front of you. Choose behaviour tests in Build and you have already manufactured your review evidence for Verify — the two sections are one decision seen from both ends.

Hold on to Section 1's rule as you read: evidence over claims, always. Everything in this chapter is a kind of evidence — a recording of the feature working, a wall of green checks, a second agent's independent read of the changes, a regression suite that hasn't gone red. Your job in Verify isn't to redo the agent's work with your own eyes; it's to decide, the way a manager or an editor does, whether the evidence in front of you actually supports the claim "this is done." Most of the time that takes minutes. The skill is knowing which minutes.

For newcomers

What "code review" normally means. On a traditional team, every change is read line by line by a colleague before it's merged — a second pair of eyes catching bugs, bad names, and missed cases. That works because a human writes maybe a few hundred lines a day, a volume another human can genuinely read. An agent can produce that before your coffee cools, and several agents in parallel (Section 11) produce it many times over. The old ritual doesn't scale to that volume — but the ritual's purpose, catching problems before they're merged, absolutely still applies. This chapter keeps the purpose and replaces the mechanics.

The flipped testing pyramid

Classic advice: mostly fast unit tests, few slow end-to-end tests. Pocock flips it — a heavy base of blackbox behaviour tests. Those are historically expensive for humans to debug, but an agent has infinite patience: it reruns, instruments, and resolves failures at no cost to you.

For newcomers

The testing pyramid. A classic diagram of how teams were told to spend their testing effort. At the wide base: unit tests — thousands of tiny checks of individual functions, kept plentiful because they run in milliseconds and point at failures precisely. At the narrow top: end-to-end tests — a scarce handful that drive the whole running app, kept scarce because each one is slow and, when it failed, a human had to spend an afternoon working out which of a hundred moving parts was to blame. The shape was never a law of nature; it was a budget, drawn around what human debugging time used to cost.

That's worth slowing down for, because the pyramid was an economic argument — and the economics just changed. The expensive step was never running an end-to-end test; computers do that happily. It was a human diagnosing one when it failed. Hand that job to an agent and the cost collapses: it reruns the failing scenario twenty times, adds logging, narrows down the cause, and reports back, without consuming an hour of your attention. Meanwhile the end-to-end test keeps the advantage Section 5 already banked on: it checks what the user actually experiences, and it survives the constant refactoring agents do. When the costly option becomes cheap and was always the more valuable one, you buy more of it. Hence the flip. One honest caveat: the flip buys realism and pays for it in runtime and flake management — the maintenance rules in the regression section below are the bill.

Demo reels — watch the feature work

Configure the behaviour tests to record as they run — a screen recording for a web app, a terminal "cinema cast" for a CLI. Each test drives a real user scenario end to end. When the work is done, the agent opens a pull request (a "PR" — a proposal to merge its branch, where teammates and automated checks review the change), confirms all checks are green, and embeds the recording. Your review becomes watching a short clip to confirm the behaviour with your own eyes.

The tooling for this is standard, not exotic. Playwright — the same tool already driving the behaviour tests in the cards below — records video of its own test runs with a one-line setting (video: 'on', or 'retain-on-failure' to keep clips only when something breaks). For command-line tools, asciinema records the terminal session itself as a tiny text file you can replay or embed. Either way, the recording is a by-product of tests that were running anyway: nobody performs a demo, nobody edits a video. The reel is simply what the test suite saw.

Watch it the way the salon owner would use the app, with the ticket's "done" sentence from Section 4 open beside it: block a holiday week, watch a customer's booking attempt get refused politely, watch the confirmation arrive. You're not checking code — you're checking that the promise in the ticket is the behaviour on the screen. That's a judgment you're fully qualified to make with no programming background at all, which is precisely the point: the flipped pyramid moved the truth of the system somewhere a human can see it.

Watch against the ticket, not against "looks fine"

A reel can look busy and convincing while quietly showing the wrong thing — an eager agent demos the path that works, not necessarily the path you asked about. Before pressing play, re-read the ticket's acceptance sentence, then check the clip shows that, including the unhappy case ("a second customer trying the same slot is refused"). If the reel doesn't show the case the ticket named, the verdict is "show me", not "probably fine".

Match scrutiny to risk — where your minutes go

Match scrutiny to risk

Not every change deserves equal review. Triage by blast radius (Addy Osmani's risk-tiered review): a copy tweak gets a glance; anything touching money, auth, data deletion, or migrations gets a real read and the demo. Spend your attention where a mistake would hurt.

In the salon app the tiers are easy to name in advance. Bottom tier: wording changes, colours, layout tweaks — the demo reel alone is plenty. Middle tier: new behaviour like the holiday-blocking feature — watch the reel and skim the second agent's review, coming next. Top tier: anything touching payments, refunds, cancellation fees, login, or deleting customer data — here you watch the reel, read the review, and have the agent walk you through the actual changes line by line ("explain this diff to me as if I'm the salon owner"). The point isn't that top-tier changes are rare; it's that they're identifiable before the work starts, so your scarce close attention lands exactly where a mistake would cost real money or trust.

A second agent reads what you don't

Watching covers behaviour, but a reel can't show you everything. It won't reveal a hard-coded password, a wasteful database query, or a corner quietly cut inside the code. For that layer you still want a reader — just not you. The same principle as Section 5's "don't let the AI mark its own homework" applies to review: an agent that didn't write the code, starting with fresh context, has no memory of the shortcuts taken and no investment in the result looking good. It reads the change the way a sceptical colleague would — except it reads all of it, every time, and is exactly as thorough on the last file as on the first.

You can also run /review to spawn adversarial reviewer agents that check the diff (the exact lines added and removed) against the spec and your standards — a second opinion before you even watch the reel. Claude Code's GitHub Actions integration can run this same review automatically on every pull request with no manual trigger, and headless mode (claude -p, with --output-format json) is what lets any of this run unattended inside CI at all. Anthropic's own dedicated code-review agents, run internally on Anthropic's own pull requests, raised the share of PRs getting a substantive review comment from 16% to 54%, with under 1% of findings marked wrong by the engineers who checked them — real evidence that agent-driven review, built properly, isn't just theoretically thorough.

For newcomers

"All checks are green." On a pull request page, every automated check — the test suite, the type checker, the linter, the reviewer agent — reports its verdict as a row with a tick or a cross. "Green" means every row passed. It's Section 1's evidence-over-claims rule made visible: the agent writing "done!" changes nothing on that page; only checks actually passing turn it green. CI is the machinery that runs those rows automatically on every proposed change, whether or not anyone remembered to ask.

Put together, the pull request page is the one screen where all of this evidence lands. Here's a compact mock of what you'll see there, part by part:

Block out holiday weeks on the staff calendar  #214    ← title: the ticket's promise
───────────────────────────────────────────────────────
✓ Behaviour tests (Playwright)     passed · 4m 12s     ← the row of checks —
✓ Type-check (strict)              passed                all green before you
✓ Linter                           passed                spend a single minute
✓ Reviewer agent                   no blocking findings
───────────────────────────────────────────────────────
▶ demo-reel.webm · 0:48                                 ← the embedded demo reel,
  recorded by the behaviour tests themselves              the promise on screen
───────────────────────────────────────────────────────
src/booking/availability.ts · line 87                   ← a review comment anchored
  reviewer agent: "This availability check runs           to one line — the second
  after the write; two simultaneous requests              agent's fresh-eyes read
  could both pass it. Unique constraint instead?"
  you: "Agree — fix it and re-run the suite."

Read it top to bottom in that order — title against the ticket, checks green, reel watched, review skimmed — and you've done a full review without opening the diff once.

When agents keep breaking existing functionality

Anthropic's team building a C compiler with parallel Claude instances hit exactly this: agents adding features while quietly breaking ones that already worked. Their fix was a near-perfect automated task verifier gating every change — "the task verifier needs to be nearly perfect, otherwise Claude will solve the wrong problem." The lesson generalises: at scale, the automated gate you build is your regression protection, not a supplement to it.

Regression testing — proving new work didn't break old work

Every test that turned green in Section 5 stays in the suite forever, and that permanence is the point: from now on, every future change has to keep every old promise. When the agent builds gift vouchers in March, the February tests for holiday-blocking still run — and if the voucher work accidentally breaks holiday-blocking, a test you'd forgotten existed goes red before the mistake reaches a customer. Breaking something that used to work is called a regression, and it's the characteristic failure of fast-moving agents: they change a lot of code quickly, and their blind spot is everything they weren't currently thinking about. The C-compiler story above is this failure at scale, and its lesson applies at yours: the automated gate is the regression protection.

A growing test suite is a liability the moment it's slow enough that people skip it or flaky enough that a red result gets ignored. Treat the suite as something to actively maintain, not something you write once during Build and forget.

For newcomers

"Flaky." A flaky test passes on one run and fails on the next without anyone changing anything — usually timing, a network hiccup, or two tests interfering with each other. One flaky test looks harmless; its real damage is to trust. Once people (and agents) learn that red sometimes means nothing, they start treating every red as probably-noise — and the safety net Section 5 built quietly stops being one. That's why the rule above pulls a flaky test out of the merge gate immediately rather than tolerating it.

Test tooling, by what it actually catches

No single test type catches everything. Pick tools by what they're for:

Unit & integration

Fast checks of one function or module boundary — Vitest or Jest for JavaScript/TypeScript, the equivalent elsewhere. Cheap, but proves the least about real behaviour.

Behaviour / end-to-end

Playwright drives the real app the way a user would — the base of the flipped pyramid above, and what your demo reels record.

Visual regression

Catches a layout that silently broke with no assertion failing. Playwright's own screenshot comparison covers small teams; Chromatic or Percy add AI-assisted diffing for component-heavy UIs.

Contract testing

Once a feature splits across services (a booking API, a separate payments service), a tool like Pact catches a breaking API change between them in CI, before it reaches staging.

Load & performance

k6, Gatling or Artillery script real traffic patterns against staging, so "fast for one user" gets checked against the concurrency you actually expect — Section 7's scalability gate. The full treatment — the test types (load, stress, soak) and their limits — lives in Section 8.

Accessibility

axe-core and Pa11y in CI catch roughly a third to half of accessibility issues automatically — a floor under the manual pass, not a replacement for it.

Don't try to install all six on day one. The salon app starts with the first two rows — unit tests for the fiddly logic, behaviour tests as the base of the pyramid — plus the accessibility check, because retrofitting that later is miserable. The other rows earn their place when the product creates the failure they catch: contract testing when the app splits into separate services, load testing before the first marketing push, visual regression once the interface is polished enough that a broken layout costs trust. And what's worth remembering isn't the tool names — the agent will happily set any of them up when asked — but the failure modes: each card names a way software breaks that none of the other rows would notice.

Verified is not the same as ready

Everything in this chapter answers one question: does the change do what the ticket said, without breaking what already worked? That's necessary — and nowhere near sufficient. A feature can pass every behaviour test, look perfect in its reel, and survive two agent reviews, and still fall over with ten thousand users, still be unusable with a keyboard, still greet a network failure with a raw error dump. Those aren't verification failures; they're things nobody asked the tests to check. Section 7 closes that gap with a definition of done — a checklist of quality gates, enforced in CI, that a change must clear before "verified" is allowed to mean "ready."

Quick check: an agent changes 2,000 lines. How do you review it?

Watch the recorded demo of the behaviour tests and read the evidence (green checks, coverage). Read code closely only for the high-risk parts — auth, payments, data loss, migrations. Reading all 2,000 lines is neither possible nor the point.

The longer answer is the chapter. Build's blackbox tests double as review evidence — the flipped pyramid puts the truth of the system where you can watch it. Demo reels, recorded by the tests themselves, show the ticket's promise happening on screen; a second agent with fresh eyes reads the full change so you don't have to; risk tiers decide where your own minutes go. The suite you keep becomes regression protection — actively maintained, fast enough to run, never flaky-and-ignored — and each test type in the toolbox catches a failure the others can't see. What verification can't tell you is whether the feature is ready for production — that's Section 7.