AI Generated Your Code, But Can It Generate Your Architecture?
Eric Evans published Domain-Driven Design in 2003. The tech world has since cycled through microservices mania, event-driven everything, and now, AI coding agents that can single-shot an entire feature in one prompt. Yet the book’s core message hasn’t just survived. It’s becoming the dividing line between teams that harness AI effectively and teams that drown in machine-generated mediocrity.
Here’s the uncomfortable truth: AI doesn’t eliminate the hard parts of software engineering. It amplifies them.
The 2003 Problem That 2026 Made Worse
Evans warned about something prescient two decades ago:
“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. Complexity in the heart of software has to be tackled head-on. To do otherwise is to risk irrelevance.”
Read that again. Now swap “elaborate frameworks” for “AI agent configurations” and you’ve got a perfect description of 2026 engineering culture. Teams obsess over model benchmarks, prompt engineering, and agentic setups, all while hoping someone else figures out what the software should actually do.
The “revolutionary” AI workflow has mostly revolutionized how quickly we can generate code that solves the wrong problem. As one developer put it on Reddit, DDD might be overkill for many domains, and infrastructure concerns like query optimization and latency dominate their daily work. That’s a fair criticism, but it misses the point entirely when AI is generating 80% of your codebase.
Why Correct Code Is No Longer Enough
Here’s what’s changed: AI coding tools generate correct code. Not good code, not coherent code, correct code. It compiles, passes tests, and handles edge cases you didn’t even think to specify. This creates a dangerous illusion of progress.
In a recent experiment, engineer Miłosz Smółka asked an AI agent to reduce cloud costs. The agent dutifully analyzed memory usage across a Go service and optimized it, saving a grand total of $1/month on RAM. The agent did exactly what was asked. It just didn’t understand the actual goal was cost reduction, not memory optimization.
This failure mode scales exponentially with codebase size. When an AI generates 10,000 lines of locally-correct code across your system, you end up with what architects call a “distributed big ball of mud”, except now it’s generated by a machine that was very confident about every wrong assumption it made.

Writing code isn’t the bottleneck anymore. Reading it is, especially when that code was generated by an agent that had no mental model of your domain.
The Domain Model Isn’t an Artifact. It’s the Product.
The most dangerous trend in AI-assisted development is treating domain modeling as a documentation exercise. Teams use AI to generate comprehensive specs, don’t read them, then feed those specs to coding agents. The result is a beautiful paper trail and a system that doesn’t work.
Here’s what the Three Dots Labs analysis correctly identifies: the value of domain modeling is the understanding your team builds by doing it. An AI-generated wall of text doesn’t help anyone. The knowledge crunching, the messy, iterative process of domain experts and engineers hammering out a shared mental model, is the actual deliverable.

Skipping this step means your team learns about the architecture for the first time during code review. With AI-generated code, that review process becomes exponentially harder. You’re not just reviewing logic, you’re reverse-engineering an agent’s implicit assumptions about customer onboarding, billing cycles, or inventory management.
Ubiquitous Language: Your New Prompt Engineering Strategy
Domain-Driven Design’s concept of Ubiquitous Language has transformed from a nice-to-have to a competitive advantage in the AI era. Here’s why:
AI agents have access to your entire repository. They search for patterns, names, and conventions across thousands of files. When your codebase calls the same concept “User” in e-commerce, “Customer” in CRM, “Account” in accounting, and “Profile” in support, agents will make one of two mistakes:
- They’ll unify everything into a generic mega-entity that serves no context well
- They’ll create inconsistent implementations that mirror the chaos of your naming

