| name | book--domain-driven-design-distilled--full |
| description | DDD Distilled (Vaughn Vernon) — Full rules — comprehensive mandatory coding standards. Use when asked to apply DDD Distilled principles or review code against DDD Distilled standards. |
| origin | github.com/ciembor/agent-rules-books (MIT) |
| license | MIT |
| version | 1.0.0 |
| compatibility | yana-ai >= 0.14.0 |
OBEY Domain-Driven Design Distilled by Vaughn Vernon
Purpose
This repository follows Domain-Driven Design Distilled:
use the smallest effective set of DDD practices to model the business meaning clearly and deliver results quickly.
All code generation, edits, and reviews must optimize for:
- clear business language
- explicit bounded contexts
- focus on core domain complexity
- selective use of tactical DDD patterns
- practical implementation over ceremony
- collaboration between model and software design
This file is a binding engineering policy: MUST is binding, SHOULD is a strong default, and MUST NOT is forbidden.
Primary Directive
Use DDD where it clarifies complex business software.
Do not turn DDD into ritual.
When uncertain:
- identify the business capability or subdomain
- decide whether it is core, supporting, or generic
- define the bounded context
- use the local ubiquitous language
- apply only the tactical patterns that actually earn their cost
Reject both extremes:
- no modeling when the domain is complex
- full-blown DDD ceremony when the problem is simple
Adoption Fit and Modeling Investment
- Use DDD when domain complexity, language ambiguity, business differentiation, or integration risk justify the modeling effort.
- Do not apply full tactical DDD to simple CRUD, generic subdomains, or problems whose complexity is mainly technical.
- Let business drivers decide where modeling effort goes.
- Reassess the model when the core business concern drifts, terms stop matching code, or supporting complexity hides the core.
- Use scenarios and acceptance tests to validate that the model expresses real business behavior.
Strategic Rules
Start with Subdomains
Classify major areas as:
- core domain
- supporting subdomain
- generic subdomain
Rules (MUST unless marked SHOULD or MUST NOT):
- Invest the most design effort in the core domain.
- Keep supporting and generic subdomains simpler unless complexity proves otherwise.
- Do not waste the best modeling effort on commodity concerns.
Define Bounded Contexts Early
- Every meaningful model lives inside a bounded context.
- A bounded context owns its language, rules, and model semantics.
- The same term may mean different things in different contexts.
- Code structure must reflect context boundaries.
Use Context Mapping
- Make context relationships explicit.
- Translate where meanings differ.
- Own integration contracts deliberately.
- Protect the local model from foreign language.
Anti-patterns (MUST NOT):
- one model reused across billing, identity, catalog, fulfillment, and support
- shared domain classes with subtly different meanings
- context boundaries documented but ignored in code
Context Relationship Rules
Choose context relationships deliberately:
- USE Partnership only when teams can coordinate closely and share planning burden.
- USE Shared Kernel only for a small stable overlap with joint ownership and tests.
- USE Customer/Supplier when the upstream team can plan for downstream needs.
- USE Conformist when adopting the upstream model is cheaper and safer than translation.
- USE Anticorruption Layer when a foreign model would corrupt the local language.
- USE Open Host Service when many clients need a stable protocol into one context.
- USE Published Language when multiple systems need a documented interchange model.
- USE Separate Ways when integration cost is higher than shared capability value.
- TREAT Big Ball of Mud as a context to contain and translate around, not as a model to spread.
Anti-patterns (MUST NOT):
- claiming independent modeling while conforming silently
- using Shared Kernel without governance
- calling integration an anticorruption layer when no translation exists
Integration Style Rules
- Use RPC only when request/response coupling, latency, versioning, and failure semantics are acceptable.
- Use REST resources as application-facing representations, not as leaked aggregate internals.
- Use messaging when asynchronous coordination fits the business process and consumers can handle lag, duplicates, and ordering limits.
- Decide whether domain events should carry enough information for consumers or require query-back.
- Keep integration contracts separate from internal models.
- Test translations at context boundaries.
Ubiquitous Language Rules
- Use domain terms from the current bounded context in code, tests, commands, events, and conversations.
- One concept gets one term.
- One term must not carry multiple meanings inside one context.
- Rename code when understanding improves.
- Prefer domain names over technical placeholders.
Avoid:
- technical placeholders that conceal a business concept
- names imported from another bounded context without translation
- generic helper or utility names that end up carrying domain decisions
Tactical Pattern Rules
Entities
Use entities when identity and lifecycle matter.
Rules (MUST unless marked SHOULD or MUST NOT):
- Entities must have explicit identity.
- Entities must protect meaningful state transitions.
- Do not expose unrestricted state changes by default.
Value Objects
Use value objects aggressively when a primitive hides meaning.
Rules (MUST unless marked SHOULD or MUST NOT):
- Value objects are immutable by default.
- They validate themselves.
- They make code read in domain language.
Aggregates
Use aggregates only where invariants require a consistency boundary.
Rules (MUST unless marked SHOULD or MUST NOT):
- Keep aggregates small.
- Protect invariants through the aggregate root.
- Reference other aggregates by identity.
- Avoid loading large object graphs.
Domain Events
Use domain events for meaningful facts.
Rules (MUST unless marked SHOULD or MUST NOT):
- Name events in the past tense.
- Use events when they clarify collaboration or integration.
- Do not publish trivial noise for every field change.
Aggregate Minimalism Rules
- Do not create large aggregates to make navigation convenient.
- Default to smaller boundaries.
- Default to eventual consistency across aggregates.
- Use IDs for references across aggregate boundaries.
- One transaction should usually change one aggregate.
Anti-patterns (MUST NOT):
- aggregate designed around a screen
- one request loading and mutating a whole graph
- aggregate roots exposing mutable children directly
Application Service Rules
- Application services coordinate use cases.
- They load aggregates, call domain behavior, save results, and trigger integration work.
- They must not become the real domain model.
- They should stay thin enough that the model still carries meaning.
Anti-patterns (MUST NOT):
- all business decisions in application services
- controllers duplicating application orchestration
- application services shaped only by transport
Architecture and Infrastructure Rules
- Infrastructure is a detail.
- Keep frameworks, persistence mechanics, REST resources, transport formats, and other technology concerns out of the domain model.
- Persist aggregates without letting persistence define the model.
- Translate transport and integration data at the boundary.
Anti-patterns (MUST NOT):
- persistence-first modeling
- reusing transport objects as domain objects
- domain methods depending on framework types
Collaboration Rules
- Keep names close to real business terms.
- Prefer code that teaches the model to a reader.
- Make domain assumptions explicit in names, tests, and events.
- Where a concept is fuzzy, do not hide the ambiguity behind technical abstractions.
Anti-patterns (MUST NOT):
- generic code that could belong to any business
- unexplained status codes and flags with domain meaning
- enums and booleans where a richer concept is needed
Practicality Rules
- Use the least expensive pattern that honestly models the problem.
- Simple domains may use simple services and data structures.
- Once invariants, lifecycle, and language complexity rise, strengthen the model.
- Prefer incremental improvement over massive design overhauls.
Anti-patterns (MUST NOT):
- dismissing DDD because not every module needs it
- over-modeling a generic subsystem
- introducing aggregates and events before knowing why
Accelerated Modeling and Project Rules
- Use event storming or similar collaborative modeling when workflow, events, commands, policies, or team language are unclear.
- Timebox modeling work so it improves implementation instead of becoming detached analysis.
- Use modeling spikes to reduce uncertainty before committing to a model shape.
- Track modeling debt when code and language are known to be imperfect but intentionally deferred.
- Involve domain experts in scenario walkthroughs, terminology decisions, and acceptance criteria.
- Estimate DDD work by modeling uncertainty, integration risk, and implementation cost, not only by feature count.
- Treat team skill and access to domain experts as constraints on how much DDD ceremony the project can sustain.
Code Generation Rules
When generating code, use this default order:
- identify the subdomain
- identify the bounded context
- write names in the local ubiquitous language
- decide whether a concept is entity, value object, aggregate, service, repository, or event
- choose the smallest tactical pattern that fits
- isolate infrastructure at boundaries
- keep context translation explicit
Default avoidance:
- giant shared domain packages
- service-centric fake DDD
- technical names replacing domain language
- full tactical DDD in trivial modules
Review Rules
When reviewing code, actively look for:
- missing subdomain classification
- missing bounded context ownership
- context bleeding
- no context translation where meanings differ
- primitive obsession
- anemic entities
- no value objects where concepts repeat
- aggregates too large
- services containing all behavior
- excessive ceremony in simple modules
- no modeling at all in complex modules
Testing Rules
- Domain tests must read in the ubiquitous language.
- Test value objects for validation and behavior.
- Test entities and aggregates for valid and invalid transitions.
- Test application services for orchestration, not for all domain rules.
- Test context translation where external or foreign models exist.
Review Checklist
Before finalizing any change, verify:
- Is the subdomain/core importance understood?
- Is the bounded context explicit?
- Is the ubiquitous language visible in the code?
- Did we use only the tactical patterns that genuinely help?
- Are aggregates small and focused on invariants?
- Are value objects used where they clarify meaning?
- Are application services coordinating rather than owning all domain logic?
- Did we keep infrastructure out of the model?
- Did we avoid DDD theater and over-modeling?
If any answer is no, revise before shipping.
Final Instruction
When uncertain, choose the option that:
- sharpens the business language
- clarifies the bounded context
- models real complexity honestly
- avoids unnecessary ceremony
- keeps the design practical enough to deliver
Use DDD selectively, but seriously.