ai-superpower/.ai/instructions/skills/clean-architecture.instructions.md
moilanik a85c7dc0fb feat: add clean-code, clean-architecture and helm skills; fix .gitignore
New skill files:
- clean-code.instructions.md — naming, functions, classes, error handling,
  formatting, DRY/KISS/SOLID, Helm YAML conventions
- clean-architecture.instructions.md — dependency rule, layers, boundaries,
  SOLID foundation, Helm as outermost layer
- helm.instructions.md — resource ownership, values hygiene, required vs
  defaults, umbrella chart pattern, two-file values layering, KISS principle,
  hook ordering, config files pattern, dependency caching, template testing

Register all three in ai-root-instructions.md skills list and routing table.

Remove .ai from .gitignore — .ai/ is the product in this repo and must be
tracked; the apply.sh skip-by-marker mechanism prevents changes to other repos.
2026-03-04 09:54:07 +02:00

4.4 KiB

Clean Architecture

Based on Robert C. Martin's Clean Architecture. Apply these principles when designing systems, services, and infrastructure — including Helm chart structure and Kubernetes deployments.


The Dependency Rule

Source code dependencies point only inward. Inner layers define interfaces; outer layers implement them.

[ Frameworks & Drivers ]   ← outermost: UI, DB, APIs, Helm, K8s
    [ Interface Adapters ]  ← controllers, presenters, gateways
        [ Use Cases ]        ← application business rules
            [ Entities ]     ← enterprise business rules (innermost)
  • Inner layers know nothing about outer layers
  • Data crossing a boundary is always in the form the inner layer prefers — never a raw DB row or HTTP request object
  • If an outer layer changes (swap MySQL for Postgres, REST for gRPC), the inner layers are untouched

Layers

Entities — Core Business Rules

  • Enterprise-wide business objects with their validation and invariants
  • Pure domain models: no framework imports, no DB annotations, no HTTP concepts
  • Stable — change only if fundamental business rules change

Use Cases — Application Business Rules

  • Orchestrate entities to fulfil one actor's goal: TransferMoneyUseCase, ProvisionClusterUseCase
  • Define input/output via interfaces owned by this layer — no knowledge of controllers or DB implementations
  • One use case = one reason to exist

Interface Adapters

  • Convert data between use cases and the outside world
  • Controllers translate HTTP/CLI input → use case input models
  • Gateways implement repository interfaces defined by use cases
  • Presenters format use case output → UI/API response format

Frameworks & Drivers

  • The outermost ring: web frameworks, ORMs, message brokers, Kubernetes, Helm
  • These are details — they plug into the system via the adapters; the core doesn't know they exist

SOLID as the Foundation

  • SRP — one module, one actor, one reason to change
  • OCP — extend behaviour through new implementations, not modification of existing code
  • LSP — subtypes must honour the contracts of their interfaces
  • ISP — prefer narrow, focused interfaces over fat ones
  • DIP — high-level policy depends on abstractions; low-level detail implements them

Boundaries

  • Boundaries are where the power lives — they isolate components so that one side can change without affecting the other
  • Define boundaries at the most volatile points: DB, UI, external services
  • Cross a boundary only via an interface; never pass a concrete type across

What This Means in Practice

  • Business rules have no imports from frameworks, ORMs, or infrastructure libraries
  • Tests of use cases and entities need no running database, no HTTP server, no cluster
  • Swapping the database or the delivery mechanism (REST → gRPC, monolith → microservices) touches only the outer rings
  • "Screaming architecture" — the top-level structure should reflect the use cases, not the framework: invoice/, user/, payment/ not controllers/, models/, views/

In Helm and Kubernetes

Clean Architecture applies to how infrastructure is organised, not just application code.

Helm charts are the outermost layer — they are the delivery mechanism, not the system.

  • A chart should deploy exactly one service or one cohesive unit — not a bundle of unrelated things
  • Business rules belong in application config (values.yaml keys mapped to env vars); they must not be hardcoded in templates
  • Separate concerns across charts: one chart for the app, separate charts (or dependencies) for databases, queues, and shared infrastructure
  • A chart change (resource limits, replica count, ingress rules) must never require touching application business logic
  • Use _helpers.tpl as the adapter layer — it translates chart-level abstractions into Kubernetes primitives; templates themselves stay thin
  • Environments (values-dev.yaml, values-prod.yaml) are driver-layer configuration — they override defaults without touching templates
  • Test charts with helm template + schema validation; business logic is tested independently of the chart

Dependency Rule for Helm:

  • App charts depend on library charts, not the reverse
  • Library charts define interfaces (helpers, common labels); app charts implement them
  • Avoid circular chart dependencies — they indicate a missing layer or a misplaced responsibility