How to verify
Verification gets read as a claim and then trusted as a fact. You make it once and everyone who ships on top of you believes it. So prove the change in the running system and not in the diff you happen to be proud of. A fix you only confirmed by re-reading your own code is a hope wearing a green tick. This is MANIFESTO.md turned back on verification itself, which is the dynamic confirmation that the change did what the issue asked and didn't break something else. Writing a test asserted the rule. This phase actually exercises the real behaviour. The objective hasn't changed, but for this phase it reads: prove the change resolves the issue and breaks nothing in a running system, subject to bounding the blast radius of the irreversible and the production-facing parts of what you are about to release. When two of the moves below pull against each other, the answer is never some slogan. It comes down to who controls the input and how wide the blast radius is. None of it is free.
Reproduce the original report, then prove it gone
The bug's reproduction is the acceptance check: it must fail before the fix and pass after, or "fixed it" is trust-me.
A fix you assert without a before-and-after is a claim about a system you never watched. The test that re-runs the rule (tenet XXIV) only means anything once you've actually seen it go red on the broken build and green on the fixed one. So reproduce the report exactly as it was filed, against the code from before your change, and confirm it fails for the reason the issue gives and not some neighbouring symptom. Then apply the fix and watch that same reproduction pass. A green check that was never red proves nothing about the bug. All it proves is that the check doesn't touch it.
- A crash: the exact payload from the report drops the process on the old build and returns cleanly on the new, not a check you wrote to match the patch.
- A data bug: the corrupting input quarantined now, the same input you confirmed corrupted the frame before, rather than a fresh fixture that would have passed regardless.
- A regression: the reproduction run against the parent commit first to prove it fails there, unlike a check added beside the fix that has never seen the broken state.
Tension: This pulls against the fast confirmation. Reproducing some bugs is expensive (a specific tenant's data, a load condition, a timing window), and you will want to skip straight to "the patch looks right". Pay the reproduction cost where the bug actually lived; for the genuinely unreproducible, name what you could not reproduce rather than pretending the patch alone is proof.
Ask yourself: Did I watch this reproduction fail on the unfixed code and pass on the fixed code, or am I trusting that a check I wrote to match my own diff means the bug is gone?
Verify against the contract and the acceptance criteria, not the diff
Check what the issue asked and what the plan promised, and re-check the irreversible decision, not merely that the code you wrote runs.
The diff tells you what you changed. It can't tell you whether what you changed is what anyone actually wanted. So verify against the contract the boundary promised (tenet XV) and the acceptance criteria the plan wrote down as done. Walk each criterion and confirm the deployed build satisfies it, and re-exercise the irreversible decision by driving the decision function with the cases that decide it (tenet XI), not just the one you happened to fix. Confirming the code runs only confirms you wrote some code. Confirming it meets the criteria confirms you wrote the right code.
- A feature: every acceptance criterion exercised on staging and ticked off, not a demo of the one happy flow you built last.
- A decision seam:
decideCharge(cart)driven with the cases that flip its outcome and the result inspected, rather than confirming the wrapper merely executed without throwing. - A contract change: the response shape checked against what callers were promised, unlike a diff that compiles while silently dropping a field a downstream team depends on.
Tension: This is paid for in time against shipping. Walking every criterion and decision case is slower than eyeballing the diff. Spend the full walk on the load-bearing criteria and the irreversible decision; let the trivially-correct change carry a lighter check rather than ceremony for a one-line label fix.
Ask yourself: Have I confirmed the running system meets what the issue asked and the plan promised, or only that the code I wrote executes without error?
Throw the worst input at the boundary, for real
Drive the over-cap body, the malformed value, the hostile payload through the running boundary, and confirm it rejects and bounds, not merely that it accepts the happy example.
Past the boundary everything trusts the parsed type, so verification has to use that boundary the way an attacker will (tenets III, IV) rather than the way the demo does. Send the oversized body, the array length picked to exhaust the heap, the field that lies about identity, the row whose null-rate breaks the schema, and then watch the real parser reject it and bound the cost before it allocates anything. A boundary you only confirmed on the example from the issue is a boundary confirmed on the one input that was never going to cause trouble in the first place.
- A request boundary: the over-cap body rejected before allocation and identity re-derived, confirmed against the live handler, not a payload
userIdit trusted in the happy run. - A data boundary: the bad-null-rate row quarantined in the running pipeline, rather than
NaN-poisoning a frame three weeks downstream where no one will trace it back. - A hostile payload: the malformed shape driven through the actual parser and observed to fail closed, unlike a verification that only ever fed it the valid example.
Tension: This trades against the internal trust boundary (tenet IV). Don't go hunting for hostile inputs to drive through every in-process call; that is effort spent where there is no threat. Concentrate the adversarial verification at the real crossings, the process edge and the deserialisation point, where the input is genuinely controlled by someone you don't trust.
Ask yourself: Have I driven the worst input the other side could actually send through the running boundary and watched it reject and bound, or only confirmed it accepts the example that was always going to pass?
Exercise the failure and degraded paths, not just the happy one
Drive the fallback, the error state, and the breaker open at runtime; the degraded tier you never exercised is a second bug waiting for the incident.
The happy path never needed verifying. It's the failure handling that's the real problem, the code that runs maybe once a year, under load, when nobody's watching. Verification that only ever saw the dependency healthy hasn't seen the part that decides whether an incident is a lost feature or a lost service. So kill the dependency for real, force the timeout, trip the breaker, and confirm the system degrades the way the plan said it would (tenet XIX), surfacing the error where you can see it instead of swallowing it (tenet XIII). A fallback you exercise for the first time during the outage is a fallback you're discovering, not one you verified.
- A dependency outage: the recommender killed and the page confirmed to render without it, not a verification that only ever ran with the dependency up.
- An error surface: the error state driven and observed to surface visibly and be recorded, rather than a swallowed exception that turns into a silent 200 nobody questions.
- A breaker: the breaker tripped open on the deployed build and the cached value served, unlike a confirmation that only ever walked the path where everything answered.
- A blocked responsive path: with the slow dependency stalled, the handler returns a pending state and stays responsive (tenet V), not freezing the one thread a user is watching.
Tension: This is paid for in effort (XIX). You cannot drive every failure permutation in verification, and trying drowns the release. Exercise the degraded tiers you actually built and will lean on in the incident; for the failure modes the design chose not to handle, the manifesto's answer is to not have them (XXI), not to drive them into submission here.
Ask yourself: When the dependency is down or the input is bad, have I driven the failure and watched the fallback run in the running system, or have I only ever verified it healthy?
Confirm replay-safety and teardown actually hold
Run it twice and interleave it, then kill it mid-flight, and assert the world mutated once, nothing leaked, and a complete output or none.
Idempotency and race-freedom and clean teardown are all claims about what happens when you repeat something, run it at the same time, or cut it off partway through, and the only honest way to check is to actually go and cause all three against the live handler (X, IX, VIII, XII). So fire the operation twice with the same key and check that it mutated once and gave you back the original result. Drive two actors into the window and check that one of them wins and it wins cleanly. Then signal the process while it is still working and check that it drained inside its deadline and left behind either a complete output or nothing at all, with no listener still firing off somewhere and no handle still being held. Call a system "idempotent" or "race-safe" and run it once, in sequence, all the way to the end, and you have left its three hardest claims sitting there unchecked.
- A retried operation: the same idempotency key fired twice on staging, one charge confirmed and the original result returned, not a single clean run trusted to stand in for the replay.
- A shared-state race: two clients driven into the window on the last seat, one confirmed to win and the other rejected cleanly, rather than a sequential run that never met itself.
- An interrupted run: the process signalled mid-write and the output confirmed complete or absent, unlike a happy-path finish that never saw the truncated file masquerading as done.
Tension: This cuts the other way against single-run reality (IX, X). In code that really is single-actor and single-run there is no window and there is no replay, and manufacturing concurrency to verify it is theatre. Spend the replay and the interleave on the operations that touch money or state or the outside world, and put the teardown check where a leak or a half-write would actually get out without anyone noticing.
Ask yourself: Have I run this twice, interleaved it, and killed it mid-flight against the running system, or am I trusting that it is safe under repetition, concurrency, and interruption because nothing went wrong the once?
Verify at the scale the caller can reach
Exercise the cost-bearing path at production-like size and assert a bound, a query count or a latency budget, not on friendly dev data.
Performance is a claim about how something behaves at size, and a verification run on dev data has none of that size in it (XVII). The O(n²) that comes back instantly on ten rows falls apart at ten million, and the N+1 query stays invisible right up until the table grows, so checking that the answer is correct on toy data tells you nothing about whether you can afford it in production. Drive the cost-bearing path at a scale the caller could really reach. Feed the endpoint the array length the contract actually allows. Run the query against a table the size production is going to hit, and assert a bound and not just a correct result. What you want is to meet the latency cliff during verification instead of meeting it later on the pager.
- An N+1 path: the query count confirmed flat as the row count grows, against a production-sized table, not a ten-row fixture that proves only correctness.
- A caller-controlled size: the parser or sort driven with the largest input the contract permits and confirmed within budget, unlike a friendly fixture that says nothing about the 2 GB body the boundary accepts.
- A pipeline: the job run on a production-scale sample and its runtime and memory envelope confirmed, rather than learning the per-row cost is hours only after launch.
Tension: This pulls against the cheap, repeatable verification. A full-scale run is slow and awkward and it has no business running on every push, so keep it as a deliberate tier that you own and trigger before the change goes wide. Where you can, verify the cheap proxy instead - the query count, or the algorithmic bound - rather than a wall-clock number that swings around depending on whatever else the runner happens to be doing.
Ask yourself: Does any path here cost more as the caller's input grows, and have I confirmed that growth against a bound at production-like size, or only ever exercised it on friendly dev data?
Verify in a prod-like environment, watching the signals you shipped
Confirm the change on staging or canary with real config and observability on; "works on my machine" is not verified, and the seams you built are what let you drive it.
A change verified only on your laptop has been verified against config and data and dependencies that production does not share (XVIII, II). So go and confirm it where it is actually going to run, on staging or behind a canary, with the real configuration and the observability you shipped switched on, and read the signals while you drive it. The metric moves. The log line shows up. The trace comes through on the path you were expecting. The seams you built for testability are the same thing that lets you reach in and drive the behaviour here, and the instrumentation is what lets you see whether it held. "Works on my machine" is a statement about one machine, and it is not the machine your users are sitting in front of.
- A release: the change confirmed on a canary with production config and the dashboards watched, not a local run against a dev database and a mocked dependency.
- An observability check: the metric and the trace you shipped confirmed to move as the change is exercised, rather than assuming the instrumentation works because the code that emits it compiled.
- A config-sensitive change: the behaviour driven through its override against the real environment's settings, unlike a laptop run where a default silently stood in for the production value.
Tension: This pulls against the fast local loop. Standing up a prod-like environment and sitting there watching it is a lot slower than just running the thing locally, and not every change has earned a canary. Spend the prod-like verification on the change whose blast radius reaches users. For a change that is reversible and low-reach, a lighter environment is the proportionate thing rather than ceremony.
Ask yourself: Have I confirmed this in an environment that shares production's config and dependencies, watching the signals I shipped, or am I extrapolating from the one machine that is not in production?
Make the verification reproducible, and keep the regression forever
Pin inputs, seed, and environment so the pass regenerates, and turn the escaped bug's reproduction into a permanent check, not a one-off manual look.
A pass you cannot regenerate is just an anecdote, and the manual confirmation you did the once protects nobody tomorrow (XXIV). So pin the inputs, write down the seed, and fix the environment so the verification regenerates the same result on another machine and again in six months' time, measuring durations on a monotonic clock and never trusting wall-clock ordering across machines (XXIII). Then promote the reproduction. The bug that got out turns into a permanent regression check that re-runs the rule for call sites nobody has written yet, instead of being a one-off look you did by hand and then threw away. A verification that lives only in your terminal history is one the next change will quietly undo.
- A reproducible pass: the inputs, seed, and environment pinned so the verification regenerates exactly, unlike "it passed when I ran it", which is not a guarantee anyone else can reach.
- A permanent regression: the escaped bug's reproduction kept forever as an automated check, rather than a manual confirmation that protected this release and nothing after it.
- A data verification: the dataset versioned and the seed recorded with the result, not a metric you cannot regenerate because the data drifted beneath you.
Tension: This is itself state (XXIV). Pinned environments drift, snapshots cost you storage, and kept reproductions pile up. Own that infrastructure and expire it the way you expire any other state (XX). Keep the reproductions that make a real escaped bug actionable forever, but do not turn every transitive detail of a verification run into a museum.
Ask yourself: Could someone else regenerate this exact pass from pinned inputs and a recorded seed, and did the bug that escaped leave behind a permanent check, or only a manual look I will not do again?
The through-line
Every move here is the manifesto's one move turned on the running system: push the proof of correctness out of the author's confidence in their own diff and into the behaviour of the running system. You reproduce the bug and watch it fail and then pass, you walk the contract and the criteria, you drive the worst input through, you exercise the failure path, you force the replay and the teardown, you meet the scale, you watch the prod-like signals, and you make the verification regenerate itself. A green tick on its own proves nothing. What you want is the dynamic proof that the issue really is resolved, that the hostile input really is bounded, and that nothing else broke, all of it seen in a system running the way production does rather than asserted from code you happened to be sure of.
Verify for the on-call engineer who will trust this release at 2am with a pager going off, knowing less than you know now. Prove the bug gone where it lived, drive the failure path before the incident does, and never let a green tick carry a claim a running system could have confirmed.