Done means used

There is a day in one of my repositories with forty three commits in it, the busiest in that project's history, and it taught me the most useful definition I have.
The morning reads like a plan being ticked off. Stage one complete, foundation and setup. Stage two, the chat interface and the model integration. Stages three, four, five, complete. Then a commit adding a comprehensive README describing the finished thing.
The afternoon is the rest of the story: forwarding session cookies through the API routes, because the shop's session did not survive the hop. The token handling for the store endpoints, a separate mechanism nobody mentions until it rejects you. Stopping the analytics script injecting itself into API responses and corrupting the JSON. The model's reasoning consuming the whole output budget, so answers arrived empty.
By evening the shop could put an item in a basket. That is what stages two through five had claimed before lunch.
The definition
Nothing is done on the basis of its own code. Done means somebody used it, through the real interface, on real data, start to finish.
For a shop: an item in a basket and a payment taken. For a form: saved, page reloaded, value still there. For an import: run twice, and the second run does not duplicate anything.
Three sentences, and they have caught more false completions than any test suite I have written.
Why this matters more than it used to
Each of those stages genuinely was complete, in the sense that coherent code for it existed. What did not exist was the agreement between two things written separately: a session, a token, a header, a shape.
That has always been where the work is. What changed is the ratio. Writing the five stages took a morning. Making them agree took the rest of the day, and nothing about that second part got faster.
So the productivity claim people make is wrong in an interesting way. I am enormously faster at producing code and roughly as fast as I ever was at making separate things agree. Which means integration is now most of the job, and it is the part that still needs someone who can hold two systems in their head.
The checklist I run before calling anything finished
- Did I use it myself, through the interface a user would touch?
- Did I run it twice?
- Did I watch it fail on purpose once, with bad input?
- Is there one value in there that came from a real source rather than a fixture?
Four questions, about two minutes. They are the cheapest quality mechanism I have and they are entirely manual on purpose, because every one of them tests the thing a test cannot see.
The commits are still there
I left that morning's commit messages in the history rather than tidying them.
They are a good reminder of how convincing finished looks from the inside, and of the fact that the convincing part arrives first and the true part arrives after lunch.