The bounded context concept becomes critical here. You need precise, well-defined names within each context, not a unified model across everything. This isn’t just about code clarity. It’s about prompt clarity.
Consider these two prompts for the same task:
Vague: “Add user to CRM and support after it’s created”
Precise: “Once the user signs up on the website, asynchronously create: 1) a customer entry in the CRM, 2) a profile in the support system”
The second prompt produces dramatically better results because it leverages precise domain language. It tells the agent which contexts are involved and what the entity is called in each. This is formalizing interactions with AI through specifications, using domain language as the type system for your prompts.
Spec-Driven Development: DDD’s Operational Cousin
Domain-Driven Design has always been somewhat abstract, a philosophy more than a methodology. That’s changing as teams adopt Spec-Driven Development to bridge the gap between domain modeling and AI execution.
Spec-Driven Development (SDD) inverts the typical AI coding workflow:
| Vibe Coding | Spec-Driven Development |
|---|---|
| Describe → Generate → Test → Iterate | Specify → Review → Generate → Validate |
| AI makes design decisions | Humans make design decisions |
| Specs exist in chat history | Specs are versioned artifacts |
| Accept if it works | Accept if it meets spec |
The key insight: specifications become executable artifacts that both humans and AI can consume. AWS’s Kiro IDE implements this natively with a three-phase workflow: Requirements → Design → Tasks. Code generation comes last, after humans have reviewed and approved each phase.
This isn’t just process theater. When Delta Airlines adopted spec-driven approaches, they achieved a 1,948% growth in AI tool adoption within six months, with product owners who had no coding experience generating production-ready prototypes from specifications.
The Spec-Driven Development Handbook frames this perfectly: “Vibe coding optimizes for the first iteration. Spec-driven development optimizes for the next hundred.”
The Proof: A Subscription Management Case Study
Let’s make this concrete. Consider the deceptively simple requirement: “Allow users to upgrade and downgrade subscription plans.”
An AI agent asked to implement this directly will generate something that technically works. It’ll handle the happy path, hitting an API endpoint, updating a database record, returning success. But it will miss the domain complexity that makes this feature production-ready:
- Prorated billing: What happens when a user upgrades 15 days into a 30-day cycle?
- Downgrade timing: Should features be removed immediately, or at the next renewal?
- Payment failures: What if plan changes during a failed authorization?
- Edge cases: Upgrade during a failed payment state? Downgrade on renewal day?
Here’s the exact specification structure a spec-driven team would create before allowing any code generation:
| Feature: Subscription plan changes |
|---|
| Problem: Users need to move between subscription tiers without contacting support. |
| Goals: Allow customers to upgrade plans at any time. Allow customers to schedule downgrades. Preserve billing accuracy during plan transitions. |
| Non-goals: Support custom enterprise contracts. Support plan changes across multiple accounts simultaneously. |
| Requirements (Upgrade): Users may upgrade immediately. Additional charges are prorated based on remaining billing period. New features become available immediately. |
| Requirements (Downgrade): Downgrades take effect at the next renewal date. Current features remain available until renewal. |
| Payment failures: Plan changes are not completed if payment authorization fails. Users receive email notification and in-product alert. |
| Acceptance criteria: Upgrade from Standard to Premium applies instantly. Prorated billing amount is correctly calculated. Downgrade does not remove access until renewal date. Failed payments leave current subscription unchanged. |
| Edge cases: Upgrade during failed payment state. Downgrade on renewal day. Simultaneous plan and billing-address changes. |
This specification isn’t bureaucracy. It’s the difference between an agent generating code that works on Monday and breaks the billing logic by Friday, versus code that handles the domain’s actual complexity.
The Design-First Advantage: Numbers Don’t Lie
The standard objection to DDD, and to any upfront design work, is that it slows things down. Who has time for planning when an agent can generate code in seconds?
But the math tells a different story. When you design and discuss the solution as a team before generating code, you compress the entire feedback loop:

