Contract Driven Engineering

Contract Driven Engineering

TL;DR: In the post Agentic Coding world, what are we as "clanker wranglers" doing exactly? “Contract Driven Engineering” (CDE) is a name I like that I happened to work with the Deft team to come up with. Contracts are the durable IP — and specs are one type of contract. So are interfaces, standards, and boundary maps. Contracts are the metal structure. Code is kindling.

What's in a name?

There’s a debate happening in the Deft project about what to call the practice of engineering software from durable artifacts downward.

The candidates:

  • Contract Engineering Framework — accurate, descriptive, but sounds like a tool, not a methodology
  • Contract Driven Engineering (CDE) — sounds like a methodology (TDD, BDD, DDD), because it is one
  • Spec-Driven Development (SDD) — names the methodology after one type of contract while ignoring the rest
  • Spec-driven framework for contract engineering — the synthesis position, which is sort of right but doesn’t fit on a sticker

I’m going with CDE. Here’s why.

The Hierarchy Problem

There’s a framing making the rounds that looks like this:

Spec (intent — the durable IP)
  → Contracts (boundaries, APIs, standards — a derived middle layer)
    → Code (the most ephemeral artifact)

Jason Goecke’s excellent piece on Phoenix Architecture and Spec Driven Development makes this case, building on Chad Fowler’s concept of Phoenix Architecture — systems designed to burn and be reborn without losing identity. Fowler puts it beautifully:

“The most durable systems of the AI era will be built from code that is meant to die.”

Goecke extends this:

“The ashes have intent. They’re meant to be farmed into the next iteration.”

I agree with the Phoenix Architecture philosophy completely. But I think the hierarchy above has the taxonomy wrong. It treats specs and contracts as separate layers, with specs on top. In reality, a spec is a contract. It’s one kind of contract. The hierarchy isn’t spec → contract → code. It’s:

Contracts (the durable IP)
  ├── Specifications — what we're building and why
  ├── Interface contracts — APIs, CLIs, TUIs, GUIs, protocol interfaces
  ├── Standards contracts — language, database, error format, naming conventions
  ├── Boundary contracts — module ownership, data domains, integration points
  └── Code (the most ephemeral artifact — a derived output of all the above)

Specs don’t sit above contracts. Specs sit inside contracts. They’re the subset that encodes intent — but intent without interfaces is a wish, and interfaces without standards are chaos.

Why Specs Alone Aren’t Enough

Frederick Brooks warned us 50 years ago in The Mythical Man-Month:

“The hardest single part of building a software system is deciding precisely what to build.”

He was right. But “what to build” isn’t just a spec. It’s the spec plus every interface the system touches, plus every standard the team agrees to follow, plus every boundary between components. Deciding “what to build” means deciding how every surface of the system behaves — not just the intent behind it.

Consider: a spec says “users can search their order history.” That’s intent. But the contract surface of that feature includes:

  • The API: GET /orders?q=<term>&page=<n> returning paginated JSON:API responses
  • The CLI: myapp orders search "blue widget" --limit 10 --json
  • The UI: a search bar with autocomplete, debounced at 300ms, showing 20 results per page
  • The standards: PostgreSQL full-text search, UTC timestamps, RFC 7807 error responses
  • The boundaries: OrderService owns search, AuthService owns permission checks, they communicate via domain events

The spec is one sentence. The contracts are a page. The code is a thousand lines. And when the code burns — and it will — you don’t regenerate from the spec alone. You regenerate from the entire contract surface. The spec tells you what. The full contract set tells you how it connects to everything else.

SDD Names the Methodology After a Subset

Every AI coding tool claims to do spec-driven development. Claude Code does it. Cursor does it. Copilot sort of does it. GitHub Speckit literally has “spec” in the name. BMAD, GSD, every framework with a README longer than its source code — they all claim to start from specs.

The problem isn’t just that SDD is undifferentiated. It’s that it’s incomplete. Naming the methodology after specifications is like naming architecture after blueprints while ignoring building codes, zoning laws, and structural engineering standards. The blueprint matters. But the blueprint alone doesn’t keep the building standing.

Bertrand Meyer understood this when he introduced Design by Contract in the 1980s for his Eiffel programming language:

“The central idea of DbC is a metaphor on how elements of a software system collaborate with each other on the basis of mutual obligations and benefits.”

Mutual obligations. Not just intent. Not just what you want to build. The agreements between the parts about how they’ll behave at their boundaries. Meyer was talking about preconditions, postconditions, and invariants at the function level. CDE takes the same philosophical foundation and elevates it to the architectural level — every surface, every interface, every standard, every boundary.

