Diablo_ClaudeMD_Ricing_example/skills/tdd/references/layer_guide.md
diablo 50fa79407d
Some checks are pending
CI — CoM Config Validation / Validate JSON Configs (push) Waiting to run
CI — CoM Config Validation / Validate YAML Configs (push) Waiting to run
CI — CoM Config Validation / Lint Shell Scripts (push) Waiting to run
CI — CoM Config Validation / Secret Detection (push) Waiting to run
CI — CoM Config Validation / Lint Markdown (push) Waiting to run
CI — CoM Config Validation / Validate CODEOWNERS (push) Waiting to run
CoM Claude Command Center — sanitized public configuration
Public, sanitized mirror of an AI orchestration command center: agents, skills,
MCP servers, slash-command workflows. All infrastructure identifiers, hostnames,
mesh IPs/subnets, repo paths, maintainer identity, and hardware fleet specifics
scrubbed to <placeholders>; session debug logs and host-specific memory removed.
No live credentials. Verified clean by automated leak sweep. See SANITIZATION.md.

churchofmalware.org . authorized research only
2026-06-10 02:02:03 -04:00

4.0 KiB

DDD / Onion Layer Reference

Compact reference for layer-aware TDD. Not a DDD textbook — just enough for agents to enforce dependency direction and choose the right test strategy.

Why This Matters (Research-Backed)

  • AI-generated code without architectural constraints produces 80% dependency violation rates in hexagonal architecture (arXiv:2512.04273, 2025). Layer constraints in agent prompts directly counteract this.
  • Static tools detect only ~77% of dependency violations on average (Pruijt et al., 2017). Our refactorer supplements tooling by checking imports + transitive deps during code review.
  • Test-driven prompting improves LLM code generation accuracy by 38-45% (Naik et al., 2024). RED-first with focused prompts is empirically better than spec-first.
  • TDD alone doesn't automatically improve design (Turhan et al., 2017). The REFACTOR phase with dependency checks is essential, not optional — it's where architectural quality emerges.

Layer Definitions (Inside → Outside)

Domain Model (Core)

  • Entities, Value Objects, Aggregates, Domain Events
  • ZERO external dependencies (no ORM, no HTTP, no frameworks)
  • Test with: direct construction, no mocks
  • Example: User entity with email validation, Money value object with currency math

Domain Services

  • Complex operations spanning multiple aggregates
  • Depends on: Domain Model only (+ interfaces for ports it needs)
  • Test with: real domain objects, in-memory fakes for repository interfaces
  • Example: RegistrationService checking uniqueness via a repository interface

Application Services (Use Cases)

  • Orchestrate domain logic, handle transactions, coordinate side effects
  • Depends on: Domain Model + Domain Services
  • Defines port interfaces that infrastructure will implement
  • Test with: in-memory fakes for all ports/repositories
  • Example: RegisterUserUseCase coordinating validation, persistence, email notification

Infrastructure & Presentation

  • DB access, external APIs, controllers, CLI handlers, adapters
  • Depends on: all inner layers (implements their interfaces)
  • Test with: integration tests, may use real dependencies or test containers
  • Example: PostgresUserRepository implementing UserRepository interface

Port Interface Placement

Ports (interfaces that abstract external dependencies) are defined by the layer that consumes them, not the layer that implements them:

  • A UserRepository interface consumed by a domain service lives in domain/ports/ or domain-service/ports/
  • A NotificationService interface consumed by an application use case lives in application/ports/
  • Infrastructure implements these interfaces but never defines them

Rule: the consumer defines the contract; the provider fulfills it. This is the Dependency Inversion Principle.

Dependency Rule

Dependencies flow INWARD only. Inner layers define interfaces (ports); outer layers implement them (adapters).

Infrastructure → Application → Domain Services → Domain Model
     ↓               ↓               ↓                ↓
  implements     orchestrates     uses real        pure logic
  interfaces     via ports        domain objects   no imports

Violation example: domain/user.py importing from infrastructure.db import Session — domain must never import infrastructure.

Layer Detection Heuristics

When classifying a slice, ask:

  1. Does it involve only business rules with no I/O? → domain
  2. Does it coordinate multiple domain objects but still no I/O? → domain-service
  3. Does it orchestrate a workflow (validate, persist, notify)? → application
  4. Does it talk to a database, HTTP API, file system, or framework? → infrastructure

Test Strategy by Layer

Layer Mocks/Fakes Framework imports I/O allowed
domain None None No
domain-service In-memory fakes for ports None No
application In-memory fakes for all ports Minimal (DI container) No
infrastructure Optional (real deps or test containers) Yes Yes