# Clean Arch

> Scaffolds and enforces hexagonal architecture with the Result pattern (no exceptions for expected failures) across backend, fullstack and web projects. Use this whenever the user starts a new backend, API, server or fullstack project; asks for hexagonal architecture, ports and adapters, clean architecture, a domain/application/infrastructure split, a pnpm monorepo, or a Result/Either error model instead of throwing; asks to add a feature, vertical, use case, port, adapter or endpoint to a project that already follows this layout; or asks to audit an existing repository for layering violations, inconsistent error-to-status mapping, or architecture rules that are silently not enforced. Also use when the user mentions Fastify, .NET, Spring or Go server scaffolding with a clean core.

- Skill: `enmanuelmag/clean-arch` (Agent Skill, multi-file: 159 files)
- Install (CLI): `npx skillmds@latest add enmanuelmag/clean-arch`
- Raw SKILL.md: https://api.skillmd.com/api/skills/enmanuelmag/clean-arch/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: enmanuelmag (https://skillmd.com/u/enmanuelmag)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/enmanuelmag/clean-arch

---


# clean-arch

Scaffolding and guidance for hexagonal architecture with the Result pattern. Distilled
from two production projects that converged, independently, on the same patterns.

## What it does and what it does NOT do

**Does:** generates the layer structure, the core (`Result`, error catalog, ports), the
mechanical enforcement of the boundary, the composition wiring, and the feature slices.
Audits existing repos against the same standard.

**Which school:** it prescribes Clean Architecture's layering — entities separate from use
cases — with Hexagonal's ports-and-adapters vocabulary at the edge, and it also supports
the single-core variant. Which one you get is an interview decision
(`--school clean|hexagonal` in `scripts/scaffold.mjs`, default `clean`).

**Does NOT:**
- It does not pick your business or write your domain rules. It generates the scaffolding,
  you supply the invariants.
- It does not replace `ahk init` or `autoskills`; it invokes them in the right order
  (§ Order of operations).
- It does not invent a new architecture. It reproduces a proven one, and tells you when to
  deviate.

## Modes

| Invocation | What it does |
|---|---|
| `/clean-arch` | Decision interview → recommends a preset and waits for confirmation |
| `/clean-arch fullstack` | Full preset: monorepo + server + web + deploy |
| `/clean-arch server` | Backend only: `packages/domain`, `packages/application`, `apps/api` |
| `/clean-arch web` | Frontend only, consuming an existing contract via codegen |
| `/clean-arch feature <name>` | New feature slice on an already scaffolded project — **the most used mode** |
| `/clean-arch audit` | Applies [references/audit-checklist.md](references/audit-checklist.md) to an existing repo and reports deviations |
| `/clean-arch explain <topic>` | Reads the reference and answers. Generates nothing |
| `/clean-arch tooling` | Bootstrap of ahk + autoskills only, on an existing project |

No argument → starts the interview.

## Stack interview

The default stack is: **TypeScript · pnpm workspace · Fastify 5 · Zod 4 · Prisma ·
PostgreSQL · Vite + React**.

Present it **whole and at once**, and ask whether it is confirmed as is or some piece
changes. Do not break it into twelve consecutive questions. Swappable pieces:

- **Server language** — TypeScript (default) · C#/.NET · Java/Spring · Go
- **Frontend** — Vite+React (default) · Next.js · TanStack Start · none
- **DB and ORM**, **auth**, **project shape**, **deployment**

Every decision, with its alternative and its real trade-off, is in
[references/decisions.md](references/decisions.md). Consult it when the user questions a
default; do not improvise the trade-off.

## Canonical order of operations

### Phase A — scaffolding

1. **Interview** → preset and decisions resolved.
2. **Resolve dependencies** — versions via Context7, never from memory (§ Delegation).
3. **`scripts/scaffold.mjs`** — generates the tree from `templates/`.
4. **`pnpm install`**.
5. **`npx autoskills@latest -y`** — detects the stack **by reading `package.json`**, which
   is why it goes **after** installing. Before that it has nothing to read.
6. **`scripts/bootstrap-tooling.mjs`** — `ahk init` / `ahk build`, with a fallback if missing.
7. **`health.sh`** must exit green before continuing.

### PHASE GATE — read before continuing

- If the project is **new** (its `.claude/` did not exist when the session started), the
  Claude Code watcher **does not cover it**: you must **restart the session inside the
  project** before implementing anything.
- If `.claude/` **already existed**, skills and agents are detected hot. Even so: a new
  `.mcp.json` **requires a restart**, and the block autoskills injects into `CLAUDE.md`
  is only re-injected after `/compact`.

Detail and diagnosis in [references/ops/agent-tooling.md](references/ops/agent-tooling.md).

### Phase B — feature slices

`feature <name>`, one at a time. Each slice touches the three layers in this order:
entity + errors → port → use cases + bundle → adapter → schema/DTO → route →
tests. Never the other way round: the adapter before the port produces a Prisma-shaped port.

