Consequential

ContentsAct I · DecideShrink the work

Move 15

Cut scope, not quality

One of them is a decision somebody made in the open. The other is a loan taken out in your name, against people who are not in the room.

It is the last week and it will not all fit. Everyone knows what happens now: something gets cut. The only question is what, and there are two available answers that look superficially similar.

You can ship fewer things. Or you can ship the same things, worse.

The two cuts are not the same shape

Cutting scope is a decision. It happens once, out loud, at a price everybody can see. The export is not in version one. It goes in the ticket, somebody agrees to it, and it is trivially reversible: if it matters, you build it next month.

Cutting quality is a loan. Nobody approves it, because nobody is asked. It does not appear in the ticket, it is invisible in the demo, and it has no repayment date. The person who eventually pays is whoever is on call, or whoever picks up that file in March, and neither of them was in the room when the decision was made.

That asymmetry is the whole move. It is not that quality matters more than scope in some abstract sense. It is that one of these is a choice with a named owner and the other is a transfer of cost to people who cannot object.

CUTTING SCOPE                     CUTTING QUALITY

 "no CSV export in v1"             "no tests on the reconciler,
                                    we'll add them after"
 written in the ticket
 visible in the demo               written nowhere
 somebody agreed to it             nobody was asked
 reversible: build it later        discovered on a Sunday
 cost: known, now                  cost: unknown, later, someone else

 the person who pays               the person who pays
 is the person who decided         is not in the room

The evidence, and the folklore you should not use

I want to be careful here, because this argument usually arrives attached to a number that does not survive checking.

The classic claim is the cost-of-defect curve: a bug costs one unit to fix in design, ten in testing, a hundred in production. It is everywhere, and the largest study of it does not support it. Menzies and colleagues tested for the delayed issue effect across 171 software projects and reported: “We found no evidence for the delayed issue effect; i.e. the effort to resolve issues in a later phase was not consistently or substantially greater than when issues were resolved soon after their introduction.” Their conclusion is that it “might be an historical relic that occurs intermittently only in certain kinds of projects.”

So do not use it. The outline for this chapter says cutting quality costs you twice, and that is a figure of speech rather than a measurement, so I am not going to print it as one either.

What does survive measurement is narrower and quite enough. A study of 39 proprietary production codebases, analysing activity across 30,737 files, found that low quality code “contains 15 times more defects than high quality code”, that resolving an issue in it “takes on average 124% more time in development”, and that those resolutions carry “9 times longer maximum cycle times”.

That last one is the one to hold onto. It is not just slower. It is less predictable, which means the estimate you give in March will be wrong in a direction you cannot plan around.

This is happening right now, at scale

The industry is currently running this experiment on itself. Across 22,000 developers, bugs per developer are up 54%. Meanwhile refactoring, measured as moved code, has collapsed from 21% of changed code in 2022 to 3.8%.

Read those together. More defects arriving, and the activity that repays quality debt nearly gone. That is what cutting quality at scale looks like while it is happening, before anybody has called it a problem.

The move

When the week is short, take things out of the release. If you are going to lower the bar instead, write it down and give it a date.

The second clause is the honest part, because sometimes you genuinely do have to cut quality. There are real deadlines with real consequences and occasionally the trade is correct.

What makes it survivable is that it stops being invisible. Not we’ll clean it up later, which means never. A line in the ticket, a name, and a date:

Shipping the reconciler without integration tests to make Friday. Tests by 14 March, owner me, ticket ENG-4602 already created.

That is still a loan. But it is a loan with a due date, which is a completely different object from a loan nobody recorded.

What it costs

Cutting scope is more visible, and visibility is uncomfortable. Removing the export is something your stakeholder sees and may push back on. Shipping it untested is something nobody sees at all. The path of least social resistance runs the wrong way, every time, which is why this needs to be a rule you decided in advance rather than a judgment you make at 6pm on a Thursday.

And “quality” is not one thing. Skipping a loading state is not skipping input validation. Deciding which parts of the bar are movable is the actual skill, and the previous move is where that list gets written: the column you named as not negotiable is the one that does not move now.

Try this week

Look at the last thing your team shipped late, and find what gave way.

If it was scope, find where it is written down, and check whether the thing that was cut ever got built. Sometimes the answer is that nobody ever missed it, which is worth knowing.

If it was quality, write the note that should have existed, now, retroactively: what was skipped, who owns it, and a date. Then put it in the backlog where somebody can see it.

That is the whole of Act One in one action, really. You have taken something that was going to be discovered by whoever was unlucky, and turned it into a decision with a name on it. The rest of this book is variations on that move.