clean-ddd-hexagonal — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited clean-ddd-hexagonal (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Backend architecture combining DDD tactical patterns, Clean Architecture dependency rules, and Hexagonal ports/adapters for maintainable, testable systems.
This skill is an opinionated synthesis of several related architecture traditions. It is not a single canonical architecture model. Use the original source that matches the design question you are answering: DDD for domain modeling, Hexagonal Architecture for ports/adapters, Clean Architecture for dependency direction, Onion Architecture for domain-centered layering, and CQRS/Event Sourcing only for specific read/write or temporal requirements.
| Use When | Skip When |
|---|---|
| Complex business domain with many rules | Simple CRUD, few business rules |
| Long-lived system (years of maintenance) | Prototype, MVP, throwaway code |
| Team of 5+ developers | Solo developer or small team (1-2) |
| Multiple entry points (API, CLI, events) | Single entry point, simple API |
| Need to swap infrastructure (DB, broker) | Fixed infrastructure, unlikely to change |
| High test coverage required | Quick scripts, internal tools |
Start simple. Evolve complexity only when needed. Most systems don't need full CQRS or Event Sourcing.
| Pattern | Primary Question | Use It For | Do Not Treat As |
|---|---|---|---|
| DDD | How do we model a complex business domain? | Ubiquitous language, bounded contexts, aggregates, value objects | A folder structure by itself |
| Hexagonal Architecture | How does the application interact with the outside world? | Ports, driver adapters, driven adapters, testable application core | A mandate for six sides or one exact package layout |
| Clean Architecture | Which direction should dependencies point? | Inward dependency rule, use case boundaries, framework independence | A universal four-folder template |
| Onion Architecture | How do we keep the domain model central? | Domain-centered layers and dependency inversion | A separate requirement when Clean/Hexagonal already solve the local problem |
| CQRS | Do reads and writes need different models? | Bounded contexts with divergent read/write workloads | A default application architecture |
| Event Sourcing | Do we need state from a complete event history? | Audit, temporal queries, replayable workflows | A persistence default for CRUD systems |
Dependencies point inward only. Outer layers depend on inner layers, never the reverse.
Infrastructure → Application → Domain
(adapters) (use cases) (core)Violations to catch:
Design validation: "Create your application to work without either a UI or a database" — Alistair Cockburn. If you can run your domain logic from tests with no infrastructure, your boundaries are correct.
Where does it go?
├─ Pure business logic, no I/O → domain/
├─ Orchestrates domain + has side effects → application/
├─ Talks to external systems → infrastructure/
├─ Defines HOW to interact (interface) → port (domain or application)
└─ Implements a port → adapter (infrastructure)Entity or Value Object?
├─ Has unique identity that persists → Entity
├─ Defined only by its attributes → Value Object
├─ "Is this THE same thing?" → Entity (identity comparison)
└─ "Does this have the same value?" → Value Object (structural equality)Aggregate boundaries?
├─ Must be consistent together in a transaction → Same aggregate
├─ Can be eventually consistent → Separate aggregates
├─ Referenced by ID only → Separate aggregates
└─ >10 entities in aggregate → Split itRule: One aggregate per transaction. Cross-aggregate consistency via domain events (eventual consistency).
src/
├── domain/ # Core business logic (NO external dependencies)
│ ├── {aggregate}/
│ │ ├── entity # Aggregate root + child entities
│ │ ├── value_objects # Immutable value types
│ │ ├── events # Domain events
│ │ ├── repository # DDD repository interface (driven port)
│ │ └── services # Domain services (stateless logic)
│ └── shared/
│ └── errors # Domain errors
├── application/ # Use cases / Application services
│ ├── {use-case}/
│ │ ├── command # Command/Query DTOs
│ │ ├── handler # Use case implementation
│ │ └── port # Driver port interface
│ └── shared/
│ └── unit_of_work # Transaction abstraction
├── infrastructure/ # Adapters (external concerns)
│ ├── persistence/ # Database adapters
│ ├── messaging/ # Message broker adapters
│ ├── http/ # REST/GraphQL adapters (DRIVER)
│ └── config/
│ └── di # Dependency injection / composition root
└── main # Bootstrap / entry pointPort placement: This skill defaults to a DDD-centered layout where aggregate repository interfaces live beside the aggregate in domain/. A stricter Hexagonal layout may instead put driven ports under application/ports/driven/. Pick one convention per codebase and keep the dependency rule intact.
| Pattern | Purpose | Layer | Key Rule |
|---|---|---|---|
| Entity | Identity + behavior | Domain | Equality by ID |
| Value Object | Immutable data | Domain | Equality by value, no setters |
| Aggregate | Consistency boundary | Domain | Only root is referenced externally |
| Domain Event | Record of change | Domain | Past tense naming (OrderPlaced) |
| Repository | Persistence abstraction | Domain (port) | Per aggregate, not per table |
| Domain Service | Stateless logic | Domain | When logic doesn't fit an entity |
| Application Service | Orchestration | Application | Coordinates domain + infra |
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Anemic Domain Model | Entities are data bags, logic in services | Move behavior INTO entities |
| Repository per Entity | Breaks aggregate boundaries | One repository per AGGREGATE |
| Leaking Infrastructure | Domain imports DB/HTTP libs | Domain has ZERO external deps |
| God Aggregate | Too many entities, slow transactions | Split into smaller aggregates |
| Skipping Use Cases | Controllers call repositories directly in a use-case architecture | Route through application use cases |
| CRUD Thinking | Modeling data, not behavior | Model business operations |
| Premature CQRS | Adding complexity before needed | Start with simple read/write, evolve |
| Cross-Aggregate TX | Multiple aggregates in one transaction | Use domain events for consistency |
DDD is collaborative. Modeling sessions with domain experts are as important as the code patterns.
| File | Purpose |
|---|---|
| references/LAYERS.md | Complete layer specifications |
| references/DDD-STRATEGIC.md | Bounded contexts, context mapping |
| references/DDD-TACTICAL.md | Entities, value objects, aggregates (pseudocode) |
| references/HEXAGONAL.md | Ports, adapters, naming |
| references/CQRS-EVENTS.md | Command/query separation, events |
| references/TESTING.md | Unit, integration, architecture tests |
| references/CHEATSHEET.md | Quick decision guide |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.