Strictness ladder
Strictness is not the same for every folder. It starts hardest at Domain and loosens outward. Runtime request flow goes outside → inside; compile-time dependencies point inward.
Concentric rings
Allowed vs forbidden
| Strictness | Area | May import | Must not |
|---|---|---|---|
| Hardest | Domain | Own Domain + Shared kernel ports | Other modules, own Application, host framework, ORM, facades/helpers |
| Strict | Application (Use Cases, App DTOs) | Own Domain + Shared kernel ports | Facades, ORM, foreign Application/Domain, foreign *ModuleInterface |
| Relaxed (wiring) | Application/Providers | Container binds, route registration, config merge | Business rules |
| Outer | Infrastructure & UI | Framework, ORM, ACL, HTTP clients | Leaking ORM or foreign Domain types into Domain / Use Cases |
Dependency rule vs runtime call
| Concern | Direction | Example |
|---|---|---|
| Runtime request | Outside → inside → outside | Controller → Use Case → port → adapter → DB |
| Compile dependency | Inner types must not know outer types | Domain does not reference a concrete persistence adapter |
| Port binding | Outer implements inner interface | Persistence adapter implements OrderRepositoryInterface |
Worked examples
| Statement | Layer | Verdict |
|---|---|---|
use …Ordering\Domain\Entities\OrderEntity | Ordering Use Case | OK |
use …Ordering\Infrastructure\…\OrderRecord | Ordering Use Case | Forbidden |
use …Warehouse\Domain\Ports\Module\WarehouseModuleInterface | Ordering Use Case | Forbidden — use local ACL port |
Same WarehouseModuleInterface | Ordering ACL adapter | OK (Infrastructure) |
Framework DB facade | Ordering Domain Event | Forbidden — Shared transaction/dispatcher ports |
Composition root exception
Providers (or the host’s equivalent) may wire the framework. If a “rule” appears there, move it to a Use Case or Domain service.
| Layer | Persistence wording |
|---|---|
| Domain | OrderRepositoryInterface |
| Infrastructure | Persistence adapter implementing the port |
| Forbidden in Use Cases | ORM models / query builders / host facades |
Illustrative host mappings — not Core MUST
Persistence quarantine (Infrastructure only)
| Host | Typical place |
|---|---|
| Laravel | Eloquent models / repositories under `…/Eloquent/` |
| Symfony | Doctrine entities / repositories under `…/Doctrine/` |
| Yii | Cycle (Yii3) or ActiveRecord (Yii2 brownfield) in Infra |
| CodeIgniter | CI Models / Query Builder only in Infra repositories |
| CakePHP | Table / Entity ORM types quarantined in Infra |
| Spiral | Cycle ORM via cycle-bridge in Infra |
| Slim | Bring-your-own ORM/SQL — still Infra-only |
| Mezzio | Bring-your-own (laminas-db, Doctrine, …) — Infra-only |
Full topic pages: Adapters overview
Next: golden flow.