Mission
Use DDD only where domain complexity justifies it. Make business rules and
ownership explicit without forcing enterprise patterns on simple CRUD. Pair with
speckit.architecture for system decisions and speckit.backend for delivery.
Protocol
0. Suitability and Discovery
- Confirm the problem has complex, evolving rules, competing meanings, or coordination costs. For simple workflows, document the model plainly and do not introduce aggregates, events, or repositories by default.
- Facilitate discovery with domain experts: events, commands, policies, actors, terms, exceptions, lifecycle, and examples. Capture a ubiquitous language and flag terms that mean different things to different teams.
1. Strategic Design
- Identify subdomains and classify core, supporting, and generic work. Define bounded contexts with explicit ownership, language, data, and responsibility.
- Map relationships and integration styles: customer/supplier, conformist, anti-corruption layer, shared kernel, or published language. Make ownership and change coordination visible; do not share a database by default.
- Define context contracts, translation, versioning, error behavior, and data consistency expectations before implementation.
2. Tactical Model
- Model entities by identity, value objects by immutable meaning, aggregates by transactional consistency boundary, and domain services only for behavior that belongs to no entity/value object.
- State each aggregate invariant, command precondition, concurrency rule, and authoritative transaction. Keep aggregates small; reference other aggregates by ID unless the invariant truly requires one transaction.
- Publish domain events only after durable state change. Define event schema, producer/consumer ownership, idempotency, ordering assumptions, versioning, retries, and replay behavior. Use an outbox when database and event delivery must remain consistent.
3. Delivery and Validation
- Convert model decisions into examples, acceptance criteria, API/event contracts, persistence mapping, and tests of invariants and edge cases.
- Evolve incrementally: isolate a context, add an anti-corruption layer, prove behavior with tests, then migrate callers in small reversible slices.
- Revisit the context map after product or ownership changes; retire patterns that no longer match the domain.
Outputs
- Ubiquitous-language glossary, subdomain map, context map, ownership/contracts, aggregate/invariant list, event catalog, and executable acceptance examples.
Guard Rails
- Do not equate DDD with microservices or create an aggregate for every table.
- Do not let technical names override business language, leak one context's model through another's API, or use events without delivery semantics.