Software is in a continuous state of disintegration...
One of the uncomfortable truths we sometimes have to break to people is that software isn't just never “done”. Worse even, it rots. Your software rots right now, as you’re reading this post. It disintegrates...Even worse, it won’t help to hire top-notch people who try really, really hard to craft good software. Then it just disintegrates a little slower.
The practices of continuous integration act as enablers for us to keep adding value and keeping development maintainable, but they cannot stop the inevitable: The system will eventually fail in unexpected ways, as is the nature of complex systems:
It may depend on a library that needs an urgent security patch, cascading long-overdue upgrades and forcing an update to be deployed instantly. Or unexpected growth may require redesigning a performance bottleneck. Or legislation requires a big rewrite of the way we store our personal information.
All of this is a natural part of the software development lifecycle and will continue until the day the whole system is fully decommissioned: Only when the last contract is expired, the last user stopped sending weird inputs and the last server has been sent to a nice retirement Homelab on the coast, can we consider the software “done”.
Because of this natural tendency of software to rot, we also must accept that every ever-so-tiny feature that a team adds will absolutely put future work onto the organisation, and we can’t even say how much.
The difference is in how we chose to handle this:
The traditional answer to this is moving maintenance and operations work into dedicated teams. Now we have the classic foundation for a feature factory, where dev teams constantly throw more code over the wall to the operations teams, who try to keep the ship afloat while everyone is constantly busy with managing the interconnectedness of all the extra work that is (not) flowing between them.
In contrast, at crafted., we prefer building autonomous teams around a “you build it, you run it” structure, where the operations team acts in a support role, e.g. providing version control, CI/CD and other supportive infrastructure as well as knowledge.
The dev teams then accept that maintenance is their responsibility, adding chores to their workload which creates a natural incentive to automate as much of them as possible.
By pushing automation to the limits, a crafted. team will notice when it approaches the natural carrying capacity of how much software it can handle sustainably: When there’s nothing we can automate, and the chores are distracting from writing new code, we must decide:
The prudent way forward is to decommission something before adding more.
Or we’ll have another team build the new thing, and run it until its end.