Back to blog

You didn't touch it. It broke anyway.

The bottleneck in software delivery has shifted from writing code to verifying what changed.

Somewhere in your product there is a behavior that worked yesterday and does not today. Nobody has reported it, because nobody has stumbled across it.

It probably is not in the feature you just shipped. That code got reviews, attention, discussion and testing. It is two steps away from an unrelated change, in a part of the system nobody thought could matter.

Those are the bugs that cost the most. A feature arriving a week late delays value. Breaking a workflow an existing customer already depends on erodes trust immediately, interrupts revenue, and starts an investigation that usually costs more than the fix. Late is recoverable. Broken isn’t. Stop guessing.

And the odds of shipping one are getting worse.

Software has a new bottleneck

AI-assisted development did not create regressions. It changed the economics around them.

Writing code used to be the slow part of delivery. For many teams it is no longer the constraint. Verification is.

Engineering organisations are shipping more changes, across more repositories, at a higher cadence than ever. The volume of change now exceeds any one person’s ability to understand every consequence of every release.

You can already see the symptoms.

  • Releases stay open another day, just to be safe.
  • QA reruns the same suite it ran last time, because nobody can say which part of it matters.
  • Somebody asks, in a channel, what else could this have touched.
  • Teams deliberately restrict AI to isolated work, because verifying a broad change costs more than generating it did.

None of that creates customer value. All of it is a payment for uncertainty.

We have been asking the wrong question

Most release processes are optimised around one question.

Did we build the new thing correctly?

It is a good question, and it is no longer the expensive one.

The question that now decides whether a release is safe is a different one.

Did we accidentally change something that already worked?

Almost nothing in a standard pipeline was designed to answer that.

Every stage answers a different question

Your test suite answers whether known behaviors still satisfy known expectations. Useful, and it covers the part of the past somebody remembered to encode. You cannot write a test for a behavior you do not know you have.

Code review answers whether a change looks reasonable to another engineer. Also useful, and it reads a diff rather than a system.

Monitoring answers whether production is unhealthy right now, and it answers that well. It speaks once your customers are already inside the problem.

Every one of those answers is worth having. None of them answers the question that decides a release before it leaves the building.

Does the product still behave the way it behaved yesterday?

Snapshot, approval and contract testing get closer, because they do compare against previous behavior. What they compare is the behavior somebody chose to capture. Everything outside that recorded surface stays invisible.

Which is why so much still reaches production. Not because the gates failed, but because everything passed the gates and the gates were never asked this question. Things clear every check, and then customers find them.

How regressions hide

The regressions that cost the most are not the ones a careless change causes. They are the ones a correct change causes, because a correct change gets approved.

Three things have to line up for one to survive. The consequence has to surface somewhere other than the code that moved, so nobody thinks to look there. It has to be intermittent rather than constant, so the system looks healthy whenever anyone checks. And it has to be separated from its cause by enough time that the connection stops being obvious.

A change that alters how long something is retained, or which state a record is left in, or what an unset value falls back to, can satisfy all three. It reads as small. It reviews as correct. It is correct, in every dimension the review can assess. What it changed was a behavior nobody was watching, and by the time the effect is undeniable the change that caused it is weeks behind.

Yesterday’s production is your best specification

Documentation goes out of date. Design documents simplify. Tests describe only the behaviors people remembered to encode.

Production is different.

Yesterday’s production behavior is the only complete specification your software has. It is everything customers already rely on. Not what somebody intended the product to do, but what it actually does.

Documentation, tests and code review are partial references. Production behavior is the complete one

That changes the release question from did the checks pass to what behaviors changed compared with production.

A different way to evaluate a release

Early holds the current production release as a behavioral baseline and compares every release candidate against it, flow by flow.

Instead of another dependency graph or another file diff, it surfaces the product behaviors that changed and highlights which of them deserve human review. A person still decides what each one means.

A production baseline and a release candidate compared, with one behavioral difference surfaced

It does not replace your tests, your reviews or your monitoring. It complements them, by answering a question none of them were designed to answer.

Before your customers do

Nobody can promise software without regressions. Every meaningful change carries consequences somebody did not intend.

What can change is when you find out.

An unexpected behavioral change found while the release is still a candidate is a review conversation. The same change found three weeks later by a customer is an incident, a rollback, a postmortem, and another withdrawal from trust you spent years earning.

The question was never whether software changes.

The question is whether you find the unintended changes before your customers do.

See what your next release puts at risk