Article 5: The Case Against Code
Or: What Evolution Teaches Us About LLMs
Donald Hoffman has spent decades arguing that we don’t see reality.
Not because we’re broken. Because we’re optimised.
The Fitness Interface
Hoffman is a cognitive scientist at UC Irvine. His theory: evolution didn’t shape our perception to see truth. It shaped us to see what’s USEFUL.
We don’t see the world as it is. We see a desktop.
Think about your computer. You see icons. Folders. A trash can. None of these things “exist” inside the machine. There are no tiny folders in there. The icon is an interface — a useful fiction that lets you get things done without understanding voltages and transistors.
Hoffman argues that reality is like this. The apple you see isn’t the apple as it is. It’s an icon. A symbol your brain renders because it’s useful for survival.
Organisms that evolved to see “truth” got outcompeted by organisms that evolved to see “fitness.”
The interface won.
The Case Against Code
I think there’s a version of this for software.
Developers are trained to believe they should understand their code. See the reality underneath. Maintain it. Own it. Know every line.
But what if that’s like trying to see past the desktop icons?
What if the most effective developers aren’t the ones who see “truth” — but the ones who work skillfully at the interface level?
Specs as Icons
When you write a spec and let an LLM generate code, you’re working at the interface level.
You’re not manipulating transistors. You’re not even manipulating code, really. You’re manipulating meaning. Intent. Outcome.
The spec is your icon. The generated code is the voltage underneath — real, but not where you live.
And just like Hoffman’s fitness interface: you don’t need to see underneath to get things done. In fact, trying to see underneath might slow you down.
Fitness Beats Truth
Hoffman ran evolutionary simulations. He pitted “truth-seeing” organisms against “fitness-seeing” organisms.
Fitness won. Every time.
The organisms that saw reality accurately went extinct. The ones that saw useful fictions — the ones tuned for action, not accuracy — survived.
I think something similar is happening in software.
Developers who try to maintain every line of code, who try to “see the truth” of their entire codebase, are being outcompeted.
By who?
By developers who maintain specs. Who regenerate instead of debug. Who work at the interface level and let the LLM handle the voltage underneath.
Fitness beats truth. Interfaces beat internals. Specs beat code.
The Desktop is Real Enough
Here’s the thing about Hoffman’s theory: he’s not saying the desktop is fake. He’s saying it’s USEFUL.
The trash can works. You can delete files with it. The fact that there’s no tiny bin inside your computer doesn’t make the icon useless — it makes it an effective interface.
Same with specs.
Your spec isn’t the “real” code. But it works. You can build software with it. The fact that you didn’t write every line doesn’t make the output useless — it makes the spec an effective interface.
The desktop is real enough. The spec is real enough.
What You Maintain
Hoffman’s interface theory asks: what level should you operate at?
Not the deepest level. Not the “truest” level. The level that’s tuned for fitness. For getting things done. For surviving.
For developers, this means asking: what do I actually maintain?
Not every line of generated code. Not the “truth” of your codebase.
You maintain:
The specs (your icons)
The durable foundations (databases, auth, core logic)
Your ability to regenerate (the LLM-as-compiler workflow)
Everything else is voltage. Let it flow.
The Case for Interfaces
Hoffman’s work is controversial. Some call it radical. Some call it obvious dressed up in math.
But the core insight feels true to me:
We’re not built to see reality. We’re built to work with it.
And maybe that’s what mcauldronism is really about. Not pretending we can see every line of code. Not maintaining the unmaintainable. But building good interfaces — specs, tools, workflows — and trusting them to handle the depth.
The case against reality is the case for interfaces.
The case against code is the case for specs.
Work at the level that works.
[Part 1: Where Do You End?] [Part 2: The Maintenance Cost is Zero] [Part 3: The Cauldron in the Spectrogram] [Part 4; REDACTED] [PART 5: It’s Time to Talk About Ethics]


I gotta really disagree with this one. If you're just casually generating some code for some minor work and otherwise have no interest in software development, then this can work, but actual software developers MUST understand the code, and very thoroughly at that.
For them, letting AI write code is not a license to stop understanding it. If they don't understand the code, then they can't understand what the AI is actually doing. They lose visibility into the logic, the ability to catch bugs, verify correctness, audit behavior, assess security (very huge importance), optimize performance, and maintain the system when something breaks or changes. In addition, there will very quickly be huge conflict with the other developers in the team, as everyone is expected to be competent at their chosen profession. AI must be subject to human review, as otherwise unnoticed problems can lead to serious issues.
The specs point too. In any serious software dev project, writing out the specs is only one small part of the overall project. The specs don't address important things like architecture, which requires crucially important decisions, with awareness of protocols, algorithms, methodologies, and integrations.
Software dev lifecycle:
- Intent (Why the software exists. The purpose, problem, goal, or desired outcome)
- Features / Requirements / Specs (What the software must do, capabilities, obligations, constraints, and behavioral conditions)
- Architecture (How the system is structurally organized at a high level: major components, boundaries, responsibilities, data flow, interfaces, and system shape)
- Design (How specific parts are planned in more detail within that architecture: component logic, module behavior, detailed flows, structures, and technical decisions)
- Implementation (The actual building of the software: Writing/generating code, wiring systems together, turning plans into executable behavior)
- Test (Checking if it works: Validation of every feature, bug finding, edge cases, integration checks, QA)
- Stage (Making sure it keeps working: testing by using for its intended purpose)
- Deploy (Running software in its real target environment: Releasing it into production)
- Maintain (Fixes and improvements: fixing bugs, new features, adapting to changing conditions, improving performance, handling regressions, security exploits/vulnerabilities)
- End of life (Retiring the software: ending support, shutting it down or replacing it, migrating users and data, and decommissioning it)
The good thing is that AI can teach all that.
Interesting... a practical question - if something isnt working quite right with whatever the code is creating e.g. one element on a webpage - for example a form, do you need to ask it to recreate the whole webpage, or can you ask it to fix just that element (does it rebuild the whole thing from scratch every time?)