agentleFS
nledfordnledford/engineering-review-board/skills/hexagonal-architecture/SKILL.md

hexagonal-architecture

Skill11 starsChanged 10 days agoMITView on GitHub

Hexagonal Architecture / Ports and Adapters guidance centered on how external actors drive or are driven by an application through explicit inbound and outbound ports and adapters. Use when classifying port ownership, replacing delivery or infrastructure mechanisms, or testing the core through those seams. Use clean-architecture when entities, use cases/interactors, and interface-adapter policy flow are primary, onion-architecture for explicit concentric domain/application rings, and architecture-review for a read-only audit. Do not use for simple CRUD, prototypes, or trivial pass-through interfaces.

24 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use layered-architecture, improve-codebase-architecture and 1 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • dkprogSkill

    layered-architecture

    Apply when structuring a backend service, creating new modules, or deciding where to place business logic. Ensures separation into transport, domain, and data access layers with correct dependency direction.

    Also in 3 projects that use this

  • GoogleSkill

    improve-codebase-architecture

    Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.

    Also in 3 projects that use this

  • GoogleSkill

    grill-me

    A relentless interview to sharpen a plan or design.

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. 0 are common, 13 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 23 edited versions we read keep these.

  • 13

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use Hexagonal Architecture, also called Ports and Adapters, to keep business rules independent from delivery mechanisms and infrastructure.

    line 8
  2. Distinctive:

    Do not force it for:

    line 30
  3. Distinctive:

    Keep transport, persistence, SDK, framework, and serialization types out of domain model APIs.

    line 49
  4. Distinctive:

    Identify the core: Put business invariants and decisions in domain entities, value objects, aggregates, and domain services.

    line 58
  5. Distinctive:

    Test by boundary: Test domain behavior directly.

    line 77
  6. Distinctive:

    When implementation begins, load the matching language engineering skill and any data skill needed for persistence, schema, query, or …

    line 82
  7. Distinctive:

    Before reporting completion, check the changed behavior plus inbound/outbound port contracts, adapter mappings, and inward dependencies.

    line 87
  8. Distinctive:

    Prefer domain unit tests for invariants and state transitions.

    line 107
  9. Distinctive:

    Use application/use-case tests with fake outbound ports for workflow behavior, failure paths, and side effects.

    line 108
  10. Distinctive:

    Use contract tests when multiple adapters must satisfy the same port.

    line 110
  11. Distinctive:

    Use integration tests for real adapters: database mappings, SQL constraints, message serialization, HTTP client behavior, SDK error …

    line 111
  12. Distinctive:

    Avoid mocking the domain model.

    line 114
  13. Distinctive:

    Do not switch terminology if the code already has healthy dependency boundaries.

    line 133

“Common” is measured: kept by at least 6 in 10 of the 23 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Hexagonal Architecture

Use Hexagonal Architecture, also called Ports and Adapters, to keep business rules independent from delivery mechanisms and infrastructure. DDD helps define what belongs inside the business-centered core; Hexagonal Architecture keeps that core isolated from external mechanisms.

Use When

Apply this skill when the work involves:

  • A complex or long-lived domain with meaningful business rules.
  • DDD-style entities, value objects, aggregates, repositories, domain services, domain events, bounded contexts, or ubiquitous language.
  • Multiple delivery mechanisms such as HTTP APIs, CLIs, jobs, message consumers, scheduled tasks, or UI flows invoking the same behavior.
  • External systems that should be swappable or testable behind seams: databases, ORMs, message brokers, HTTP clients, cloud SDKs, file systems, clocks, ID generators, payment gateways, email senders, or vendor APIs.
  • Tests that should exercise domain behavior or use cases without real infrastructure.
  • Refactors where framework, persistence, SDK, or transport types are leaking into domain APIs.

Do not force it for:

  • Simple CRUD apps with little domain behavior.
  • Prototypes, throwaway scripts, short-lived automation, or tiny tools.
  • Codebases where framework conventions are intentionally the architecture.
  • Features that do not yet justify ports and adapters unless they are likely to grow across delivery or infrastructure boundaries.
  • Trivial functions where a port would only forward parameters to one concrete implementation.

Dependency Rule

  • The domain/application core must not depend directly on frameworks, databases, ORMs, message brokers, HTTP clients, cloud SDKs, UI layers, or vendor APIs.
  • External systems interact with the core through ports and adapters.
  • Ports are contracts at the application boundary. Adapters implement or invoke those contracts outside the core.
  • Dependency inversion points inward: adapters depend on ports/core, not the reverse.
  • Keep transport, persistence, SDK, framework, and serialization types out of domain model APIs. Map them at adapter boundaries.

