Software Entropy and the Ethics of Craft
A reflection inspired by The Pragmatic Programmer, Uncle Bob, and the Agile principle of sustainable development: software quality is a cultural and ethical practice.

Some years ago, I shared a page from The Pragmatic Programmer on LinkedIn with a short note:
Probably the page that changed my working life when I read it years ago, and the one I still return to in my mind whenever I encounter “dirty” situations. An ethical commitment to doing things well, every day.
Pragmatic Programmer, page 5
I meant it literally. That page is the short section on software entropy, and it has aged better than almost anything else I read early in my career.
Some months later I shared another page, this time from Uncle Bob. My note was about something that still bothers me: too many people treat programming as a temporary stage, something to survive for a few years before moving into management or away from technology entirely. The assumed destiny of a programmer is to fight the machine until exhaustion, then become something else. I argued the opposite, leaning on the Agile idea of a sustainable pace: programming can be a craft you stay in, not a phase you escape.
The two pages stayed connected in my mind. One talks about entropy: the way software decays when broken windows are left unrepaired. The other talks about craftsmanship: the discipline, standards, and apprenticeship that make it possible to resist that decay without burning out.
Together they describe something I still consider central to this job: doing software well is not only a technical practice. It is an ethical one.
The metaphor of entropy is simple: physical systems tend toward disorder, and software projects have their own version of that tendency. We call it many things: software rot, decay, technical debt, erosion, entropy. The words change, but the feeling is familiar to anyone who has worked on a project long enough.
The codebase does not usually collapse in one spectacular moment.
It gets worse quietly.
A bad decision remains in place because there was no time to fix it. A temporary workaround becomes part of the architecture. A test suite starts failing intermittently, so people stop trusting it. A naming convention is broken once, then twice, then everywhere. A module becomes unpleasant to touch, so everyone routes around it. The project still works, but it starts to feel abandoned from the inside.
That slow worsening is the part I find most interesting, because it is never only a technical process. It is also a psychological one, and that is where craftsmanship enters the picture.
The first broken window
The section in The Pragmatic Programmer connects software entropy to the broken windows theory: the idea that visible neglect can change how people behave around a place.

