SR.

Domain-Driven Design matters more when the agent writes the code

Back to blog

Domain-Driven Design matters more when the agent writes the code

Sep 30, 2026·10 min read·
DDDAISoftware Architecture

Domain-Driven Design has spent two decades being sold as a bag of code patterns. Aggregates, repositories, value objects, layers. Those are exactly the parts an agent will now generate for you in seconds, so it's fair to ask whether any of it still matters.

The patterns were never the point. The hard part was always understanding the domain well enough to say what the software should do, and generated code doesn't touch that. So the ideas in DDD that were never about code matter more now rather than less: how a team arrives at a shared understanding, and what it agrees to call things. This is about systems maintained over months or years, where teams struggle. Not pet projects, and not CRUDs.

The bottleneck moved

The cheapest way to see it is a cloud bill.

I had a personal Go project that cost more to run than I wanted, so I set an agent on it. That looked like a good job for one; the target is a number and you can watch it move. I asked it to find where the service used the most memory and bring it down.

It did exactly that. It found the heaviest allocations, cut them down, and my bill dropped by a dollar a month.

Smółka reports the same figure from the same mistake, which is the part that actually bothered me.

What I asked for was less memory. What I wanted was a smaller bill. Nobody had written down that those were two different things, least of all me.

The failure there isn't the model and not the tooling. You name a metric, the agent optimizes that metric, and it does the job well. The metric was a proxy for what you actually wanted, nobody wrote that down, and so the number that mattered barely moves.

That gap, between what you asked for and what you meant, is what DDD has been about since 2003. Eric Evans published Domain-Driven Design more than two decades ago and the main message has held: the hard part of software engineering is understanding the problem domain and modeling it well in code. He was specific about where technical talent goes instead.

Instead, the technical talent goes to work on elaborate frameworks, trying to solve domain problems with technology. Learning about and modeling the domain is left to others.

Eric Evans, Domain-Driven Design

Implementation details really are getting cheaper. You can be productive without deep knowledge of a language or a framework, moving between stacks is easier, and the good coding agents generate decent code quickly.

None of that touches the other half.

Making the left column cheap doesn't make the right column cheaper. It just promotes the right column to the constraint.

The escape hatch Evans described is still open, only relabeled. Instead of elaborate frameworks we have model benchmarks and agent setups, tuned to generate better code with less effort. It's the same move, solving domain problems with technology, and this time the executives believe it too.

Which leaves one small thing to figure out: how the thing should actually work.

Knowledge crunching

Model-driven design means distilling how the domain works into a model expressed in code. The model itself is abstract. Documents, diagrams, and code are all simplifications of it, and an accurate one comes from switching between design and implementation and applying what you learned, over and over.

DDD calls this knowledge crunching. It needs domain experts, who know how the business works, and engineers, who know how to build software. Event Storming is one format for it: developers and stakeholders mapping out the business with sticky notes.

It's hard work, so handing it off is tempting. Agents are good at research and analysis, and they can read your documents, chats, and code. It looks like they could build the model and then implement it too.

The value of the work is that the team understands the domain afterward. That understanding sits in people. A document is only a picture of it, which is why an agent asked for the document hands back an impressive artifact nobody reads.

Writing up how something could possibly work was never the hard part. Projects fail for other reasons:

  1. Engineers work on the wrong thing.
  2. No one knows what needs to be done in the first place.
  3. The team tries to build everything at once.

None of those improve when the code arrives faster. If anything they get worse, because the wrong thing now ships in an afternoon.

Design first

Writing code has always been easier than reading it, and an agent that single-shots a whole feature makes the gap extreme. The thing works and you've no idea what is going on under the hood.

So review becomes the place everything jams. It isn't a new problem and it even feels familiar: this is the lone-wolf developer who builds a complete feature and drops a massive PR on you. You know nothing about the design, there are gaps nobody considered, and reviewing it is painful.

The fix isn't a better prompt. Design and discuss the solution as a team before anyone sits down to code. Domain parts first, then the technical side. This needs no complete spec and no agreement on every detail; sticky notes and a whiteboard are enough.

Skipping the design doesn't remove it. It relocates it to after the first review, once a cycle of code has already been paid for.

The planning block is highlighted in both rows. Coding first doesn't skip planning, it reaches it after a full code-and-review cycle and then repeats both. The widths carry the claim, not measured durations.

Code review should confirm that the implementation is correct, not open the question of whether the approach makes sense at all. Reviews are asynchronous, so a disagreement found in a PR comment turns into rounds of comments across days.

Designing first also makes the agent better. More high-quality context going in means more accurate output, and the more the team already knows, the easier the review, even when every line is generated.

Names

Back to the cloud bill. The goal stayed in someone's head and only the metric reached the prompt, so the agent optimized the proxy it was handed. The same thing happens between people, which is the part worth noticing. The practices that make you understandable to colleagues turn out to be the ones that make you understandable to agents.

DDD starts with Ubiquitous Language: the same words across teams and in code. Messy names are the default. Engineers reach for technical terms that drift from what the rest of the company says, and feeding an agent your documents doesn't fix it, because it still has to make sense of whatever language is in them.

So decide what to call things during knowledge crunching. Pick a name you already use, or invent a more accurate one, then use it in documents, in speech, and in code.

What gets agreed isn't one word. It's three: the thing, the action, and the thing that happened. Competing nouns and competing commands collapse into Customer, Onboard Customer, and Customer onboarded. Agree the noun but leave the event called User Created, and the drift survives in the part of the system agents read most eagerly.

Vague names cost real effort:

Add user to CRM and support after it's created

The same request in the agreed names:

Once the user signs up on the website, asynchronously create: 1) a customer entry in the CRM, 2) a profile in the support system

In a bigger system those names stop being universal, and DDD calls each area a Bounded Context. Your customer is a profile in support and a user in e-commerce. Keep names consistent within a context rather than forcing one set across the whole project.

One person, four contexts, and in each one a name for the thing plus a name for what happened to it. The heavy arrows are the risk: unless something says these are separate on purpose, an agent will try to unify them.

Keep the domain language where the agents read it. Markdown files next to the code are a good start, since nothing has to be integrated to fetch them.

The other side

The case against all of this is short. You won't need the experience, because the models will handle it, and leaning on them could simply become normal.

Two narratives sit behind that. The first is that anyone can now generate a clone of a well-known app, which was startling at first and is not interesting for long, since there were already too many half-baked apps. The second is that experienced engineers can now build more complex things: replacing expensive third-party software with an in-house version, and trusting it because they already know the domain.

Both assume somebody can still tell whether the output is right, and that's the whole objection. The only thing that lets you judge a plan is having built plans like it before. You don't get that by reading what an agent produced. You get it by doing the work at least once yourself.

The analogy that fits is reading a book against reading a summary of it. Reading makes you sit with the topic for hours, building a model and wiring it to what you already know. You understand the topic, instead of reading a few sentences you forget when the tab closes.

Nobody knows the best practices yet, which makes it a good time to experiment. The thing that would settle the argument is an agent that holds the domain instead of the repository, one that could have looked at the cloud bill and said the metric was the wrong target. I haven't seen it yet.

Sources

DDDAISoftware Architecture