The frame for any argument about “cleanliness”: the complexity of the problem domain cannot be removed; the complexity introduced by tools and abstractions can be, and should be attacked.
The source is Fred Brooks, “No Silver Bullet — Essence and Accident in Software Engineering” (1986, reprinted in IEEE Computer, April 1987). Brooks borrows Aristotle’s distinction: the essence of software is the conceptual construct — data, relationships, algorithms, interfaces — and its accidents are the difficulties of representing that construct in a language on a machine. His argument: high-level languages, time-sharing and unified environments had already removed most of the accidental difficulty, so no further single development could yield an order-of-magnitude gain within a decade. That was a forecast backed by argument, not by measurement. Moseley and Marks, “Out of the Tar Pit” (2006), sharpen the line for engineers: essential is what the users’ problem requires; everything else, including most mutable state and explicit control flow, is accidental.
An example. Tax rules per jurisdiction, late-arriving events that must be attributed to the right day (79), refunds that reverse a partially shipped order — that is essential; no framework makes it smaller, and code that pretends otherwise just hides it. A message bus between two functions in one process, a repository interface with one implementation over an ORM over SQL, a custom DSL for five config values — that is accidental, and every layer has to be read, deployed and debugged. The review question: “what essential complexity does this layer express?” No answer — the layer is accidental.
Misuse. The line is not fixed: a retry layer is accidental in a monolith and essential once the call crosses a network (63). Labelling a colleague’s abstraction “accidental” is not an argument until you say which requirement it fails to serve. And removing accidental complexity is not free either — a rewrite to remove it can cost more than living with it (73, 75).