In the original urban metaphor, one unrepaired broken window signals that nobody is paying attention. Then a second window breaks. Then litter appears. Then graffiti. At some point, abandonment stops being a perception and becomes the actual state of the building.
The software equivalent is painfully recognizable.
One broken test says: this suite is not reliable.
One ignored lint rule says: consistency is optional.
One undocumented production workaround says: operational knowledge can live in someone’s head.
One bad abstraction that nobody wants to touch says: this part of the system is not worth caring for.
None of these is fatal alone. That is why they are dangerous.
They are small enough to postpone.
But they are also visible enough to teach the team what is acceptable.
Technical debt is too optimistic
I have always liked the term “technical debt”, but it can be misleading.
Debt implies a ledger. It suggests that we knowingly borrowed time from the future and that, one day, we will repay it with interest.
Sometimes that is true.
A team can make a conscious tradeoff: ship the simpler version now, record the limitation, return to it after validation, and replace it with a more durable design when the product proves the need.
That is debt.
But many broken windows are not debt in that clean sense.
They are not strategic. They are not tracked. They do not have an owner. They were not accepted by the team as a conscious tradeoff.
They are just damage.
Calling everything technical debt can make decay sound more intentional than it really is. It can create the illusion that the project has a repayment plan, when in practice the team is simply getting used to a lower standard.
Software entropy begins when deterioration becomes normal.
Culture is stored in code
Codebases carry culture.
Not as slogans, not as values written in a company handbook, but as repeated decisions.
You can learn a lot about a team by reading its code:
- whether failures are handled explicitly or pushed away;
- whether naming is treated as part of design;
- whether tests are trusted or merely present;
- whether errors are actionable or decorative;
- whether duplication is tolerated when it hides uncertainty;
- whether comments explain intent or excuse confusion;
- whether configuration is designed or accumulated.
The codebase tells new contributors what kind of behavior belongs there.
A clean module asks people to be careful. A messy module gives them permission to be messy. A precise test suite invites precise changes. A flaky test suite invites indifference.
This is why entropy spreads so easily.
Developers are not only modifying code. They are reading social cues from the system.
Craft is not nostalgia
The word “craftsmanship” can sound old-fashioned.
It can suggest a romantic image of the lone expert, the artisan, the person who cares about invisible details while the world only wants shipping dates.
I do not think that is the useful interpretation.
Craft is not nostalgia. It is not decoration. It is not pretending software should be handmade furniture.
In software, craft means having standards that survive pressure.
It means knowing that small decisions compound. It means understanding that code is read more often than it is written. It means treating tests, names, boundaries, errors, logs, documentation, and deployment paths as part of the product, not as secondary chores.
Most importantly, it means the work is meant to be learnable.
A craft has transmission.
People enter as beginners. They observe. They imitate. They are corrected. They acquire taste. They learn which shortcuts are acceptable and which ones damage the work. They become able to teach the next person.
Software often pretends this happens automatically.
It does not.
Without apprenticeship, teams get more developers but not necessarily more professionals. People learn the syntax, the framework, the ticket flow, the deployment ritual. But they may never learn the disciplines, standards, and ethics that make the work sustainable.
That is why the “programming as a temporary phase” mindset is so damaging.
If everyone is trying to escape the craft, nobody is left to transmit it.
The cost of caring alone
One of the most frustrating situations in software work is being the only person who still seems to care about a broken window.
You see the naming problem.
You see the unsafe edge case.
You see the missing test.
You see the module that keeps getting worse because everyone is afraid to touch it.
At first, caring feels professional. Then it starts to feel lonely. If nobody else reacts, your own standards begin to feel like personal fussiness rather than project hygiene.
That is where entropy becomes psychological.
It is not only that the code gets worse.
It is that the team loses confidence that improvement is possible.
Once people believe “this is just how the project is”, they stop repairing windows. They adapt to them. They build habits around them. They add new code in the same style because consistency with a bad local pattern feels safer than introducing a better one.
The project has trained them.
Sustainable pace is also a quality principle
There is an Agile principle that is usually quoted as a warning against burnout:
Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
That sentence is often read as a humane process guideline, and it is.
But I think it is also a software-quality principle.
If a team cannot maintain its pace indefinitely, quality will become the first hidden expense.
Under unsustainable pressure, people stop repairing broken windows. They stop teaching. They stop refining names. They stop writing the test that would make the next change safer. They stop asking whether a design will still make sense in six months. They stop making the system easier for the next person.
At some point, speed becomes extraction.
The project extracts energy from the team, clarity from the codebase, and options from the future.
Craftsmanship is not the opposite of agility. It is one of the conditions that makes agility possible for more than a short burst.
You cannot maintain a constant pace indefinitely if every sprint makes the code harder to change.
You cannot call a process sustainable if the only way to keep it moving is to consume the people doing the work.
You cannot build a serious software practice if programming is treated as the painful stage before the “real” career begins.
AI agents make this sharper
Working with AI agents makes the broken windows problem more important, not less.
An agent will usually follow the local pattern it finds.
If the codebase is clear, typed, tested, and consistent, the agent has a better chance of producing useful work. It can infer conventions. It can reuse existing helpers. It can run verification. It can make a small, coherent change.
If the codebase is full of broken windows, the agent will often reproduce them.
It may copy the wrong abstraction because that is the nearest example. It may preserve accidental naming because it looks like convention. It may route around missing tests because the project itself does not communicate that tests matter. It may turn local disorder into generated disorder at higher speed.
This is one of the reasons I have become more interested in Markdown plans, explicit acceptance criteria, and small reviewable changes.
Agents can help reduce entropy, but only when the human side remains opinionated about standards.
Without that, they can accelerate decay.
Boarding up matters
The useful lesson from the broken windows metaphor is not that every problem must be perfectly fixed immediately.
That is unrealistic.
Sometimes there is not enough time. Sometimes the product direction is uncertain. Sometimes a dependency is temporary. Sometimes the correct design is still not visible.
But doing nothing is different from making a temporary repair visible.
When a team cannot fix the window, it can still board it up:
- add a failing test that documents the bug;
- isolate the workaround behind a named function;
- leave a short design note explaining why the compromise exists;
- create a tracked task with a clear owner;
- add a runtime guard instead of silently accepting bad state;
- remove dead code instead of letting it become archaeological noise;
- mark an unsupported path explicitly rather than pretending it works.
These actions are not perfect repairs.
They are signals.
They tell the next person: we saw this, we care, and this is not the standard we want to normalize.
That signal matters more than it looks.
Entropy work is product work
Teams often separate “feature work” from “maintenance work” as if one creates value and the other merely cleans up after value has been created.
That split is too simple.
A product is not only the features users see. It is also the system’s ability to keep changing without becoming frightening.
If every new feature makes the next feature harder, the product is spending its future. If every bug fix increases local disorder, the product is losing maneuverability. If every deadline teaches the team that quality language is ceremonial, the product is weakening its own delivery system.
Reducing entropy is not aesthetic perfectionism.
It is preserving the ability to act.
The small standard
The best teams I have worked with were not the teams that had no broken windows.
Every real project has some.
The best teams were the ones where broken windows remained visible as broken.
People could say:
This is not good enough yet.
We are accepting it temporarily.
Here is why.
Here is how we will contain it.
Here is what would make it acceptable later.
That is a very different culture from pretending the window is not broken.
It keeps the standard alive.
Software entropy will always be there. Every system changes. Every team makes compromises. Every project accumulates history.
The question is not whether disorder appears.
The question is whether the team still reacts when it does.
References
- The Pragmatic Programmer, 20th Anniversary Edition - the book that prompted this reflection, especially its early section on software entropy.
- My LinkedIn post on page 5 of The Pragmatic Programmer - the first of the two posts mentioned at the start.
- My LinkedIn post on Uncle Bob and the sustainable pace - the second post, on programming as a craft rather than a temporary phase.
- Pragmatic Programmer Tips - includes Tip 5, “Don’t Live with Broken Windows.”
- The Clean Coder - Robert C. Martin’s book on professional conduct, discipline, and software craftsmanship.
- Principles behind the Agile Manifesto - especially the principle on sustainable development and constant pace.
- Broken Windows - the 1982 essay by George L. Kelling and James Q. Wilson that introduced the metaphor in its original urban context.
- AI Agents Are Making Me a Better Programmer - my related reflection on making software work more explicit when working with coding agents.
Share