| name | adversarial-ddd |
| description | Use this skill to gate DDD and ubiquitous-language quality with a pass/fail adversarial review — a single blind reviewer subagent judges a diff, a module/bounded context, or a DSL/semantic-model surface against 20 decidable rules across glossary lifecycle (a recorded ubiquitous language is required once domain concepts exist — absence is FAIL; code must conform; entries stay live and carry business meaning), language consistency (one name per concept, one meaning per name, no Manager/Helper/Data names on domain rules, transitions named as operations, one vocabulary across code, tests, docs, UI copy), domain model integrity (anemic models, valid-on-construction, value types over primitives, named states over flag piles), context boundaries (foreign-model reach, vendor-type absorption, infrastructure in the domain, multiple writers), and DSL surfaces. Language-agnostic; repeated runs converge code, team, and stakeholders on one recorded vocabulary. Verdicts only. |
Adversarial DDD Gate
A domain-driven design and ubiquitous-language gate for any codebase — a pass/fail gate: a single blind reviewer subagent judges the work against this gate's rules with an adversarial mandate, and the work passes only when every rule is PASS or N/A. This skill renders verdicts; it never fixes the work.
The gate's engine is the glossary lifecycle: once a target contains domain concepts, a recorded ubiquitous language (a glossary) must exist — its absence is a FAIL whose fix list names the exact file to create and the terms it must define. Run the gate on any project and the first verdict forces the vocabulary into existence; every later run holds the code, tests, docs, and customer-facing copy to it and keeps it well-sized. That is how one skill produces a common, well-understood vocabulary across many projects, exactly as DDD prescribes.
When to Apply
- Domain code is about to merge and needs an objective PASS/FAIL on ubiquitous-language and domain-model quality, not advisory feedback.
- A project is being started or adopted and you want the shared vocabulary forced into existence — the first run's fix list is the glossary's initial contents.
- An agent (Claude, Codex) authored the code and you want an independent check on its known defaults:
*Manager/*Helper types, setStatus() transitions, anemic entities, vendor types absorbed into the model.
- A DSL, fluent builder, or declarative spec format is being introduced and its surface needs judging as a domain-vocabulary artifact.
- A periodic audit — the codebase, docs, and stakeholder-facing surfaces have drifted and you want the divergences named with locations.
Do not apply to targets with no domain concepts — pure infrastructure, build tooling, generic libraries (the reviewer prompt's precondition aborts with "GATE NOT APPLICABLE"). Do not apply when the user wants explanations or refactoring rather than a verdict. Rules whose prerequisite structure is absent (no identifiable contexts, no DSL, no glossary yet for the conformance rules) go N/A, not FAIL — except the two absence rules (gloss-language-recorded, dsl-deterministic-validator-exists), where the missing artifact is itself the FAIL.
Review Protocol
Follow these steps exactly — the gate's value is that every review runs the same way.
- Identify the target. Pin down exactly what is under review (a diff, a module/bounded context, a DSL surface) and note the ref/paths so the review runs against an unambiguous, fixed target. Always include the repo root — the
gloss-* rules search the repo for a glossary and for term usage, and the ctx-* rules need sibling contexts visible beyond the diff. Note where docs and user-facing copy live if they exist.
- Load the rules. Read references/_sections.md and every rule file in
references/ (all gloss-*.md, lang-*.md, model-*.md, ctx-*.md, dsl-*.md files).
- Compose the reviewer prompt. Fill references/reviewer-prompt.md with the rules and the target. The composed prompt must be fully self-contained — a reviewer sees no conversation history, so nothing may refer to context outside the prompt.
- Dispatch one blind reviewer. Launch a single Task subagent whose entire input is the composed prompt — no conversation context, no commentary alongside it.
- Render fail-closed. The reviewer's structured output is the verdict — there is no merge step. Overall verdict is PASS only when every rule is PASS or N/A; any single FAIL fails the gate. Never average, weigh severity, or waive a rule — a "minor" FAIL is a FAIL. If the reviewer returns "GATE NOT APPLICABLE" (no domain concepts in the target), stop and report that instead of a verdict.
- Render the verdict. Fill assets/templates/verdict.md. On FAIL, aggregate the reviewer's "missing for PASS" suggestions into the fix list, each with its location, ordered by category importance — glossary edits first, since creating or correcting the recorded language is what makes the remaining rules checkable. Every rule whose result is FAIL must appear in the fix list with a change concrete enough to apply as written — if the reviewer's suggestion only restates the violation, derive the fix from the rule's Correct example before rendering.
If the same rule flips verdicts across re-reviews of an unchanged target, or a human reads the evidence and overrides the verdict, that is a decidability bug in the rule — record it in gotchas.md and sharpen the rule; do not override the gate.
Verdict Format
The reviewer returns, per rule: PASS | FAIL | N/A, evidence (file:line, a quote, or the glossary entry — required for PASS as well as FAIL), and for every FAIL, the fix that flips the rule to PASS once applied — the named change plus its location, never a restatement of the violation. The reviewer also reports which glossary it found (or that none exists and where it searched). The final report follows assets/templates/verdict.md.
Rule Categories
| # | Category | Prefix | Covers |
|---|
| 1 | Glossary Lifecycle | gloss- | A recorded ubiquitous language exists (absence is FAIL), code conforms to it, every entry stays live, definitions carry business meaning |
| 2 | Language Consistency | lang- | One name per concept, one meaning per name, no semantics-free names on domain rules, transitions named as operations, one vocabulary across code/tests/docs/UI |
| 3 | Domain Model Integrity | model- | Rules live with the model, valid on construction, domain types over bare primitives, named states over boolean flag piles |
| 4 | Boundaries & Context Integrity | ctx- | Published interfaces between contexts, anticorruption at vendor seams, infrastructure-free domain, one writer per stored model |
| 5 | Semantic Model & DSL Surface | dsl- | Semantic model separate from carrier syntax, illegal statements unconstructible or fail-fast, deterministic validator for external DSLs |
Related Skills
domain-architect (experimental) — teaching-style domain modeling guidance; use it when the goal is designing the model rather than gating it.
adversarial-ts-patterns (experimental) — pattern-usage gate for TypeScript/React; run alongside this gate on TS targets for full coverage (it owns the state-machine and over-abstraction rules at the code-idiom level).
feature-arch-gate (experimental) — folder/feature architecture gate; complementary at the project-structure level.
Reference Files