Workflow

  1. Confirm the architecture earns its cost. Name the business behavior, expected lifetime, delivery mechanisms, external dependencies, and testing needs. If the change is simple CRUD, keep it simple and leave refactoring seams rather than adding unused ports.
  2. Identify the core. Put business invariants and decisions in domain entities, value objects, aggregates, and domain services. Put workflow orchestration in application services or use cases.
  3. Define inbound entry points. Controllers, routes, CLIs, jobs, schedulers, message consumers, and UI actions are inbound adapters. They should translate input, authorize and validate at the trust boundary, call an application use case or inbound port, and map the result to transport output.
  4. Define outbound ports only for real boundaries. Persistence, messaging, external API clients, clocks, ID generators, payment gateways, email senders, file systems, and SDK integrations are outbound capabilities. Create a port when the core needs the capability but should not know the mechanism.
  5. Implement adapters outside the core. Database repositories, HTTP clients, queue publishers, mailers, filesystem adapters, SDK wrappers, and telemetry integrations implement outbound ports. Keep their DTOs, rows, errors, retries, transactions, and vendor details at the edge.
  6. Map deliberately. Convert request/response DTOs, ORM rows, JSON payloads, SDK objects, database errors, and framework errors to application/domain types at boundaries. Do not let mapping logic smuggle business policy into adapters.
  7. Test by boundary. Test domain behavior directly. Test use cases with fake or in-memory outbound adapters. Test adapters against their real framework, database, broker, or SDK contract. Add end-to-end tests only for behavior that narrower tests cannot prove.

When implementation begins, load the matching language engineering skill and any data skill needed for persistence, schema, query, or transaction work.

Verification And Reporting

Before reporting completion, check the changed behavior plus inbound/outbound port contracts, adapter mappings, and inward dependencies; then run broader repository checks when the change warrants them. Report failures, skipped checks, and residual risk from unverified adapters, contracts, or infrastructure wiring.

Layer Responsibilities

  • Domain objects: enforce invariants, state transitions, calculations, policies, and domain events. They should be framework-independent.
  • Application services/use cases: coordinate a workflow, transaction boundary, authorization decision handoff, port calls, and domain operations. They should not contain low-level persistence or transport code.
  • Inbound adapters: HTTP handlers, controllers, CLIs, jobs, schedulers, message consumers, UI event bridges, and server functions.
  • Outbound adapters: repository implementations, database gateways, external service clients, queue publishers/producers, email senders, file stores, payment clients, clocks, ID generators, cache clients, and cloud SDK wrappers.

Testing Guidance

  • Prefer domain unit tests for invariants and state transitions.
  • Use application/use-case tests with fake outbound ports for workflow behavior, failure paths, and side effects.
  • Use contract tests when multiple adapters must satisfy the same port.
  • Use integration tests for real adapters: database mappings, SQL constraints, message serialization, HTTP client behavior, SDK error mapping, and framework wiring.
  • Avoid mocking the domain model. Mock or fake slow, nondeterministic, external, or infrastructure boundaries.

Relationship To Other Design Skills

  • DDD: DDD defines the model, invariants, repositories, bounded contexts, and language inside the core. Hexagonal Architecture protects that model from infrastructure leakage.
  • BDD: BDD scenarios describe behavior at the system or use-case boundary. Step definitions should usually drive a public API, inbound adapter, or use case rather than internal classes or database rows.
  • TDD: TDD can drive domain objects and use cases before real infrastructure exists by substituting fake adapters for outbound ports.
  • Clean Architecture: shares the inward dependency rule and core isolation goal. Load clean-architecture when the main decision is concentric policy/detail layers, use-case/interactor boundaries, presenters, DTOs, and interface-adapter responsibilities. Prefer Hexagonal wording when the main decision is ports and adapters around external actors. Do not switch terminology if the code already has healthy dependency boundaries.
  • Onion Architecture: shares the inward dependency rule and domain-centered goal. Load onion-architecture when the main decision is domain/application rings and infrastructure outside those rings, especially in DDD-heavy code.

Anti-Patterns

  • Domain objects depend on ORM annotations, framework base classes, SDK models, request objects, response objects, or database row shapes when avoidable.
  • Controllers, handlers, components, jobs, or step definitions contain business rules that belong in domain objects or use cases.
  • Repositories or adapters decide business policy instead of translating between infrastructure and domain/application contracts.
  • Infrastructure errors, transaction handles, query builders, HTTP clients, or serialization types leak into core APIs.
  • A port is created for every trivial function without a real boundary, alternate implementation, testing need, or external mechanism to isolate.
  • Domain models are anemic: all behavior lives in services while entities only store data.
  • Simple CRUD is over-engineered with excessive abstractions before business rules, multiple mechanisms, or testability needs justify them.

Successful Use

The final design names the core behavior, application use cases, inbound adapters, outbound ports, concrete adapters, mapping points, dependency direction, tests per boundary, and any deliberate choice to keep a simpler non-hexagonal structure.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.