I counted them once, on a slow afternoon between deployments. Ninety-six releases in a little under three years on the same platform. Some were large, most were ordinary, a few I'd rather forget. And when I sat with that number, trying to work out what it had actually taught me, I expected the lesson to be something about process. Better testing, tighter change control, cleaner handoffs. Something you could put on a slide.

It wasn't any of that. The lesson, the one that took me nearly a hundred releases to properly learn, is embarrassingly simple and much harder to live by than it sounds.

Say no earlier.

Not no more often. Earlier. There's a difference, and the difference is where most of the pain lives.

The scope creep you can see isn't the one that hurts

When people talk about scope creep, they usually picture the obvious version. Someone asks for a feature that wasn't in the plan, it gets waved through, and the release balloons. That happens, and it's annoying, but it's honestly the easy case. It's visible. Somebody can point at it, argue about it, and either push it to the next release or accept it with their eyes open. Visible scope creep gets managed, because it announces itself.

The scope creep that actually damaged the releases I worked on was quieter than that, and it almost never looked like a new feature. It looked like a small ambiguity nobody resolved.

A requirement would come in that was ninety percent clear. The remaining ten percent was a question nobody wanted to stop and ask, because asking it felt like slowing down a thing that was moving nicely. Does this new premium calculation apply to policies already in force, or only new ones? When we say the report should show "current" exposure, current as of when? These weren't feature requests. They were forks in the road, disguised as details, and the temptation every single time was to note them as minor open points and keep moving, because the release had momentum and momentum feels like progress.

And here's the trap. Each of those little unresolved questions doesn't cost anything on the day you skip it. It costs later, and it costs far more than it would have, because by the time it surfaces, something has been built on top of the wrong assumption. What would have been a thirty-second conversation in refinement becomes a defect found in testing, or worse, a defect found by a user in production, at which point unwinding it means unwinding everything that quietly assumed the wrong answer.

Why "later" is so expensive in this particular world

I work on reinsurance platforms, and this world is unusually unforgiving about the cost of a late no, for a reason that's worth naming.

The things we build sit on top of contracts and calculations that reach backwards and forwards through time. A treaty, a cession, a recovery, a reserve movement. Get an assumption wrong in a normal system and you fix it going forward. Get an assumption wrong here and it doesn't just affect what happens next. It quietly corrupts a chain of figures that have to reconcile across periods, and the wrongness doesn't announce itself politely. It shows up at quarter-end, or in a regulatory report, or when a reinsurer's team disputes a number, which is the worst possible moment to discover that a decision you deferred nine months ago was made, by default, incorrectly.

So the deferred question isn't a neutral thing you can pick up later at the same price. In this domain it accrues interest. The longer an ambiguity stays unresolved, the more code and data pile up on top of whichever interpretation someone guessed at to keep moving, and the more expensive it becomes to discover you guessed wrong.

The uncomfortable thing about saying no earlier

If the fix is so simple, why did it take me the better part of ninety-six releases to internalize it? Because saying no earlier feels, in the moment, like being the difficult one.

Early in a release, everything is optimism. The plan looks clean, the team is energized, the stakeholders are happy, and into that pleasant atmosphere you have to be the person who stops and says, wait, we haven't actually decided what "active policy" means here, and we can't build this until we do. That is not a popular intervention. It reads as pedantic. It slows down a thing that was feeling fast. Nobody thanks you for it, because the cost you're preventing is invisible and hypothetical, while the delay you're introducing is real and right in front of everyone.

Saying no later, by contrast, feels responsible, because by then the problem is obvious and everyone agrees it needs handling. But that's exactly backwards. The no that everyone agrees with is the one that's already too late to be cheap. The valuable no is the one that feels premature, slightly annoying, and unnecessary, precisely because it's early enough to still be free.

I came to think of it as the difference between being briefly unpopular in refinement and being quietly responsible for a defect in production. Those are the two options, more often than not. The scope question doesn't disappear because you were polite about it. It just moves downstream and gets more expensive.

What this looks like when you actually do it

The discipline, in practice, is less about saying no to features and more about refusing to let ambiguity travel.

It's asking the awkward clarifying question while the requirement is still a sentence, not a build. It's treating "we'll figure that edge case out later" as a small alarm bell rather than a reasonable plan, because later is where edge cases go to become expensive. It's being willing to hold up something that looks ready over a detail that looks minor, on the instinct, earned over enough releases, that the minor-looking details are exactly the ones that come back.

And it's a shift in what you consider your job to be. For a long time I thought a good analyst was one who captured everything clearly. I now think a good analyst is one who forces the uncomfortable decisions to the surface early, while they're still cheap to make, rather than documenting them neatly and letting them drift downstream. Clear documentation of an unresolved question is not progress. It's a beautifully written liability.

The one line I'd give my younger self

If I could go back to release one and tell myself a single thing, it wouldn't be about tooling or testing or any of the things I assumed mattered when I started counting.

It would be this. The scope decisions that sink a release are almost never the big obvious ones. They're the small ambiguities you were too polite, or too rushed, or too optimistic to resolve when resolving them was still free. Every one of them is a bill that arrives later with interest, usually at the worst possible moment.

So say no earlier. Ask the annoying question now. Be the person who slows things down for thirty seconds in refinement, and you'll be the person who didn't have to explain a production defect three months later.

Ninety-six releases taught me that. I'm fairly sure the next ninety-six will just keep proving it.