✓ Human-authored analysis; AI used for formatting and proofreading.
In 1986, Fred Brooks published "No Silver Bullet — Essence and Accident in Software Engineering." His argument: software complexity has two kinds. Accidental complexity is the difficulty imposed by the tools — syntax rules, boilerplate code, build configurations, deployment scripts. Essential complexity is the difficulty imposed by the problem. The business rules, the data relationships, the edge cases where the real world doesn't fit neatly into a data model.
Brooks predicted that even if we eliminate ALL accidental complexity, software will still be hard. Essential complexity is irreducible. It comes from the domain, not the tools. No tool can eliminate it because it's not a property of the tool. It's a property of the problem.
AI is the most effective tool ever built for eliminating accidental complexity. It's proving Brooks right in the way he predicted.
What AI eliminates
AI generates boilerplate instantly. HTTP handlers, database CRUD operations, serialization code, test scaffolding, configuration files, Dockerfile templates, CI pipeline definitions. Every piece of accidental complexity that developers spend hours writing — AI produces in seconds.
A developer who spends 40% of their time on boilerplate and 60% on essential logic now spends 5% on boilerplate and has 95% of their time for essential logic. The time savings and productivity improvement is real. The 10x feeling is real for the accidental part.
AI eliminates accidental complexity. The problem happens after the accidental complexity is gone.
What remains after the accidental is removed
When the boilerplate is generated in seconds, the developer reaches the essential complexity faster. The business logic, domain rules, edge cases etc. The relationships between entities that don't map clearly to database tables. The race conditions that only appear under specific ordering. The authorization rules that depend on organizational hierarchy, delegation chains, and temporal state.
This is the complexity Brooks said was irreducible. AI can't eliminate it because it's not a syntax problem. It's a problem about the correspondence between the software and the real world. The AI can generate a function that handles a business rule. But it can't know whether the business rule is correct. Because correct is defined by the domain.
The old workflow had a natural pacing mechanism: the time spent writing boilerplate was time the developer unconsciously spent thinking about the domain. The struggle with syntax gave the developer time to notice: "wait, this business rule doesn't make sense." The boilerplate was annoying, but it was also friction that slowed the developer down enough to think.
AI removed the friction. The developer goes from prompt to working code in minutes. The essential complexity is still there. But the developer didn't notice it because they never slowed down enough to see it.
The illusion of completion
The most dangerous consequence: AI-generated code looks complete. The boilerplate and the error handling is there. The tests pass. The developer reviews it and thinks: "this is done."
But done means the accidental complexity is resolved. The essential complexity — the domain logic, the edge cases, the invariants was never examined. The code handles the common cases correctly (because the AI was trained on common patterns) and fails on the specific cases that make this particular domain unique (because those weren't in the training data).
The failure surfaces weeks or months later, when a customer hits an edge case the AI never considered. The developer debugging the issue finds code they didn't write, implementing a business rule they didn't design, handling a case they didn't think about. They can't fix it because they don't understand the essential complexity. The AI hid it under a layer of perfect-looking accidental resolution.
The reviewer's dilemma
This creates an asymmetry that compounds the problem. It is harder to review 100 lines of AI-generated code than to write 50 lines yourself.
When a developer writes code, they build a mental model of the domain as they go. They encounter edge cases during implementation, make decisions about how to handle them, and carry the reasoning forward. The code and the understanding are built together.
When a developer reviews AI-generated code, the code arrives pre-formed with no reasoning trail. The reviewer must reverse-engineer the domain model from the implementation — figure out which edge cases were handled, which were missed, and whether the ones that were handled were handled correctly. This is harder than building the model yourself, because the reviewer is reconstructing intent from an artifact that has no intent.
The result: teams that measure productivity by lines of code shipped or pull requests merged see massive throughput gains. Teams that measure productivity by defects avoided or domain coverage verified see the same essential-complexity bottleneck, now arriving faster and in larger batches.
Throughput is not progress.
Where the essential complexity lives
Brooks identified four properties that make essential complexity irreducible. AI interacts with each one differently.
Complexity. The sheer number of states the system can be in. A system with ten interacting components has more possible states than a developer can enumerate. Brooks called this the fundamental property — the one that makes all the others worse.
AI multiplies this property directly. A developer writing code by hand produces hundreds of lines per day. Each line is a decision point they consciously made. An AI-assisted developer ships thousands of lines per day. Each line is a decision point someone needs to understand but nobody consciously made. The number of states in the system grows with the code, but the developer's ability to map those states in their head remains constant. More code, same brain. The state space grows. The developer's model of it doesn't.
Conformity. The software must conform to the real world — to regulations, to existing systems, to human expectations. These conformity requirements can't be derived from code patterns. They must be understood from the domain.
Conformity is the hardest of Brooks's four properties, and the cloud makes it visible. The cloud is a conformity engine. You must conform to every service that imposes a model. AWS's IAM evaluation logic, GCP's networking model, Azure's RBAC hierarchy. AI is fluent in the syntax of these APIs but silent on the security implications of how they interact with your internal compliance rules.
AI that generates IAM policies based on training patterns doesn't understand IAM evaluation semantics. It pattern-matches on policies that appeared in its training data. The difference matters when two policies interact in ways the training data never combined, when a new action namespace silently changes the meaning of an existing wildcard, or when the specific compliance requirement falls between two regulatory interpretations.
Changeability. The requirements change. Because the real world changes. A pricing model that was correct last quarter is wrong this quarter. An IAM policy that was secure last week grants OAuth agent authorization this week because the provider added new actions to the namespace. The AI-generated code implements last quarter's model perfectly. The developer who needs to update it for this quarter's model doesn't understand the old model (they didn't write it) and can't safely modify it (they don't know which assumptions are embedded in the implementation).
Invisibility. Software is invisible. There's no spatial representation that shows the full structure. The developer must hold the structure in their head. As Peter Naur argued in "Programming as Theory Building," the developer must build a theory of the program: a mental model of how the solution maps to the problem, what each piece does and why, how the parts relate to each other and to the domain.
Naur's insight compounds Brooks's. If programming is building a theory in the developer's head, then AI-generated code is theory-less code. The artifact exists but the theory behind it was never constructed. No one holds the mental model of why the code is shaped the way it is, which domain constraints it satisfies, or which assumptions would break if the requirements changed. The code is doubly invisible: the developer doesn't have the theory, and the code's structure follows patterns from training data rather than patterns from the domain. The structure in the code doesn't match the structure of the problem. It matches the structure of similar code the AI has seen.
This makes AI-generated code uniquely fragile under change. Human-written code degrades when the developer who understood it leaves the team — the theory walks out the door. AI-generated code starts without a theory. There is no door for it to walk out of. The understanding was never there.
What this means for AI-assisted development
Brooks's insight predicts what DORA's 2025 data measured: organizations saw roughly a 10% improvement in actual code shipped to production. Higher throughput alongside higher instability — more code shipped, more rollbacks.
The accidental complexity was eliminated (massive time savings). The essential complexity remained (same number of domain bugs). The net improvement was modest. Because the time was always going to be spent in essential complexity, and AI doesn't reduce it.
The teams that will succeed are the ones that use the time saved on accidental complexity to invest more time in essential complexity — in domain modeling, property definition, invariant specification, understanding the business rules deeply enough to verify that the AI's output is correct.
The teams that will fail are the ones that use the time savings to generate more code, features, endpoints, services without investing in understanding the domain. They'll hit Brooks's wall later, with a larger codebase, less understanding, and more surface area for essential-complexity failures.
The specification as essential complexity management
Specifications — type signatures, API contracts, database schemas, property definitions are the tools for managing essential complexity. They make the domain rules explicit instead of leaving them implicit in the code.
A type signature that says func ProcessOrder(order Order) (Receipt, error) captures essential complexity: an order produces a receipt or an error. Not a maybe-receipt, a silent failure or a partial result. The type system enforces this at compile time regardless of whether the implementation was written by a human or an AI.
A property that says "no order can have a negative total after discounts are applied" captures a domain invariant. AI might generate discount logic that produces negative totals for specific discount combinations. The property catches it — mechanically, deterministically, on every change. Because the essential complexity was made explicit as a verifiable statement.
AI eliminates accidental complexity. Specifications manage essential complexity. Both are needed. AI without specifications produces code that looks correct but embeds unexamined domain assumptions. Specifications without AI require humans to write all the boilerplate. Together: the AI handles the syntax, the specifications handle the semantics.
Brooks said there's no silver bullet. He was right. AI eliminates the accidental complexity that was never the hard part. The hard part remains — irreducible, essential, and now hidden under a layer of perfectly formatted code that looks like it's finished.
In cloud security, the essential complexity is the domain invariant: "no privilege escalation path exists through any combination of roles, policies, and trust relationships." The accidental complexity is writing the checks — the YAML, the CEL predicates, the test fixtures. Stave handles the accidental complexity (3,000+ controls, mechanically evaluated). The essential complexity, knowing which properties to verify remains a human judgment that no AI can replace. Brooks, 40 years later is still right.
Top comments (0)