The “just generate it and review it” approach creates an asynchronous review cycle that drags on for days. Every round of comments spawns another generation cycle, another review, more comments. The plan-first approach front-loads the discussion into a focused session before code exists.
And here’s the best part for AI adoption: better context produces better AI output. Every insight from your planning session becomes part of the specification you feed the agent. The result isn’t just cleaner review, it’s less code generation churn, fewer incorrect assumptions, and fewer gaps between what was built and what was needed.
The Fractal Architecture approach suggests that when cognitive load is the real bottleneck, self-similar vertical slices beat both layered architectures and feature factories. DDD’s bounded contexts provide exactly this kind of cognitive stability, a structure that lets developers hold the whole system in their heads, even when an AI generated half of it.
What AI Actually Can’t Do
Let’s address the elephant in the room. Can AI agents do the knowledge crunching for us? Can they run the Event Storming sessions and produce the domain model?
The honest answer is no, and not because AI is too weak. It’s because the value isn’t in the artifact, it’s in the understanding. An AI-generated domain model is like a book summary on a blog. You might feel like you’ve absorbed it, but ten seconds after closing the tab, it’s gone.
Working through a domain problem, the mess of competing terminologies, ambiguous business rules, and conflicting stakeholder expectations, builds mental models that persist. This is what one engineering lead described as the difference between “getting paid to think” versus “getting paid to delegate all thinking to an agent.” The first builds expertise that compounds. The second creates dependency that atrophies.
The cognitive load of event-driven architectures already strains teams that design systems by hand. When AI generates those systems, the problem compounds. Without clear domain boundaries, you’re not just debugging code, you’re debugging an agent’s hallucinations about your business.
The Real Risks of Unstructured AI Coding
Event-driven architecture gives us a warning example. Teams rushed to adopt Kafka and event sourcing a decade ago, attracted by the promise of loose coupling and infinite scalability. What they got instead was a distributed debugging nightmare where a single misbehaving event could cascade across twenty services.
The hidden tax of loose coupling is that you spend more time tracing data flow than building features. When AI generates 50,000 lines of event handlers, consumers, and ordering logic in a weekend, you don’t have the luxury of gradually learning the system. You need the domain embedded in the architecture from day one.
DDD’s approach to scaling domain models becomes crucial here, not as a theoretical exercise, but as the operational infrastructure that lets teams validate AI-generated code against a clear mental model.
The uncomfortable truth about resisting over-engineered distributed systems is that modern AI makes premature complexity trivially easy to create. Agents will happily generate microservices, event buses, and saga orchestrators for a system that would fit comfortably in a single Rails app. Your domain model is the only defense against this.
The Practical Playbook
So what does DDD look like in an AI-first world? Not the full ceremony, not the repositories, entities, value objects, and application services layered like a wedding cake. Just the parts that matter:
1. Own your domain language. Run the Event Storming sessions. Argue about whether it’s “User” or “Customer” or “Account.” Decide on the names, then enforce them ruthlessly in code, prompts, and documentation. Agents will respect your language, if you define it explicitly.
2. Make specs executable, not decorative. Don’t generate requirements documents that no one reads. Create versioned specifications in your repository that both humans and agents can reference. Store steering rules in the project, not as conversation history.
3. Design before generating. Every feature should pass through a design checkpoint where a human confirms the approach. Code review should verify that the implementation matches the design, not discover the design for the first time.
4. Keep documentation adjacent to code. Agents will consume the documentation you feed them. Markdown files in the repository are the starting point. Update them as the domain evolves.
5. Build domain expertise, not just coding skill. The engineers who will thrive in the AI era are those who understand their business domain deeply enough to judge whether generated code actually solves a real problem. This is the analogy of reading a book versus reading a summary: summaries feel productive but don’t build the mental models you need to make architectural decisions.
The Verdict
Domain-Driven Design isn’t just relevant in the AI era. It’s becoming the defining skill for senior engineers.
AI agents are getting better at implementation by the quarter. They’re becoming dangerously good at generating code that compiles, runs, and even passes tests. But they still don’t understand your business, your customers, or your domain constraints. They can’t tell you why the billing calculation is wrong on leap years, or why the support team needs a different view of the customer than the accounting department.
The teams that will thrive aren’t the ones that prompt with sophisticated “vibe coding” techniques. They’re the ones that invest in domain modeling, develop shared vocabulary, maintain bounded contexts, and build specifications rigorous enough to constrain AI agents to produce code that actually fits the system.
Eric Evans didn’t predict AI in 2003. But he diagnosed the disease that AI was about to amplify: the belief that technical skill alone can solve domain problems. We’re now seeing what happens when that belief scales to millions of lines of machine-generated code.
Don’t delegate the thinking. Delegate the typing. That’s always been the deal, DDD just made it explicit. AI has made it existential.
The “revolutionary” AI policy mostly revolutionized how many code generation requests you can fire off per day. Domain modeling is what ensures those requests produce a system that holds together. It’s a toolbox, not a religion, but in the age of AI, it’s a toolbox you can’t afford to leave unused.




