OBEY Clean Architecture by Robert C. Martin
Purpose
This repository must follow Clean Architecture.
When writing, modifying, or reviewing code, prefer decisions that preserve:
- independent business rules
- inward-pointing dependencies
- framework independence
- database independence
- UI independence
- testability
- replaceable details
Treat this file as a binding implementation policy: MUST is binding, SHOULD is a strong default, and MUST NOT is forbidden.
Non-Negotiable Rules
Follow the Dependency Rule
- Source code dependencies must point inward, toward higher-level policies.
- Inner layers must not import or depend on outer layers.
- Business rules must not depend on frameworks, web handlers, database drivers, UI libraries, queues, external services, or other details.
Keep Business Rules Pure
- Entities and use cases must contain business policy.
- Business rules must not read web requests, environment variables, framework context, database-bound structures, or database rows directly.
- Pass plain data into use cases through request models or arguments.
Treat Frameworks as Details
- Frameworks are tools, not the foundation of the design.
- Keep framework annotations, decorators, controllers, routes, middleware, serializers, and database artifacts at the edges.
- Do not let framework types leak into core policies.
Treat the Database as a Detail
- Do not shape the domain model around tables.
- Use gateways to isolate persistence.
- Business rules must work without a real database.
Treat the Web as a Detail
- Controllers and endpoints translate delivery input into input models for use cases.
- Use cases must not know about web transport, status codes, cookies, headers, or routing.
- Presenters or response mappers translate use case output for delivery mechanisms.
Use Explicit Boundaries
- Define interfaces at architectural seams.
- External systems, persistence, messaging, file systems, clocks, and service clients must sit behind boundaries.
- Prefer adapters over direct calls from policy code to implementation details.
Organize by Use Case
- Prefer feature and use-case oriented structure over generic technical buckets.
- The architecture should scream the domain and application intent.
- Avoid codebases dominated by generic technical buckets that do not reveal use cases or business purpose.
Use Cases Must Orchestrate
- A use case coordinates entities and gateways.
- A use case should not contain delivery concerns, database concerns, or presentation formatting concerns.
- A use case should represent one application action.
Entities Must Guard Invariants
- Critical domain rules belong in entities or equivalent domain objects.
- Entities must protect invariants and consistency.
- Do not leave core rules in controllers, jobs, handlers, or database scripts.
Outer Layers May Depend on Inner Layers, Never the Reverse
- Controllers may depend on use cases.
- Gateways may implement interfaces defined by the use case or domain layer.
- Presenters may implement output boundaries owned by inner layers.
- Never invert this relationship accidentally.
Required Layer Responsibilities
Domain Layer
Contains:
- entities
- enterprise business rules
- domain invariants
- core business rules
These may be implemented with plain objects, functions, modules, or other structures. Clean Architecture requires independent business rules; it does not require a specific domain modeling style.
Must:
- be framework free
- be persistence ignorant
- be delivery mechanism agnostic
- avoid annotations and infrastructure imports where possible
Must not:
- import web libraries
- import database access types
- import external service clients
- perform I/O
- read configuration directly
Application Layer
Contains:
- use cases
- input models
- output models
- ports and boundaries
- orchestration logic
Must:
- depend on domain abstractions and models
- define interfaces for required external behavior
- coordinate workflows explicitly
Must not:
- contain controller logic
- contain database access details
- return framework response types
- format UI strings unless explicitly part of a presenter boundary
Interface Adapters Layer
Contains:
- controllers
- presenters
- view models
- gateway adapters
- mappers between external and internal models
Must:
- translate between external formats and internal models
- depend inward on application and domain code
- isolate framework and vendor details
Must not:
- move business policy out of the use case or domain layer
- bypass use cases to call gateways directly unless explicitly justified by architecture
Infrastructure Layer
Contains:
- framework bootstrap
- object graph and component wiring
- database access details
- external service integrations
- message bus clients
- filesystem implementations
- network clients
Must:
- remain replaceable
- implement interfaces owned by inner layers
- stay at the outermost edge
Must not:
- define business rules
- dictate domain shapes
- leak vendor types inward
Code Generation Rules
When generating code, always apply the following.
1. Define the Use Case First
For every non-trivial feature:
- identify the use case
- define the input
- define the output
- define required ports
- keep orchestration in one place
Prefer this order:
- domain rule or entity behavior
- use case
- boundary interfaces
- presenter contract
- gateway contract
- adapters
- framework wiring
2. Use Plain Models at Boundaries
- Use request and response models owned by the application layer.
- Do not pass database-bound entities, web requests, or framework-bound data structures into core logic.
- Do not return framework objects from use cases.
3. Create Ports for Volatile Dependencies
Introduce interfaces for:
- gateways
- mailers
- payment providers
- message publishers
- storage providers
- clocks
- ID generators
- transaction runners if needed
Do not call volatile details directly from core use cases.
4. Keep Wiring in the Main Component
- Object construction belongs in the composition root.
- Do not instantiate infrastructure dependencies inside use cases or entities.
- Use explicit construction, factories, or composition in the outer layer.
5. Prefer Stable Dependencies
- Inner layers own the abstractions they need.
- Outer layers implement those abstractions.
- Avoid shared "common" packages that create sideways coupling.
6. Keep Boundaries Visible
- When in doubt, introduce a boundary sooner.
- Partial boundaries are acceptable if they preserve future extraction options.
- Use interfaces, request models, and output models to avoid coupling to details.
Architecture Heuristics
Dependency Direction
Always verify:
- Does this import point inward?
- Is a high-level policy depending on a low-level detail?
- Is a framework or vendor type leaking into a core layer?
- Is an adapter bypassing the intended boundary?
If yes, refactor.
Policy vs Detail
When placing code, ask:
- Is this business policy?
- Is this orchestration?
- Is this translation?
- Is this infrastructure?
Put the code in the highest-level place that matches its responsibility.
Stable Core, Replaceable Edge
Prefer designs where you can replace:
- web framework
- persistence technology
- message broker
- job runner
- cloud vendor
- serializer
- UI
without rewriting business rules.
Feature First Structure
Prefer:
- feature/use-case names
- business-capability/use-case names
- names that reveal the application's use cases
Over:
- generic controller, service, or gateway buckets
- generic technical buckets
Technical subfolders are acceptable only when they do not obscure use-case ownership.
Architecture Economics and Priority
- Treat architecture as a way to keep future change cost proportional to the scope of change.
- Do not sacrifice important architectural work merely because urgent feature work is louder.
- Preserve options around frameworks, databases, delivery mechanisms, and deployment topology until evidence justifies commitment.
- Choose boundaries by volatility, policy importance, substitution value, testability, and cost.
- Do not overbuild boundaries whose cost exceeds the option value they preserve.
- Revisit architecture when change shape, team ownership, deployment needs, or operational constraints reveal rising cost.
Paradigm and Component Rules
- Use structured programming to make behavior decomposable and testable.
- Use polymorphism to invert dependencies when high-level policy must not know low-level details.
- Use immutability or controlled mutation when it protects policy from accidental state coupling.
- Apply SRP by separating code that changes for different actors or reasons.
- Apply the Open-Closed Principle by protecting stable policy from volatile extension details.
- Apply LSP by ensuring substitutable implementations preserve caller expectations.
- Apply ISP by keeping interfaces focused on what each client actually needs.
- Apply DIP by making source dependencies point toward stable policy and abstractions.
- Group components by cohesion and release pressure; do not group unrelated policy just because it shares a technical layer.
- Avoid component cycles; break cycles before they harden into deployment or test bottlenecks.
- Balance stability and abstraction: stable components should not depend on unstable details, and abstract components should have concrete reason to exist.
Boundary Cost, Deployment, and Operations
- A boundary may be a source boundary, deployment boundary, process boundary, service boundary, or partial boundary.
- Choose the lightest boundary that preserves the needed independence.
- Use partial boundaries when a full deployment/runtime split is too expensive but future separation is valuable.
- Keep development, deployment, operation, and maintenance concerns visible without letting them own business policy.
- Do not combine unrelated use cases just because operational wiring is easier.
- Do not eliminate duplication when the shared code would couple use cases that change for different actors.
- Make architectural boundaries enforceable through package structure, tests, dependency rules, or build constraints.
Services, Distribution, and Embedded Boundaries
- A service is not automatically an architectural boundary; source dependencies and data ownership still decide coupling.
- Remote calls must be treated as I/O boundaries, not as local method calls.
- Keep service listeners humble: translate external messages into use case calls and return through output boundaries.
- Keep embedded and hardware details behind interfaces so policy can be tested without the target device.
- Do not let real-time, firmware, database, web, or framework concerns pull policy outward.
Naming Rules
- Name modules and packages after business capabilities or use cases.
- Name use cases with action verbs from the application's use cases.
- Name ports by the role they play for the use case.
- Name adapters by the external detail or delivery mechanism they adapt.
- Avoid vague technical names when a use case, policy, boundary, presenter, controller, gateway, or entity role is more precise.
- If a class is named
Service, justify why it is not a use case, adapter, or domain object.
Testing Rules
Core Tests First
Prioritize tests for:
- entities
- use cases
- boundary contracts
These tests must:
- run without the real framework
- run without the real database
- run without the network
- run fast and deterministically
Adapter Tests
Test adapters separately for:
- mapping correctness
- gateway behavior
- controller translation
- presenter formatting
- integration with framework or external service
Do not use slow integration tests as a substitute for testing business rules.
Test Through Supported Boundaries
- Avoid reaching private internals when a public use case boundary exists.
- Prefer testing use cases with fakes or mocks for ports.
- Use integration tests only where architectural seams meet real details.
Forbidden Patterns
Do not generate or keep code that does any of the following unless explicitly required and justified.
Framework Leakage
- domain entities annotated with database or web framework metadata when avoidable
- use cases depending on
Request, Response, controller base classes, framework sessions, or middleware objects
- application layer importing serializer or database base classes
Database Leakage
- use cases returning table rows or database-bound entities
- domain rules embedded in gateway implementations or database access
- domain objects designed primarily around persistence convenience
Controller-Centric Logic
- controllers containing branching business rules
- controllers performing validation that belongs to business policy
- controllers calling gateways directly instead of use cases
God Services
- large
*Service classes that create, fetch, validate, persist, publish, and present everything
- services that own unrelated use cases
- application services that become dumping grounds
Layer Bypass
- controllers bypassing use cases to call gateways
- presenters reading directly from databases
- infrastructure code importing inward and also being imported by domain code
Direction Violations
- gateway interfaces defined in infrastructure and consumed by core policy
- entities importing adapters
- use cases depending on concrete implementations
Utility Dumping Grounds
- generic utility, shared, base, or core folders used as architecture escape hatches
- generic abstractions with no clear ownership
- convenience modules that hide bad dependency direction
Refactoring Rules
When modifying existing code:
Move business rules inward
- Extract domain logic from controllers, handlers, views, gateway classes, and jobs.
Introduce boundaries around details
- Wrap external services, database access, message buses, filesystem operations, and clocks.
Replace concrete dependencies with ports
- Define interfaces in inner layers.
- Implement them in outer layers.
Separate translation from policy
- Request parsing, data mapping, serialization, and presentation formatting belong outside core business rules.
Break up god services
- Split by use case.
- Give each use case one clear application action.
Eliminate framework coupling from tests
- Rewrite tests to target use cases and entities directly where possible.
Preserve behavior while improving direction
- Refactor incrementally.
- Prefer safe boundary extraction over large rewrites.
Output Expectations
When asked to implement a feature, default to producing:
- a domain model or entity if business invariants exist
- a focused use case
- input and output models if needed
- ports/interfaces for external dependencies
- adapters for web, persistence, or messaging details
- composition root wiring outside the use case
When asked to modify existing code:
- keep or improve dependency direction
- avoid adding framework dependencies to inner layers
- call out architectural debt explicitly if it cannot be fixed safely now
When asked to review code:
- identify boundary violations
- identify dependency rule violations
- identify framework leakage
- identify misplaced business rules
- identify god services and layer bypass
- propose concrete refactorings toward Clean Architecture
Review Checklist
Before finalizing any change, verify:
- Are business rules independent from frameworks?
- Are use cases independent from delivery and persistence details?
- Do source dependencies point inward?
- Are controllers thin?
- Are gateways just persistence adapters?
- Are entities guarding domain invariants?
- Are ports owned by inner layers?
- Is composition happening at the edge?
- Can core tests run without the web framework and database?
- Does the project structure reflect the domain and use cases?
- Did we avoid generic utility dumping grounds?
- Did we avoid creating another god service?
- Did we keep details replaceable?
If any answer is no, revise the design before shipping.
Preferred Default Shapes
Preferred feature shape
- domain
- application
- adapters
- infrastructure
Or, if feature-oriented:
- feature/domain
- feature/application
- feature/adapters
- feature/infrastructure
Preferred use case shape
- request model
- use case
- output boundary or response model
- ports
- adapter implementations outside
Preferred dependency pattern
- inner layer defines interface
- outer layer implements interface
- composition root wires them together
When Tradeoffs Are Necessary
If constraints force a compromise:
- keep the compromise at the outermost layer possible
- document the boundary violation clearly in code comments or review notes
- avoid normalizing the compromise into the core architecture
- preserve a future path to separation
Choose the design that minimizes long-term coupling, not the one that is only shortest today.
Final Instruction
When uncertain, choose the option that:
- keeps business rules independent
- points dependencies inward
- isolates details behind boundaries
- improves testability
- makes replacement of frameworks, databases, and delivery mechanisms easier
If a proposed change conflicts with these priorities, reject it and propose a cleaner architectural alternative.
1---2name: book-clean-architecture-full3description: Clean Architecture (Robert C. Martin) — Full rules — comprehensive mandatory coding standards. Use when asked to apply Clean Architecture principles or review code against Clean Architecture standards.4license: MIT5---6
7# OBEY Clean Architecture by Robert C. Martin
8
9## Purpose
10
11This repository must follow **Clean Architecture**.
12When writing, modifying, or reviewing code, prefer decisions that preserve:
13- independent business rules
14- inward-pointing dependencies
15- framework independence
16- database independence
17- UI independence
18- testability
19- replaceable details
20
21Treat this file as a binding implementation policy: `MUST` is binding, `SHOULD` is a strong default, and `MUST NOT` is forbidden.
22
23---
24
25## Non-Negotiable Rules
26
271. **Follow the Dependency Rule**
28 - Source code dependencies must point inward, toward higher-level policies.
29 - Inner layers must not import or depend on outer layers.
30 - Business rules must not depend on frameworks, web handlers, database drivers, UI libraries, queues, external services, or other details.
31
322. **Keep Business Rules Pure**
33 - Entities and use cases must contain business policy.
34 - Business rules must not read web requests, environment variables, framework context, database-bound structures, or database rows directly.
35 - Pass plain data into use cases through request models or arguments.
36
373. **Treat Frameworks as Details**
38 - Frameworks are tools, not the foundation of the design.
39 - Keep framework annotations, decorators, controllers, routes, middleware, serializers, and database artifacts at the edges.
40 - Do not let framework types leak into core policies.
41
424. **Treat the Database as a Detail**
43 - Do not shape the domain model around tables.
44 - Use gateways to isolate persistence.
45 - Business rules must work without a real database.
46
475. **Treat the Web as a Detail**
48 - Controllers and endpoints translate delivery input into input models for use cases.
49 - Use cases must not know about web transport, status codes, cookies, headers, or routing.
50 - Presenters or response mappers translate use case output for delivery mechanisms.
51
526. **Use Explicit Boundaries**
53 - Define interfaces at architectural seams.
54 - External systems, persistence, messaging, file systems, clocks, and service clients must sit behind boundaries.
55 - Prefer adapters over direct calls from policy code to implementation details.
56
577. **Organize by Use Case**
58 - Prefer feature and use-case oriented structure over generic technical buckets.
59 - The architecture should scream the domain and application intent.
60 - Avoid codebases dominated by generic technical buckets that do not reveal use cases or business purpose.
61
628. **Use Cases Must Orchestrate**
63 - A use case coordinates entities and gateways.
64 - A use case should not contain delivery concerns, database concerns, or presentation formatting concerns.
65 - A use case should represent one application action.
66
679. **Entities Must Guard Invariants**
68 - Critical domain rules belong in entities or equivalent domain objects.
69 - Entities must protect invariants and consistency.
70 - Do not leave core rules in controllers, jobs, handlers, or database scripts.
71
7210. **Outer Layers May Depend on Inner Layers, Never the Reverse**
73 - Controllers may depend on use cases.
74 - Gateways may implement interfaces defined by the use case or domain layer.
75 - Presenters may implement output boundaries owned by inner layers.
76 - Never invert this relationship accidentally.
77
78---
79
80## Required Layer Responsibilities
81
82### Domain Layer
83Contains:
84- entities
85- enterprise business rules
86- domain invariants
87- core business rules
88
89These may be implemented with plain objects, functions, modules, or other structures. Clean Architecture requires independent business rules; it does not require a specific domain modeling style.
90
91Must:
92- be framework free
93- be persistence ignorant
94- be delivery mechanism agnostic
95- avoid annotations and infrastructure imports where possible
96
97Must not:
98- import web libraries
99- import database access types
100- import external service clients
101- perform I/O
102- read configuration directly
103
104### Application Layer
105Contains:
106- use cases
107- input models
108- output models
109- ports and boundaries
110- orchestration logic
111
112Must:
113- depend on domain abstractions and models
114- define interfaces for required external behavior
115- coordinate workflows explicitly
116
117Must not:
118- contain controller logic
119- contain database access details
120- return framework response types
121- format UI strings unless explicitly part of a presenter boundary
122
123### Interface Adapters Layer
124Contains:
125- controllers
126- presenters
127- view models
128- gateway adapters
129- mappers between external and internal models
130
131Must:
132- translate between external formats and internal models
133- depend inward on application and domain code
134- isolate framework and vendor details
135
136Must not:
137- move business policy out of the use case or domain layer
138- bypass use cases to call gateways directly unless explicitly justified by architecture
139
140### Infrastructure Layer
141Contains:
142- framework bootstrap
143- object graph and component wiring
144- database access details
145- external service integrations
146- message bus clients
147- filesystem implementations
148- network clients
149
150Must:
151- remain replaceable
152- implement interfaces owned by inner layers
153- stay at the outermost edge
154
155Must not:
156- define business rules
157- dictate domain shapes
158- leak vendor types inward
159
160---
161
162## Code Generation Rules
163
164When generating code, always apply the following.
165
166### 1. Define the Use Case First
167For every non-trivial feature:
168- identify the use case
169- define the input
170- define the output
171- define required ports
172- keep orchestration in one place
173
174Prefer this order:
1751. domain rule or entity behavior
1762. use case
1773. boundary interfaces
1784. presenter contract
1795. gateway contract
1806. adapters
1817. framework wiring
182
183### 2. Use Plain Models at Boundaries
184- Use request and response models owned by the application layer.
185- Do not pass database-bound entities, web requests, or framework-bound data structures into core logic.
186- Do not return framework objects from use cases.
187
188### 3. Create Ports for Volatile Dependencies
189Introduce interfaces for:
190- gateways
191- mailers
192- payment providers
193- message publishers
194- storage providers
195- clocks
196- ID generators
197- transaction runners if needed
198
199Do not call volatile details directly from core use cases.
200
201### 4. Keep Wiring in the Main Component
202- Object construction belongs in the composition root.
203- Do not instantiate infrastructure dependencies inside use cases or entities.
204- Use explicit construction, factories, or composition in the outer layer.
205
206### 5. Prefer Stable Dependencies
207- Inner layers own the abstractions they need.
208- Outer layers implement those abstractions.
209- Avoid shared "common" packages that create sideways coupling.
210
211### 6. Keep Boundaries Visible
212- When in doubt, introduce a boundary sooner.
213- Partial boundaries are acceptable if they preserve future extraction options.
214- Use interfaces, request models, and output models to avoid coupling to details.
215
216---
217
218## Architecture Heuristics
219
220### Dependency Direction
221Always verify:
222- Does this import point inward?
223- Is a high-level policy depending on a low-level detail?
224- Is a framework or vendor type leaking into a core layer?
225- Is an adapter bypassing the intended boundary?
226
227If yes, refactor.
228
229### Policy vs Detail
230When placing code, ask:
231- Is this business policy?
232- Is this orchestration?
233- Is this translation?
234- Is this infrastructure?
235
236Put the code in the highest-level place that matches its responsibility.
237
238### Stable Core, Replaceable Edge
239Prefer designs where you can replace:
240- web framework
241- persistence technology
242- message broker
243- job runner
244- cloud vendor
245- serializer
246- UI
247without rewriting business rules.
248
249### Feature First Structure
250Prefer:
251- feature/use-case names
252- business-capability/use-case names
253- names that reveal the application's use cases
254
255Over:
256- generic controller, service, or gateway buckets
257- generic technical buckets
258
259Technical subfolders are acceptable only when they do not obscure use-case ownership.
260
261---
262
263## Architecture Economics and Priority
264
2651. Treat architecture as a way to keep future change cost proportional to the scope of change.
2662. Do not sacrifice important architectural work merely because urgent feature work is louder.
2673. Preserve options around frameworks, databases, delivery mechanisms, and deployment topology until evidence justifies commitment.
2684. Choose boundaries by volatility, policy importance, substitution value, testability, and cost.
2695. Do not overbuild boundaries whose cost exceeds the option value they preserve.
2706. Revisit architecture when change shape, team ownership, deployment needs, or operational constraints reveal rising cost.
271
272---
273
274## Paradigm and Component Rules
275
2761. Use structured programming to make behavior decomposable and testable.
2772. Use polymorphism to invert dependencies when high-level policy must not know low-level details.
2783. Use immutability or controlled mutation when it protects policy from accidental state coupling.
2794. Apply SRP by separating code that changes for different actors or reasons.
2805. Apply the Open-Closed Principle by protecting stable policy from volatile extension details.
2816. Apply LSP by ensuring substitutable implementations preserve caller expectations.
2827. Apply ISP by keeping interfaces focused on what each client actually needs.
2838. Apply DIP by making source dependencies point toward stable policy and abstractions.
2849. Group components by cohesion and release pressure; do not group unrelated policy just because it shares a technical layer.
28510. Avoid component cycles; break cycles before they harden into deployment or test bottlenecks.
28611. Balance stability and abstraction: stable components should not depend on unstable details, and abstract components should have concrete reason to exist.
287
288---
289
290## Boundary Cost, Deployment, and Operations
291
2921. A boundary may be a source boundary, deployment boundary, process boundary, service boundary, or partial boundary.
2932. Choose the lightest boundary that preserves the needed independence.
2943. Use partial boundaries when a full deployment/runtime split is too expensive but future separation is valuable.
2954. Keep development, deployment, operation, and maintenance concerns visible without letting them own business policy.
2965. Do not combine unrelated use cases just because operational wiring is easier.
2976. Do not eliminate duplication when the shared code would couple use cases that change for different actors.
2987. Make architectural boundaries enforceable through package structure, tests, dependency rules, or build constraints.
299
300---
301
302## Services, Distribution, and Embedded Boundaries
303
3041. A service is not automatically an architectural boundary; source dependencies and data ownership still decide coupling.
3052. Remote calls must be treated as I/O boundaries, not as local method calls.
3063. Keep service listeners humble: translate external messages into use case calls and return through output boundaries.
3074. Keep embedded and hardware details behind interfaces so policy can be tested without the target device.
3085. Do not let real-time, firmware, database, web, or framework concerns pull policy outward.
309
310---
311
312## Naming Rules
313
314- Name modules and packages after business capabilities or use cases.
315- Name use cases with action verbs from the application's use cases.
316- Name ports by the role they play for the use case.
317- Name adapters by the external detail or delivery mechanism they adapt.
318- Avoid vague technical names when a use case, policy, boundary, presenter, controller, gateway, or entity role is more precise.
319- If a class is named `Service`, justify why it is not a use case, adapter, or domain object.
320
321---
322
323## Testing Rules
324
325### Core Tests First
326Prioritize tests for:
327- entities
328- use cases
329- boundary contracts
330
331These tests must:
332- run without the real framework
333- run without the real database
334- run without the network
335- run fast and deterministically
336
337### Adapter Tests
338Test adapters separately for:
339- mapping correctness
340- gateway behavior
341- controller translation
342- presenter formatting
343- integration with framework or external service
344
345Do not use slow integration tests as a substitute for testing business rules.
346
347### Test Through Supported Boundaries
348- Avoid reaching private internals when a public use case boundary exists.
349- Prefer testing use cases with fakes or mocks for ports.
350- Use integration tests only where architectural seams meet real details.
351
352---
353
354## Forbidden Patterns
355
356Do not generate or keep code that does any of the following unless explicitly required and justified.
357
358### Framework Leakage
359- domain entities annotated with database or web framework metadata when avoidable
360- use cases depending on `Request`, `Response`, controller base classes, framework sessions, or middleware objects
361- application layer importing serializer or database base classes
362
363### Database Leakage
364- use cases returning table rows or database-bound entities
365- domain rules embedded in gateway implementations or database access
366- domain objects designed primarily around persistence convenience
367
368### Controller-Centric Logic
369- controllers containing branching business rules
370- controllers performing validation that belongs to business policy
371- controllers calling gateways directly instead of use cases
372
373### God Services
374- large `*Service` classes that create, fetch, validate, persist, publish, and present everything
375- services that own unrelated use cases
376- application services that become dumping grounds
377
378### Layer Bypass
379- controllers bypassing use cases to call gateways
380- presenters reading directly from databases
381- infrastructure code importing inward and also being imported by domain code
382
383### Direction Violations
384- gateway interfaces defined in infrastructure and consumed by core policy
385- entities importing adapters
386- use cases depending on concrete implementations
387
388### Utility Dumping Grounds
389- generic utility, shared, base, or core folders used as architecture escape hatches
390- generic abstractions with no clear ownership
391- convenience modules that hide bad dependency direction
392
393---
394
395## Refactoring Rules
396
397When modifying existing code:
398
3991. **Move business rules inward**
400 - Extract domain logic from controllers, handlers, views, gateway classes, and jobs.
401
4022. **Introduce boundaries around details**
403 - Wrap external services, database access, message buses, filesystem operations, and clocks.
404
4053. **Replace concrete dependencies with ports**
406 - Define interfaces in inner layers.
407 - Implement them in outer layers.
408
4094. **Separate translation from policy**
410 - Request parsing, data mapping, serialization, and presentation formatting belong outside core business rules.
411
4125. **Break up god services**
413 - Split by use case.
414 - Give each use case one clear application action.
415
4166. **Eliminate framework coupling from tests**
417 - Rewrite tests to target use cases and entities directly where possible.
418
4197. **Preserve behavior while improving direction**
420 - Refactor incrementally.
421 - Prefer safe boundary extraction over large rewrites.
422
423---
424
425## Output Expectations
426
427When asked to implement a feature, default to producing:
428- a domain model or entity if business invariants exist
429- a focused use case
430- input and output models if needed
431- ports/interfaces for external dependencies
432- adapters for web, persistence, or messaging details
433- composition root wiring outside the use case
434
435When asked to modify existing code:
436- keep or improve dependency direction
437- avoid adding framework dependencies to inner layers
438- call out architectural debt explicitly if it cannot be fixed safely now
439
440When asked to review code:
441- identify boundary violations
442- identify dependency rule violations
443- identify framework leakage
444- identify misplaced business rules
445- identify god services and layer bypass
446- propose concrete refactorings toward Clean Architecture
447
448---
449
450## Review Checklist
451
452Before finalizing any change, verify:
453
454- Are business rules independent from frameworks?
455- Are use cases independent from delivery and persistence details?
456- Do source dependencies point inward?
457- Are controllers thin?
458- Are gateways just persistence adapters?
459- Are entities guarding domain invariants?
460- Are ports owned by inner layers?
461- Is composition happening at the edge?
462- Can core tests run without the web framework and database?
463- Does the project structure reflect the domain and use cases?
464- Did we avoid generic utility dumping grounds?
465- Did we avoid creating another god service?
466- Did we keep details replaceable?
467
468If any answer is no, revise the design before shipping.
469
470---
471
472## Preferred Default Shapes
473
474### Preferred feature shape
475- domain
476- application
477- adapters
478- infrastructure
479
480Or, if feature-oriented:
481- feature/domain
482- feature/application
483- feature/adapters
484- feature/infrastructure
485
486### Preferred use case shape
487- request model
488- use case
489- output boundary or response model
490- ports
491- adapter implementations outside
492
493### Preferred dependency pattern
494- inner layer defines interface
495- outer layer implements interface
496- composition root wires them together
497
498---
499
500## When Tradeoffs Are Necessary
501
502If constraints force a compromise:
503- keep the compromise at the outermost layer possible
504- document the boundary violation clearly in code comments or review notes
505- avoid normalizing the compromise into the core architecture
506- preserve a future path to separation
507
508Choose the design that minimizes long-term coupling, not the one that is only shortest today.
509
510---
511
512## Final Instruction
513
514When uncertain, choose the option that:
5151. keeps business rules independent
5162. points dependencies inward
5173. isolates details behind boundaries
5184. improves testability
5195. makes replacement of frameworks, databases, and delivery mechanisms easier
520
521If a proposed change conflicts with these priorities, reject it and propose a cleaner architectural alternative.