All notes

Note August 2026

Software That Finishes

Most software is never allowed to be done. What changes when finishing is the goal rather than the failure state.

A product that stops changing is usually read as a product that stopped mattering. The roadmap goes quiet, the changelog thins out, and someone eventually asks whether the thing is still maintained. We have started answering yes, and nothing is planned, and meaning it.

The assumption underneath the question is that software is a service rendered continuously — that a tool has to keep arriving to keep being worth something. For a certain kind of product that is true. For most of what we build, it is a habit borrowed from companies with growth expectations we do not have.

What each feature costs after it ships

The build cost of a feature is the part you can see and the part that ends. The part that does not end is the surface it adds to everything already there — every new capability has to keep working alongside every old one, across upgrades nobody asked for.

$$\begin{aligned} \text{build} \;&\propto\; n \\[2pt] \text{carry} \;&\propto\; \tbinom{n}{2} \;=\; \frac{n(n-1)}{2} \end{aligned}$$

Building is linear in features. Carrying them is not.

Where \(n\) is the number of things the product does. Shipping the tenth feature costs about what the ninth did; carrying it costs roughly nine new interactions, each of which can break, confuse, or need a migration. Doubling the surface roughly quadruples what has to keep holding together.

This is the arithmetic behind a familiar shape: a small team ships quickly for two years, then slows to a crawl without anyone doing anything wrong. Nobody got worse. The carry got larger than the capacity, and every hour now goes to keeping the existing thing upright.

Finished is not abandoned

A finished product still gets security patches, still gets fixed when a dependency moves underneath it, still gets answered when someone writes in. What it does not get is new scope. The distinction matters because the two are constantly confused — usually by the person proposing the new scope.

Deciding a product is finished is a decision about \(n\), and it is worth making explicitly rather than discovering by exhaustion. It converts an open-ended obligation into a bounded one: a known, small annual cost to keep something working, against however long it stays useful. That is the same trade we like in a domain, and the same reason the holding structure suits us. Bounded cost, unbounded duration.

How we decide

We ask two questions of a proposed feature. Does the product fail at its stated job without it? And would we still want it in the codebase in five years, when whoever asked for it has moved on? A request has to survive both. Most survive neither — they are real requests from real users that happen to describe a different product than the one we built.

Saying no to those is not discipline so much as arithmetic. Every yes is a permanent addition to the carry, paid by a team that stays small on purpose.

The products we are proudest of holding are the ones we have not touched in a year and that still do exactly what they did when we stopped. They earn quietly, need almost nothing, and have never once appeared in a planning meeting. In a portfolio meant to be held for a decade, that is not neglect. It is the point.

Keep reading

View all