The Translation Layer Is Where Projects Die

Here’s the dirty secret of AI-assisted development in 2026: the spec-to-code gap isn’t a gap. It’s a canyon. And most tools try to jump it in one leap.

You write a spec. You feed it to an AI. The AI generates code. The code is… fine. It works. It passes the tests you thought to write. And then six weeks later, you realize:

  • The API surface makes no sense
  • Module boundaries were drawn by vibes
  • The database schema is a reflection of the LLM’s training data, not your domain
  • Every integration point is a bespoke snowflake

Martin Fowler called this the “big ball of mud” — though he was riffing on Brian Foote and Joseph Yoder’s 1997 paper that first named it:

“A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle.”

AI didn’t invent the big ball of mud. AI just made it possible to generate one in an afternoon instead of over three years. What went wrong? The spec was fine. The rest of the contracts didn’t exist.

Contracts Are the Whole Surface

I wrote about this in 100 Future Fortnights:

“Interfaces are contracts. They’re the points of trust between humans and software, between components and components, between your system and the world.”

And I meant all interfaces:

  • APIs — the endpoints your customers build against
  • CLIs — the commands your DevOps team memorizes
  • TUIs — the terminal interfaces your power users love
  • UIs — the screens your customers navigate by muscle memory
  • PIs — Protocol Interfaces — the wire formats that everything rides on

Each of these is a contract. Each is a promise about how a surface behaves. And a spec — the statement of intent, the “what and why” — is also a contract. It’s a promise to stakeholders about what the system will do.

Sam Newman, author of Building Microservices, put it well:

“The golden rule: can you make a change to a service and deploy it by itself without changing anything else?”

That’s a contract question. Not a spec question. Not an interface question. A contract question — because “contract” is the word that encompasses every durable promise your system makes, from stakeholder intent to wire format.

Why “Driven” Matters

Kent Beck — the person who gave us Test-Driven Development — framed the whole practice as a paradox:

“Clean code that works — now. This is the seeming contradiction that lies behind much of the pain of programming. Test-driven development replies to this contradiction with a paradox — test the program before you write it.”

TDD isn’t called “Test-Oriented Development” or “Test-Aware Engineering.” It’s Test-Driven. The tests come first. They drive the implementation. You don’t write code and then check if tests exist — you write the test, watch it fail, and let the failure pull the code into existence.

CDE works the same way.

Before you write a line of implementation:

  1. Define the spec contract — what are we building and why?
  2. Define the interface contracts — APIs, CLIs, UIs, protocol surfaces
  3. Define the standards contracts — language, database, error formats, naming conventions
  4. Define the boundary contracts — module ownership, data domains, integration points
  5. Validate — do the contracts compose? Are they internally consistent? Do the interfaces satisfy the spec? Do the standards support the interfaces?
  6. Then — and only then — generate the code

The contracts drive the implementation. All of them. Not just the spec. The full contract surface comes first, is validated independently, and the code is derived from it.

Eric Evans, author of Domain-Driven Design, identified the same structural need from a different angle:

“When complexity gets out of hand, developers can no longer understand the software well enough to change or extend it easily and safely.”

Evans’ Bounded Contexts are contracts by another name — explicit boundaries where the rules of one domain end and another begins. CDE makes these boundaries first-class artifacts rather than implied conventions.

This is what Deft’s contract hierarchy actually does. It forces you to define standards before APIs, APIs before module specs, module specs before implementation. Each layer constrains the next. Nothing gets generated until the contracts are solid.

Respectfully Dis-engineering

My friend and Cambiar co-founder Jason Goecke argues that contracts are a derived middle layer — a subset of the spec, not the other way around:

“If you go the route of Contract Engineering, you are describing but a subset that isn’t actually that durable, nor should it be.”

I think he has the containment relationship inverted. A spec doesn’t contain contracts. Contracts contain specs. The spec is one contract among many — the one that encodes intent. But intent without interface definitions is just a wish list. Intent without standards is ambiguity. Intent without boundary maps is a system that can’t be built by more than one person (or agent).

When Goecke says “the ashes have intent because the spec encodes that intent,” I’d reframe it: the ashes have structure because the contracts encode that structure. Intent is necessary but not sufficient. When your codebase burns and you regenerate from the ashes, you need the spec (what and why), but you also need the interface contracts (how it faces the world), the standards contracts (what tools and conventions), and the boundary contracts (where one thing ends and another begins).

The spec is the soul. The contracts are the skeleton. You need both to stand back up.

Stewart Brand gave us the concept of shearing layers in How Buildings Learn — the idea that buildings have components that change at radically different rates:

