2023.04.18

what does it actually mean for software to be finished?

the code runs, the feature works, and somehow the software is still not finished. i have been thinking about what done really means.

i have a small problem with the word "finished" in software.

when i started building things, finished meant the code ran. if i clicked the button and the correct thing happened, that was it. close the editor, take the screenshot, move to the next idea.

but software has an annoying habit of continuing to exist after the exciting part is over.

the user enters something you did not expect. the API goes down. the database grows. a dependency changes. you open the project three months later and cannot remember why one strange condition is holding the entire thing together.

the feature was finished. the software was not.

there are different kinds of done

i think a lot of frustration comes from using one word for several different states.

there is demo done. the happy path works well enough to show another person.

there is useful done. somebody can use it for a real task without you standing beside them explaining every button.

there is production done. failures are handled, important actions are logged, data is backed up and the application can survive being restarted.

then there is maintainable done. another person, or your future self, can understand the system well enough to change it without archaeology.

these are not the same finish line.

a weekend script does not need the operational ceremony of a payment platform. a private tool can survive with rough edges that would be unacceptable in software used by strangers. the mistake is not stopping early. the mistake is pretending we reached a different kind of done.

the last twenty percent is not really twenty percent

the visible feature is usually the clean part. receive input, perform an operation, return output. it fits inside a diagram.

the rest is where reality enters:

  • what happens when the input is empty?
  • can an action safely run twice?
  • what happens halfway through a failed operation?
  • where do errors go?
  • how do we know the service is alive?
  • can we restore the data?
  • what will confuse me when i return later?

none of these questions look impressive in a screenshot. they are still the difference between code that works once and software that keeps working.

abandoned is also a valid state

not every project deserves completion.

sometimes the idea has already taught you what it needed to teach. sometimes the problem is not worth solving. sometimes you discover that maintaining the solution will cost more than the inconvenience it removes.

i used to see an unfinished repository as evidence of failure. now i think a project becomes dangerous when we refuse to admit that we are no longer responsible for it. an abandoned experiment with a clear note is healthier than a supposedly active product nobody is watching.

software can be finished by being retired properly too.

my current definition

software is finished when it has reached the level of responsibility its users expect from it.

for a script, that may mean it solves my problem and has enough comments for next month. for a public application, it means the boring things have been considered: errors, security, recovery, monitoring and maintenance.

the code running is still a lovely moment. it is just not always the end.