[Architecture] Use when you need to analyze business domain: bounded contexts, aggregates, entities, ERD, domain events, and cross-context integration.
[Architecture] Use when you need to analyze business domain: bounded contexts, aggregates, entities, ERD, domain events, and cross-context integration.
[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval.
[BLOCKING] Before each step or sub-skill call, update task tracking: set in_progress when step starts, set completed when step ends.
[BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason.
[BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.
Quick Summary
Goal: Analyze business domain (bounded contexts, aggregates, entities, VOs, domain events, cross-context relationships) and generate a domain model report + ERD — producing a user-validated DDD domain model with correct bounded contexts, aggregate boundaries, and event flows so downstream implementation builds on the right invariants and avoids costly boundary rework after consumers depend on them.
Summary:
Drive the model from business artifacts, not guesses: load plan/PBI/business-eval inputs and domain-entities-reference.md, then extract nouns→entities, verbs→events, roles, and processes before classifying anything.
Every concept passes the Entity-vs-VO matrix and aggregate boundary rules (≤5 entities, one transaction, reference-by-ID only, root is the sole mutation entry) — flag primitive obsession and anemic models as you go.
User validation is non-skippable: present bounded contexts and the Mermaid ERD, then run the 5-8 question interview to confirm boundaries, aggregate roots, and event flows before marking the model confirmed.
AskUserQuestion
Close the loop on persistence: reconcile findings against domain-entities-reference.md (new/modified/deprecated), update the ## Domain Model section of plan.md, and keep cross-context communication event-driven with {AggregateNoun}{PastTenseVerb} naming and no cross-service FKs.
Workflow:
Load Business Context — Read idea, business evaluation, refined PBI artifacts + domain-entities-reference.md
Identify Bounded Contexts — Group related concepts, define context boundaries
Model Entities & Aggregates — Define aggregates, entities, value objects per context
Rule: Primitive with validation rules, formatting, or always passed grouped with other primitives → missing Value Object.
Value Object Construction Pattern
A VO is self-validating: invariants enforced at construction via a factory (no public constructor that can produce an invalid instance), immutable, and equality-by-value. The base class and factory names below are one illustrative instantiation — translate to your language's equivalents.
Example (illustrative — adapt to your language):
// Self-validating VO — never an invalid instance in memorypublicsealedclassEmail : ValueObject<Email>
{
privateEmail(stringvalue) { Value = value; }
publicstring Value { get; }
publicstatic Email Of(string raw)
{
var normalized = raw?.Trim().ToLowerInvariant();
if (string.IsNullOrWhiteSpace(normalized) || !IsValidFormat(normalized))
thrownew DomainException($"Invalid email: {raw}");
returnnew Email(normalized);
}
}
Rules:
No public constructor without validation — factory method (Of() / Create()) enforces invariants
VOs can reference other VOs; VOs NEVER reference entities (lifecycle coupling)
Mutation means replacement: email = Email.Of(newValue), NEVER email.Value = newValue
VO Persistence Strategies
Strategy
When to Use
Trade-offs
Owned types (EF Core)
VO maps to same table as owning entity
Simple, no FK, nullable columns possible
Embedded document store
VO stored as subdocument
Natural fit, no joins
JSON column
Complex VO, low query frequency on VO fields
Flexible, not queryable by parts
Serialized string
Simple VOs (Email, PostalCode)
Compact, unqueryable by parts
Rule: VOs NEVER have own table with primary key — that makes them entities by infrastructure.
DDD Reference: Entity Design
Identity Strategies
Strategy
When to Use
Trade-offs
ULID (default)
New entities in distributed system
Sortable, URL-safe, monotonic, 128-bit
UUID v4
True randomness / security-sensitive IDs
Not sortable, fragmented indexes
UUID v7
Sortable UUID needed
Time-ordered, good index locality
Natural key
Domain guarantees permanent uniqueness (SSN, EAN)
Unstable — domain can change
Surrogate int
Legacy/single-DB sequences
No distributed generation
Composite key
Relationship/join table
Harder to reference from other aggregates
Rules:
Prefer ULID for new entities — sortable, no coordination overhead
NEVER use email/username as PK — users change them
Cross-service references use same ID type as the owning service
GOOD: order.Hold(reason) (entity enforces its own invariants)
Entity Invariant Enforcement
A rich entity guards its own state: a private constructor reserved for ORM/persistence hydration, named factory methods for valid creation, and intent-named mutation methods that reject invalid transitions and emit domain events. The base class, guard helper, and ID generator below are one illustrative instantiation — substitute your language's equivalents.
Example (illustrative — adapt to your language):
publicclassOrder : AuditedAggregateRoot<Order, string>
{
privateOrder() { } // ORM hydration onlypublicstatic Order Create(string name, Email email, WarehouseId warehouseId)
{
Guard.NotNullOrWhitespace(name, nameof(name));
Guard.NotNull(email, nameof(email));
returnnew Order
{
Id = Ulid.NewUlid().ToString(),
Name = name,
Email = email,
WarehouseId = warehouseId,
Status = OrderStatus.Confirmed
};
}
publicvoidCancel(string reason, DateOnly cancellationDate)
{
if (Status == OrderStatus.Cancelled)
thrownew DomainException("Order already cancelled");
if (cancellationDate < DateOnly.FromDateTime(DateTime.UtcNow))
thrownew DomainException("Cancellation date cannot be in the past");
Status = OrderStatus.Cancelled;
CancellationReason = reason;
CancellationDate = cancellationDate;
AddDomainEvent(new OrderCancelledDomainEvent(Id, cancellationDate));
}
}
Entity Lifecycle State Machines
Document ALL transitions explicitly. Unmodeled transitions throw DomainException.
Draft → Submitted (Submit())
Submitted → Approved (Approve(approverId))
Submitted → Rejected (Reject(reason))
Approved → Active (Activate())
Active → Suspended (Suspend(reason))
Suspended → Active (Reinstate())
Active → Archived (Archive())
Pattern
When to Use
Status enum + transition methods
Simple linear/branching lifecycles (most cases)
State pattern (class per state)
Complex per-state behavior, many states
Event sourcing
Full audit trail + point-in-time reconstruction required
Domain Validation Layers
Layer
What It Validates
Failure Signal (per stack)
Value Object
Single-value format/range invariants
Construction failure (raised error or result type)
Entity method
Aggregate consistency rules, state transitions
Domain rule violation (e.g. DomainException)
Application service
Cross-aggregate rules, authorization, existence
Structured validation result (e.g. ValidationResult / problem-details payload)
Infrastructure
DB constraints (last resort, NEVER first line)
Persistence-layer error (last-resort constraint)
Decision rule:
Rule requires loading another aggregate? → Application service
Rule needs only data within aggregate? → Entity method
Rule concerns single value's format? → Value Object constructor
Factory Methods on Entities
Use when: construction requires domain logic, multiple paths, raises domain events, or object graph initialization.
All mutation paths go through root (child entities NEVER directly accessible from outside)
Emit domain events for significant state changes
Control creation of child entities (factory methods on root)
Assign IDs to child entities
Rule: Outside code NEVER holds direct reference to non-root entity within aggregate.
Cross-Aggregate References
Rule
Detail
Reference by ID only
NEVER order.Customer.Name — load separately
No FK object navigation
CustomerId field, NEVER Customer Customer navigation property
Cross-aggregate transactions are eventual
Need them in same transaction → boundaries are wrong
Deletion cascade
Domain event → handler → compensating action in other aggregate
Aggregate Invariant Enforcement
All mutation flows through the aggregate root, which checks every invariant before applying a change and recomputes derived state so no member can be left inconsistent. The throw-on-violation idiom below is one illustrative instantiation — your language may surface invariant breaches differently (exceptions, result types).
Example (illustrative — adapt to your language):
publicvoidAddLineItem(ProductId productId, int quantity, Money unitPrice)
{
if (Status != OrderStatus.Draft)
thrownew DomainException("Cannot modify confirmed order");
if (LineItems.Count >= 50)
thrownew DomainException("Order cannot exceed 50 line items");
var item = OrderLineItem.Create(productId, quantity, unitPrice);
_lineItems.Add(item);
RecalculateTotal(); // invariant: Total == sum(lineItems)
}
Aggregate Design Patterns
Pattern
When to Use
Single-entity aggregate
Default — most entities are their own aggregate
Nested aggregate
Invariant requires atomic consistency across root + children
Aggregate with VOs
Root + embedded value objects (no IDs, no own table)
When to Break Aggregate Rules (Pragmatic DDD)
Situation
Acceptable Pragmatism
ORM limitation (EF owned entities)
Allow private owned collections even if not strictly necessary
Performance — 1-query load
Embed child data as VO/owned type rather than separate aggregate
Legacy schema migration
Accept cross-aggregate FK temporarily, document as debt
Rule: Breaking aggregate rules acceptable ONLY when explicitly documented as technical debt with mitigation plan.
Payload contains value copies, not object references
Domain Events vs Integration Events
Dimension
Domain Event
Integration Event
Scope
Within one bounded context
Across bounded contexts
Delivery
In-process, post-commit
Via configured message bus or event stream
Schema ownership
Domain owns, internal
Published Language contract
Versioning
Internal refactor freely
Versioned, backward-compatible
Failure handling
Transaction rollback
At-least-once delivery, idempotent consumer
Rule: Domain event raised → in-process handlers fire → if cross-service needed, handler publishes integration event to message bus.
Event Versioning Strategies
Strategy
Mechanism
Trade-offs
Additive only
NEVER remove/rename fields, only add
Simple, payload bloats over time
Multiple versions
OrderConfirmedV1, OrderConfirmedV2
Clear versioning, consumers handle both
Upcasting
Transform old events to new on deserialization
Transparent to consumers, complex infra
Backward compatibility rules:
Adding optional field → backward compatible
Removing or renaming field → breaking
Changing field type → breaking
DDD Reference: Repository Pattern
Interface Design Principles
One repository per aggregate root — NEVER one for child entities
Domain language in methods — GetConfirmedOrdersInWarehouse() not FindAll(e => e.Status == Active)
Return domain objects — repositories return entities, not DTOs
No infrastructure concerns — no leaked query/ORM types or connection strings in the interface.
Async-first — methods return the configured runtime's async primitive.
Repository vs DAO
Repository
DAO
Domain-oriented interface
Data-oriented interface
Returns entities/VOs
Returns DTOs or raw data
Used in application/domain layer
Used in infrastructure layer
Hides persistence mechanism
Often tied to persistence mechanism
Query Objects — When to Use Specification
Use when: rule used in multiple places, warrants naming + testing, needs composition.
A specification names a query predicate as a reusable, composable, testable unit owned by the domain. The expression-tree form below is one illustrative instantiation — your language may model it as a predicate function, query builder, or specification object.
Roles — User types with different permissions/views
Processes — Business workflows (application flow, review cycle, etc.)
Step 2: Identify Bounded Contexts
Group related entities using DDD principles. Apply context boundary signals from reference table above.
### Bounded Context: {Name}**Purpose:** {What this context owns — one sentence}
**Classification:** Core domain / Supporting / Generic
**Key Responsibility:** {primary business capability}
**Team ownership:** {suggested team or role}
**Ubiquitous language:** {key terms and their meaning in this context}
Context boundary tests:
Same term used by two teams with different meanings? → separate contexts
Two entities with same name but different invariants? → separate contexts
Can this context be worked on without understanding the other? → good separation
MANDATORY IMPORTANT MUST ATTENTION present identified contexts to user via AskUserQuestion:
"I identified {N} bounded contexts: {list}. Does this grouping make sense?"
Payload includes AggregateId, OccurredOn (UTC), Version?
Payload minimal — just what changed + correlation IDs?
Version field included for schema evolution?
Domain event vs integration event clearly classified?
Step 6: Generate ERD
Produce Mermaid ER diagram. Apply ERD-to-Aggregate mapping + anti-patterns from reference above.
```mermaid
erDiagram
%% Bounded Context: {Name}
ENTITY_A ||--o{ ENTITY_B: "has many"
ENTITY_A {
string id PK
string name
string status
datetime createdAt
}
ENTITY_B {
string id PK
string entityAId FK
string externalServiceId "ID only - no FK across services"
string type
}
```
ERD requirements:
Group entities by bounded context (use Mermaid comments %% Context: ...)
Show PK/FK fields and key business fields (not all fields)
Show cardinality (1:1, 1:N, M:N) using Crow's Foot notation
Cross-service references: string/ULID field with comment, no relationship line
Identify association entities for M:N relationships
ERD — MUST ATTENTION verify before finalizing:
No God tables (>20 columns — consider decomposing)?
No cross-service FK arrows?
All M:N through explicit named join entity?
No nullable FK everywhere (clarify optional relationships)?
Step 7: User Validation Interview
MANDATORY IMPORTANT MUST ATTENTION present domain model and ask 5-8 questions via AskUserQuestion:
Required Questions
Context boundaries — "Are these {N} bounded contexts correct? Any missing or misplaced?"
Options: Correct (Recommended) | Need changes | Not sure, explain more
Aggregate roots — "Is {Entity} the right aggregate root for {Context}? It controls {child entities}."
Entity vs VO — "I modeled {concept} as a Value Object because it has no independent identity. Does that match the business model?"
Relationship verification — "The {Entity A} to {Entity B} relationship is {type/cardinality}. Is that correct?"
Missing entities — "Are there business concepts — workflows, roles, rules — I haven't captured as explicit domain objects?"
Event verification — "When {event} happens, should {contexts} be notified? What data do they need?"
Deep-Dive Questions (pick 2-3 based on complexity)
"Should {Entity} be a separate aggregate or part of {Aggregate}? [separating = eventual consistency between them]"
"Is {field} really a Value Object or does it need its own identity and lifecycle?"
"How does {process} work step-by-step? What state transitions are involved?"
"What happens when {edge case}? Which invariant prevents the bad state?"
"Which entities change most frequently under concurrent load? (impacts aggregate design)"
"Any concepts domain experts name that I haven't modeled explicitly?"
After user confirms, update report with final decisions and mark as status: confirmed.
Options: Approve all (Recommended) | Review each change | Skip update
If docs/project-reference/domain-entities-reference.md does NOT exist, ask user:
"No domain-entities-reference.md found. Create it with all entities from this analysis?"
Options: Yes, create it (Recommended) | No, skip
After user confirms: update/create docs/project-reference/domain-entities-reference.md following existing format. Append new entities to appropriate bounded context section. Update field lists + relationships for modified entities.
Step 9: Update Main Plan (MANDATORY)
Read {plan-dir}/plan.md, append/update ## Domain Model section:
## Domain Model-**Bounded Contexts:** {N} — {list names with context map patterns between them}
-**Total Entities:** {N} ({N} aggregates, {N} child entities, {N} value objects)
-**Domain Events:** {N} cross-context events
-**Key Aggregates:** {list with invariant summaries}
-**Key Relationships:** {summary of critical relationships}
-**ERD:** See `phase-01-domain-model.md`-**Full Analysis:** See `research/domain-analysis.md`
Output
{plan-dir}/research/domain-analysis.md # Full domain analysis report
{plan-dir}/phase-01-domain-model.md # Confirmed domain model with ERD
{plan-dir}/plan.md # Updated with domain model summary
docs/project-reference/domain-entities-reference.md # Updated/created with new/modified entities
Context map (bounded contexts with integration patterns)
Per-context entity/aggregate detail with identity strategy and invariants
Relationship tables (intra + cross-context, identifying vs non-identifying)
Value Objects catalog (VO type, attributes, invariants)
Domain events catalog (with payload design)
Mermaid ERD diagram
Anti-pattern warnings (any detected issues in model)
Unresolved questions
Report must be ≤250 lines. Use tables over prose.
MANDATORY IMPORTANT MUST ATTENTION break work into small todo tasks using TaskCreate BEFORE starting.
MANDATORY IMPORTANT MUST ATTENTION validate EVERY bounded context and key relationship with user via AskUserQuestion.
MANDATORY IMPORTANT MUST ATTENTION include Mermaid ERD and confidence % for all architectural decisions.
MANDATORY IMPORTANT MUST ATTENTION add a final review todo task to verify work quality.
Next Steps
MANDATORY IMPORTANT MUST ATTENTION — NO EXCEPTIONS after completing this skill, use AskUserQuestion to present these options:
"/review-domain-entities (Recommended)" — Review DDD quality of entities modeled/modified in this analysis (anemic model, VO classification, invariant enforcement, aggregate boundaries)
"/tech-stack-research" — Research tech stack based on domain model
"/plan" — If tech stack already decided and entity quality already reviewed
"Skip, continue manually" — user decides
Council escalation (always-offer, second prompt)
After the existing ## Next Steps prompt above resolves, present a second, independent AskUserQuestion call (do NOT merge into the first):
"Skip council — proceed with model (Recommended)" — Continue with the bounded contexts / aggregate boundaries as drawn. Recommended default.
"Escalate to /llm-council" — Run 11 sub-agent council (5 advisors + 5 reviewers + chairman). Best applied when bounded-context splits or aggregate boundaries are contested (multiple defensible cuts), the model touches >=3 services, or invariants span aggregates. DDD boundary decisions are hard to reverse once consumers depend on them. Cheaper alternatives: /why-review, /plan-validate (run these first if you haven't).
MANDATORY IMPORTANT MUST ATTENTION use TaskCreate to break ALL work into small tasks BEFORE starting.
MANDATORY IMPORTANT MUST ATTENTION use AskUserQuestion at EVERY decision point — validate every bounded context and entity relationship with user.
MANDATORY IMPORTANT MUST ATTENTION produce ERD diagram (Mermaid) and domain model report with confidence %.
External Memory: For complex or lengthy work (research, analysis, scan, review), write intermediate findings and final results to a report file in plans/reports/ — prevents context loss and serves as deliverable.
Evidence Gate: MANDATORY IMPORTANT MUST ATTENTION — every claim, finding, and recommendation requires file:line proof or traced evidence with confidence percentage (>80% to act, <80% must verify first).
AI Mistake Prevention — Failure modes to avoid on every task:
Re-read files after context changes. Context compaction, resume, or long-running work can make memory stale; verify current files before acting.
Verify generated content against source evidence. AI hallucinates APIs, names, claims, and document facts. Check the relevant source before documenting or referencing.
Check downstream references before deleting or renaming. Removing an artifact can stale docs, generated mirrors, configs, and callers; map references first.
Trace the full impact chain after edits. Changing a definition can miss derived outputs and consumers. Follow the affected chain before declaring done.
Verify ALL affected outputs, not just the first. One green check is not all green checks; validate every output surface the change can affect.
Assume existing values are intentional — ask WHY before changing. Before changing a constant, limit, flag, wording, or pattern, read nearby context and history.
Surface ambiguity before acting — don't pick silently. Multiple valid interpretations require an explicit question or stated assumption with risk.
Keep shared guidance role-relevant. Universal guidance must help every receiving skill or agent; code-specific obligations belong only in code-specific protocols.
Critical Thinking Mindset — Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence >80% to act.
Anti-hallucination: Never present guess as fact — cite sources for every claim, admit uncertainty freely, self-check output for errors, cross-reference independently, stay skeptical of own confidence — certainty without evidence root of all hallucination.
MUST ATTENTION apply critical + sequential thinking — every claim needs appropriate traced evidence (file:line for repo/code claims; source URL or artifact section for research, product, content, and docs claims); confidence >80% to act, <60% DO NOT recommend. Anti-hallucination: never present guess as fact, admit uncertainty freely, cross-reference independently, stay skeptical of own confidence.
MUST ATTENTION apply AI mistake prevention — verify generated content against evidence, trace downstream references before deleting or renaming, verify all affected outputs, re-read files after context loss, and surface ambiguity before acting.
Prompt-Enhance Closing Anchors
IMPORTANT MUST ATTENTION follow declared step order for this skill; NEVER skip, reorder, or merge steps without explicit user approval
IMPORTANT MUST ATTENTION for every step/sub-skill call: set in_progress before execution, set completed after execution
IMPORTANT MUST ATTENTION every skipped step MUST include explicit reason; every completed step MUST include concise evidence
IMPORTANT MUST ATTENTION if Task tools unavailable, maintain an equivalent step-by-step plan tracker with synchronized statuses
Closing Reminders
IMPORTANT MUST ATTENTION Goal: Produce a user-validated DDD domain model — correct bounded contexts, aggregate boundaries, and event flows — so downstream implementation builds on the right invariants and avoids costly boundary rework after consumers depend on them.
Protocols in force (concise digest of the SYNC/shared blocks this skill carries):
AI Mistake Prevention: verify generated content against evidence, trace downstream references, verify all affected outputs, re-read after context loss, surface ambiguity.
Critical Thinking: Traced proof per claim; confidence >80% to act, NEVER guess as fact.
IMPORTANT MUST ATTENTION validate EVERY bounded context + key relationship with user via AskUserQuestion — NEVER auto-decide a boundary — why: DDD boundaries are hard to reverse once consumers depend on them; one wrong cut costs days of rework.
IMPORTANT MUST ATTENTION domain events ALWAYS follow {AggregateNoun}{PastTenseVerb} naming — NEVER command-style (CancelOrder) or generic (OrderStatusChanged) — why: command/generic names hide what happened and break consumer routing.
IMPORTANT MUST ATTENTION NEVER place cross-service FK in the ERD — use ID reference ({Entity}Id string/ULID) + event-driven sync only — why: cross-service FK couples schemas and blocks independent deployment.
MUST ATTENTIONTaskCreate ALL tasks BEFORE the first artifact read or write; mark one in_progress, complete immediately after evidence; on context loss TaskList first — why: compaction wipes prior-work memory, duplicated tasks waste budget.
MUST ATTENTION load business artifacts FIRST (plan/PBI/business-eval + domain-entities-reference.md) and derive nouns→entities, verbs→events — NEVER model from guesses — why: a model built on assumptions encodes the wrong invariants.
MUST ATTENTION search 3+ existing entities in domain-entities-reference.md before introducing a new one; reconcile new/modified/deprecated against it and follow its existing format — why: divergent or duplicated domain models fragment the source of truth.
MUST ATTENTION evaluate fit before reusing a nearby aggregate/VO pattern — verify the new concept shares the same identity, lifecycle, and transaction scope — why: closest example ≠ matching preconditions.
MUST ATTENTION entity vs VO classification — replace with equal-valued copy breaks nothing? → Value Object. Tracked across time or fetched by ID? → Entity. Flag primitive obsession (3+ primitives travel together) and anemic models as you go.
MUST ATTENTION every aggregate passes boundary rules — ≤5 entities, one transaction, reference-by-ID only, root is the sole mutation entry; >5 entities → decompose or justify as documented debt.
MUST ATTENTION include the Mermaid ERD and a confidence % (>80% to act, <80% verify first) for EVERY architectural decision; cite file:line / artifact evidence — NEVER present a boundary or classification as fact without traced proof.
MUST ATTENTION persist intermediate findings to plans/reports/ incrementally and add a final review task to verify work quality — why: long analysis hits context cutoffs; batched writes lose findings.
Anti-Rationalization:
Evasion
Rebuttal
"Boundaries are obvious, skip user validation"
User validation is non-skippable — run the 5-8 question AskUserQuestion interview.
"Already know the entities, skip reference doc"
Show file:line from domain-entities-reference.md. No proof = not checked.
"This concept is clearly an entity"
Run the Entity-vs-VO matrix anyway — state confidence %. Pattern-matching skips context.
"Small model, skip task tracking"
Still TaskCreate first. Skip depth, never skip tracking.
"Cross-service link is just one FK"
Never — ID reference + event-driven sync. One FK couples two schemas permanently.
[TASK-PLANNING] Before acting, analyze task scope and systematically break it into small todo tasks and sub-tasks using TaskCreate.
IMPORTANT MUST ATTENTION validate EVERY bounded context with the user, name domain events {AggregateNoun}{PastTenseVerb}, and keep cross-service links as ID-reference + events — these three are the most-skipped, highest-blast-radius rules of this skill.
[IMPORTANT] Analyze how big the task is and break it into many small todo tasks systematically before starting — this is very important.