“A building is not something you finish. A building is something you start.”

The site lasts centuries. The structure lasts decades. The skin lasts years. The services last months. The space plan changes weekly. Software has the same layers. But the “structure” isn’t just the spec — it’s the full contract surface: specs, interfaces, standards, and boundaries. Together, they’re the skeleton that survives when the code burns.

What This Looks Like in Practice

In a CDE workflow:

Hour 0: You interview the stakeholder. You write the spec contract. “We need a service that processes incoming webhooks from Stripe, validates them, and updates our billing state.”

Hour 1: You derive the rest of the contracts:

  • Interface contract (API): POST /webhooks/stripe, accepts Stripe event payloads, returns 200/400/500
  • Interface contract (CLI): billing webhooks replay <event-id> for debugging
  • Boundary contract: WebhookProcessor owns validation, BillingService owns state changes, they communicate via domain events
  • Standards contract: Node.js, PostgreSQL, RFC 7807 errors, structured logging, UTC timestamps
  • Integration contract: Stripe webhook signature verification, idempotency keys, retry handling

Hour 2: You validate the contracts against each other. Does the API interface align with the boundaries? Do the standards support the integration requirements? Does the spec contract actually describe what the interfaces deliver? Are there gaps?

Hour 3: You hand the full contract set to an AI agent and say “implement this.” The code that comes back isn’t a guess — it’s a derivation. And when it inevitably needs to be rewritten (next month, next week, tomorrow), the contracts survive. All of them. The code burns. The contracts endure.

This is Goecke’s Phoenix Architecture in practice:

“When code becomes cheap to generate, this calculus inverts completely… The startup advantage — building on today’s state of the art without attachment to decisions made in the distant past — becomes widely available.”

The difference: when CDE regenerates, it regenerates from the full contract surface, not just the spec.

The Intellectual Lineage

CDE doesn’t appear out of nowhere. It stands on the shoulders of decades of thinking about how to make software that survives contact with reality:

CDE synthesizes these into a single practice: contracts — specs, interfaces, standards, and boundaries — are the durable IP. Code is a renewable output.

Jeff Bezos understood this intuitively when he issued his famous API mandate at Amazon in 2002:

“All teams will henceforth expose their data and functionality through service interfaces… Anyone who doesn’t do this will be fired.”

The mandate wasn’t about specs. It wasn’t about implementation. It was about contracts — the enforceable promises between teams. Bezos didn’t say “write good specs” or “write clean code.” He said: define your interfaces and honor them. That’s CDE in four words.

Phoenix Architecture, Meet CDE

Goecke’s Phoenix Architecture concept — that code should burn and be reborn from durable artifacts — is the philosophical foundation for CDE. They’re not competing ideas. They’re complementary.

Fowler frames the discipline required:

“Regenerative software requires more discipline than maintenance-oriented software, not less. You need specifications rigorous enough to regenerate from. Vague specs produce random implementations.”

I’d add: you need contracts rigorous enough to regenerate from. Vague specs produce random implementations. Missing interface contracts produce implementations that don’t compose. Missing standards produce implementations that fight each other. Missing boundary contracts produce implementations where everything depends on everything.

Phoenix Architecture tells you what to believe: implementations are disposable, durable artifacts survive.

CDE tells you what to do: define your full contract surface before code — specs, interfaces, standards, and boundaries. When the code burns, regenerate from the contracts. All of them.

Or as Doug McIlroy, the father of Unix pipes, put it decades before any of us were arguing about this:

“Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new features.”

Build afresh. From the contracts. Every time.

The Bottom Line

We don’t need a bunch of new acronyms. But we need this one.

AI has made code generation trivially cheap. That’s wonderful. It’s also dangerous — because cheap generation without structural discipline produces cheap results. Fast code that’s wrong in ways you won’t discover until production.

Tony Hoare — the computer scientist who gave us quicksort, null references, and Hoare logic (the formal verification system that Design by Contract is built on) — said it best:

“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.”

CDE is the discipline of simplicity at every boundary. It says: before you generate, define your contracts — all of them. Specs, interfaces, standards, and boundaries. And when the code inevitably burns — and it will, faster than ever now — you don’t start from scratch. You start from the contracts.

Contracts are the dogma. Code is kindling.

That’s Contract Driven Engineering.


This post is part of an ongoing discussion in the Deft Directive project. Deft is an open-source AI-assisted development framework that implements CDE. The debate includes contributions from MScottAdams on methodology naming and Jason Goecke on the primacy of specs. If you’re tired of watching AI generate beautiful code that doesn’t compose, come argue with us.