Part I

The Shift

Chapter 1

The Staircase

In 1972, at Bell Telephone Laboratories in Murray Hill, New Jersey, a programmer named Dennis Ritchie wanted to write a text editor.

The only language available was assembly — a notation so low-level that before Ritchie could process a single keystroke, he first had to write code to manage memory allocation, handle hardware interrupts, and control the terminal display. The text editor was the goal. The infrastructure was the obstacle.

So Ritchie did something that changed computing: he created the C programming language. C introduced procedures — named blocks of code you could call by name, pass data into, and get results from. Instead of writing fifty lines of assembly to display text on screen, you could write display_line(text, row) and the procedure handled the rest.

This seems obvious today. In 1972, it was revolutionary. It was the first answer to a question that software engineering has been asking — and re-answering — every decade since:

What is the right-sized piece to build with?

Each step solved the previous era's pain. Each introduced new pain. The question mark is the subject of this book.
Each step solved the previous era's pain. Each introduced new pain. The question mark is the subject of this book.

Five answers in fifty years. Procedures in the 1970s. Objects in the 1990s. Services in the 2010s. Agents in 2025. Each answer lasted about a decade. Each felt permanent. None was.

Here's what most engineers miss about this staircase. Every transition looks like it was driven by new technology — a better language, a faster protocol, a smarter framework. It wasn't. Every transition was driven by composition pain — the inability to build large systems from the current unit without everything breaking.

Create a sophisticated, minimalist typographic illustration on a warm cream background (#faf8f5) featuring precise, elegant text placement. The central focal point is the large, bold word 'PAIN' in a striking red accent color (#c4392a), followed by a greater-than symbol '>' and the word 'technology' in dark charcoal (#1a1917) with a distinct horizontal strikethrough line crossing it out. Above this, include the small, widely-spaced dark charcoal text 'EVERY TRANSITION WAS DRIVEN BY', and below it 'THE LAW OF SOFTWARE EVOLUTION'. The design should feel like a premium $50 technical book—authoritative but approachable—improving upon the original with flawless typographic hierarchy, sharper contrast, and generous editorial whitespace.
Create a sophisticated, minimalist typographic illustration on a warm cream background (#faf8f5) featuring precise, elegant text placement. The central focal point is the large, bold word 'PAIN' in a striking red accent color (#c4392a), followed by a greater-than symbol '>' and the word 'technology' in dark charcoal (#1a1917) with a distinct horizontal strikethrough line crossing it out. Above this, include the small, widely-spaced dark charcoal text 'EVERY TRANSITION WAS DRIVEN BY', and below it 'THE LAW OF SOFTWARE EVOLUTION'. The design should feel like a premium $50 technical book—authoritative but approachable—improving upon the original with flawless typographic hierarchy, sharper contrast, and generous editorial whitespace.

Procedures died because every function in a program shared the same global state. Change one variable inside calculate_tax(), and three other functions across the codebase — generate_invoice(), process_refund(), audit_trail() — silently broke. The pain was so widespread that in October 1968, forty of the world's top computer scientists — Edsger Dijkstra, Tony Hoare, Alan Perlis, Peter Naur — gathered in Garmisch, Germany for the NATO Software Engineering Conference. They gave the problem a name: the "software crisis."4NATO Software Engineering Conference, Garmisch, Oct 1968. Report PDF

Objects solved the global state problem by encapsulating data inside classes — each object owned its state, and you interacted through methods, not raw variables. But objects introduced a new pain: deep inheritance hierarchies. A PremiumCustomer extending Customer extending User extending Entity meant changing Entity could break every class in the chain. "Favor composition over inheritance" became the battle cry of the Gang of Four in 1994, after a decade of burned developers.

Services solved the deployment problem that objects couldn't: independent teams deploying, scaling, and updating their code without coordinating with every other team. But services introduced the "distributed monolith" — ten microservices that were technically in separate repos but practically coupled through shared databases, synchronous calls, and undocumented API dependencies. Change the user service, break the billing service. Sound familiar?

The distributed monolith: seven "independent" services, twelve hidden dependencies.

Each step on the staircase solved the composition pain of the previous era. And each introduced a new kind of pain that nobody anticipated until it was too late.

Agents are not exempt from this pattern.

Agents solve the integration pain that services couldn't. Instead of writing custom code for every workflow — "if this webhook fires, call that API, transform the response, write to this database" — you describe the goal in natural language and the agent figures out the steps. This is genuinely powerful. It eliminates thousands of lines of glue code.

But agents introduce a composition problem that is fundamentally different from anything software engineering has seen before. Not harder. Different in kind. The next two chapters explain what that difference is and why it changes everything about how you build.

A skimmer who sees only this image understands the chapter.
A skimmer who sees only this image understands the chapter.
29%
of software projects succeed — the rest fail at composition5Standish Group CHAOS Reports, 1994-present. Standish Group
Diagnostic — Composition Pain Locator

Before you can solve the agent composition problem, you need to identify which composition pain you're currently hitting. The staircase isn't theoretical — your codebase is sitting on one of these steps right now. Most teams don't know which one until something breaks.

// LOCATE YOUR POSITION

current_unit =

composition_pain =

pain_frequency = daily | weekly | every_deploy

next_step_solves =

// If pain_frequency == "every_deploy", you've outgrown your unit.

← Previous The Deleted Database An AI agent reasoned past a safety constraint, deleted everything, then lied about it.