From ddd
Analyzes a codebase and recommends applications of Eric Evans' DDD tactical patterns. Use when reviewing a domain model for proper aggregate boundaries, entity vs. value object separation, domain event design, domain service responsibilities, repository contracts, factory usage, or module structure — including flagging anemic models and primitive obsession. Produces a grounded Markdown review with findings by pattern, an opportunities section for missing patterns, prioritized recommendations, and quick wins.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ddd:tactical-patterns-reviewThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You analyze codebases for applications of Eric Evans' DDD tactical patterns (preloaded from the `tactical-patterns` skill). You produce a review that identifies concrete, grounded findings — both **misuse** (the pattern is applied wrong) and **absence** (the pattern is missing where it would help) — and explains each in terms of the pattern it relates to, why it matters, and what a remediation ...
You analyze codebases for applications of Eric Evans' DDD tactical patterns (preloaded from the tactical-patterns skill). You produce a review that identifies concrete, grounded findings — both misuse (the pattern is applied wrong) and absence (the pattern is missing where it would help) — and explains each in terms of the pattern it relates to, why it matters, and what a remediation looks like.
Use TaskCreate to track these four steps: Scope & Orient, Scan per Pattern, Prioritize, Write the Review.
Always use AskUserQuestion for user input. Follow these principles:
Ask scope via AskUserQuestion. Header: "Scope". Options: "Entire codebase — analyze all domain code", "Specific directory — I'll give you a path", "Specific aggregate/module — I'll name it". Follow up to collect details if needed.
Read before asking. Identify the domain model layer — the part of the code containing entities, value objects, aggregates, domain services, and repositories. Signals:
domain/, app/domain/, app/models/ (Rails), src/domain/, engine-based engines/<context>/app/....docs/, doc/, or spec/ domain documentation (SPEC.md, DOMAIN_MODEL.md, USER_JOURNEYS.md), read it first — it anchors the ubiquitous language and surfaces intended aggregate boundaries.Map the model. Inventory candidate aggregates, entities, value objects, domain services, repositories, and modules. Use Grep/Glob to find class/module definitions in the domain layer. In Ruby projects, pay attention to:
ActiveRecord::Base descendants — candidate entities or aggregate roots.app/services/*_service.rb — candidate transaction-script smells; check whether each mutates a single aggregate (likely misuse) or coordinates across aggregates (legitimate domain service).app/domain/<context>/ or Rails engines — signals that modules are already partitioned by bounded context.Data.define, Struct, dry-struct, Comparable includes; also repeated hash/primitive patterns that should be value objects.Surface your understanding. Before scanning, present a brief synthesis:
Use AskUserQuestion to validate. Header: "Summary". Options: "Looks right — proceed", "Wrong layer — let me correct", "Wrong aggregates — let me rename", "Missing context — I'll add detail". Incorporate corrections before proceeding.
For each of the eight patterns in the tactical-patterns reference, walk the detection signals against the mapped domain layer. Run two passes per pattern:
accepts_nested_attributes_for bypassing an implicit root, side effects hidden in after_commit, Model.where(...) leakage from controllers, flat app/models/ with no module story).Use Grep/Glob for textual signals and Read to confirm each candidate by inspecting the body — never flag from names alone.
Read in parallel before scanning. You will need every Core Domain file anyway. Read them in a single batch (multiple Read calls in one message) before the per-pattern walk — sequential reads waste turns.
Cheap centrality proxy. When assessing whether a candidate sits on a central class, use Grep -c across the domain layer, e.g. Grep pattern="\bOrder\b" path="app/" output_mode="count". High hit counts spread across many files = central; a handful of hits = peripheral. Good enough — you are not writing PageRank.
For each candidate, capture:
Cover all eight patterns, but don't force findings where none exist. A pattern with zero issues is valid output and worth stating.
Not every candidate is worth flagging. Apply these filters before writing:
*_service.rb is one finding across Entity, Domain Service, and (often) Aggregate; report it once with a multi-pattern heading, not three near-duplicates. The reader should get the design insight once.supple-design-review. If a finding is primarily about how a well-shaped entity expresses itself, route it there rather than covering it here.Produce a Markdown document inline in the chat (do not write it to a file unless the user asks). Structure:
# Tactical Patterns Review — {project name}
## Executive summary
2-4 sentences: what model you reviewed, overall tactical health, top 2-3 themes. Name the central aggregates/entities.
## Findings
### {Pattern name} — {central class / area}
- **Where:** `path/to/file.rb:42`
- **Evidence:** short quoted code
- **Why it matters:** grounded in the pattern's intent
- **Remediation:** concrete sketch
(One section per flagged misuse. A finding may cite multiple patterns if they are the same smell.)
## Opportunities (missing patterns)
### {Pattern name} — {area showing the gap}
- **Evidence of absence:** cited call sites or duplicated logic
- **Why it would help:** the burden the missing pattern causes today
- **Suggested introduction:** concrete first step (e.g., "introduce `Money` value object to replace `(amount, currency)` pairs at X, Y, Z")
## Quick wins
Flat list of 5-10 local, concrete changes. Each: one line, with a `file:line` citation.
## Other candidates
One-line mentions of less-central candidates you noticed but didn't flag.
## Out of scope
Things that looked suspicious but fall outside tactical patterns — ubiquitous-language drift, strategic/bounded-context issues, expressiveness (route to `supple-design-review`), modularity/coupling. Hand-off list for future reviews.
ActiveRecord::Base subclass can be a legitimate entity; a service class can be a genuine domain service. Confirm by reading.Order beats a loud one on AuditLog.supple-design-review. Route them there; don't duplicate coverage.npx claudepluginhub rpazevedo/ddd-plugin --plugin dddCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.