## References

Each line states **when** to read it. Do not load them all at once.

### Core — language-agnostic

- **[references/core/01-layers.md](references/core/01-layers.md)** — The three layers, the dependency direction, the composition root and the directory structure. **Always read it** before creating a new file, to know where it goes.
- **[references/core/02-result-pattern.md](references/core/02-result-pattern.md)** — The `Result` type, the propagation idiom and the three sanctioned exceptions to no-throw. **Always read it** before writing any use case or adapter.
- **[references/core/03-error-catalog.md](references/core/03-error-catalog.md)** — Closed catalog of codes, per-aggregate factories, messages as a wire contract. **Read it** when defining new errors or when you see a per-feature error `enum`.
- **[references/core/04-use-cases.md](references/core/04-use-cases.md)** — Factory-returning-function, `Deps`/`Input`, per-slice bundle and its surface as a security decision. **Read it** on every `feature <name>`.
- **[references/core/05-ports-adapters.md](references/core/05-ports-adapters.md)** — What a port is, invariants in doc-comments, when to split it, the row→entity seam. **Read it** before touching persistence or any external service.
- **[references/core/06-dto-mapping.md](references/core/06-dto-mapping.md)** — Anatomy of the schema file, `toXDto`/`toXInput`, `present<T>()` and correct PATCH. **Read it** when writing the HTTP layer of a slice.
- **[references/core/07-testing.md](references/core/07-testing.md)** — The port fake with `calls`/`failWith`/`guard`, the `subject()` helper, which layer is tested how. **Read it** before writing the first test of a slice.
- **[references/core/08-boundary-enforcement.md](references/core/08-boundary-enforcement.md)** — The three layers of defence and the mandatory negative test. **Always read it** when scaffolding, and **mandatorily** if you touch the linter config.

### Stacks — per-language detail

- **[references/stacks/ts-fastify-prisma.md](references/stacks/ts-fastify-prisma.md)** — The default stack. Read it if the server is TypeScript.
- **[references/stacks/csharp-dotnet.md](references/stacks/csharp-dotnet.md)** — Read it only if the server is .NET.
- **[references/stacks/java-spring.md](references/stacks/java-spring.md)** — Read it only if the server is Spring.
- **[references/stacks/go-chi.md](references/stacks/go-chi.md)** — Read it only if the server is Go.

### Frontends

- **[references/frontends/vite-react.md](references/frontends/vite-react.md)** — Default SPA.
- **[references/frontends/nextjs.md](references/frontends/nextjs.md)** — If there is SSR/RSC.
- **[references/frontends/tanstack-start.md](references/frontends/tanstack-start.md)** — If full-stack type-safe routing was requested.

### Operations

- **[references/ops/deployment.md](references/ops/deployment.md)** — Containers, single proxy, monorepo build context. Read it when preparing the deployment.
- **[references/ops/quality-gates.md](references/ops/quality-gates.md)** — `health.sh`, CI, per-workspace script coverage. Read it when scaffolding and when auditing.
- **[references/ops/config-env.md](references/ops/config-env.md)** — Variables by trust boundary, environment validation, secret leakage into the bundle. Read it before adding any variable.
- **[references/ops/agent-tooling.md](references/ops/agent-tooling.md)** — ahk, autoskills, and why you sometimes have to restart the session. Read it at the phase gate.

### Cross-cutting

- **[references/decisions.md](references/decisions.md)** — The ~12 interview decisions with their trade-off. Read it in interview mode or when someone questions a default.
- **[references/audit-checklist.md](references/audit-checklist.md)** — Actionable checklist with concrete commands. Read it in `audit` mode.

## Scripts

| Script | What for |
|---|---|
| `node scripts/scaffold.mjs <preset>` | Generates the preset tree from `templates/` |
| `node scripts/new-feature.mjs <name>` | New slice across the three layers + tests |
| `node scripts/check-boundaries.mjs` | **Negative test**: injects a forbidden import and requires the lint to fail |
| `node scripts/check-env-secrets.mjs` | Detects privileged credentials exposed to the client bundle |
| `node scripts/check-coverage.mjs` | Verifies that every workspace declares `typecheck`/`build`/`test`/`lint` or a documented exemption |
| `node scripts/bootstrap-tooling.mjs` | ahk init/build + autoskills, with a fallback |

Templates in `templates/_root/`, `templates/packages/`, `templates/apps/`,
`templates/deploy/`, `templates/feature/`.

## Delegation: library versions and APIs

**There is no version knowledge embedded in this skill, and you must not add any.**
For the current API, configuration or syntax of Fastify, Prisma, Zod, React, Vite,
EF Core, Spring or any other dependency, consult **Context7 MCP**
(`resolve-library-id` → `query-docs`) before writing the code. The references in
`references/core/` describe the *pattern*, which does not expire; versions do.

