enhance-arch-boundaries · git:20260818.6723100 · 2026-08-18 · sha256 703b9348b7d3b3ab
enhance-arch-boundaries git:20260818.6723100A
Immutable. This exact content never changes and is served at /api/v1/blob/703b9348b7d3b3ab.
--- name: enhance-arch-boundaries description: > Install mechanically-enforced architecture boundaries (dependency-cruiser / eslint-boundaries) so layer direction, feature isolation, and forbidden imports fail CI. Use when "enforce module boundaries", "stop spaghetti imports", "add architecture rules". Advisory audit → audit-backend-architecture. license: MIT --- # enhance-arch-boundaries — Architecture as a fitness function Codify the repo's intended structure as rules that block merge. **Import spaghetti is how agents degrade architecture: each import looks locally reasonable, no single diff is wrong, and after forty sessions the layering is gone.** A rule in AGENTS.md is advisory. A dependency-cruiser rule in the aggregator gate is physics. ## This skill vs neighbors | Skill | Owns | |---|---| | **enhance-arch-boundaries** (this) | Mechanical boundary rules + shrink-only baseline | | `audit-backend-architecture` | Advises which pattern to adopt — does not enforce | | `housekeep-gates` | Wires this check into the aggregator | | `docs-adr` | Records *why* the model was chosen | | `enhance-agent-guardrails` | Broader guard install; this owns the import graph | --- ## Phase 0 — Recover the intended architecture (do not invent one) The rules must encode the architecture the repo *means* to have. - Read folder structure and existing conventions (`features/*`, `app/`, `lib/`, `server/`, `components/`, monorepo packages). - Read `audit-backend-architecture` output if it exists — that is the drift to stop. - Confirm with the user in one pass: layers and allowed direction (e.g. `ui → application → domain → infrastructure`, never reverse), feature units that must stay isolated, special zones (server-only, secrets, generated). State the model in ten lines before writing any rule. If the repo genuinely has no intended structure, **stop and say so** — enforcing a structure nobody chose creates fights, not quality. Propose a minimal layering first. --- ## Phase 1 — Install the rule set Tool by stack: **dependency-cruiser** (framework-agnostic JS/TS), **eslint-plugin-boundaries** (when living inside ESLint is preferable), Nx module-boundary tags, import-linter (Python). Core rules, each mapped to the confirmed model: - **Layer direction** — lower layers cannot import upward; skipping layers flagged where the model says so. - **Feature isolation** — features import each other only via a public surface (`features/x/index.ts`), never deep paths. Shared code goes through `shared/`, not sideways. - **No circular dependencies** — anywhere. Cycles are where "change one thing" stops being possible. - **Forbidden edges** — client importing server-only / service-role modules (cross-ref `plan-rls-audit` / `plan-secrets-audit`), UI importing the DB layer directly, production importing test utilities, anything importing generated internals. - **No orphans** — modules nothing reaches (feeds `workflow-housekeep`). - **Dependency hygiene** — no `devDependencies` from shipped code; deprecated internals marked un-importable so migration ratchets. --- ## Phase 2 — Grandfather, then ratchet Do not weaken the rules to fit existing violations, and do not block the repo on fixing them all. - Capture existing violations into the tool's **known-violations baseline** so CI is green today. - The baseline is a **shrink-only ratchet**: new violations fail; existing ones are tracked debt; the baseline file can only get smaller without review — same reset policy as `housekeep-gates`. - File the grandfathered list as a burndown, worst edges first (cycles and client→server-secrets before cosmetic layer skips). --- ## Phase 3 — Wire and make agent-legible - Add the check to CI wired into the aggregator gate (`housekeep-gates`) and mirror it in local hooks (same command, two callers). - Generate the dependency **graph visualization** into docs; regenerate it on the scheduled run so it cannot go stale. - Write the ten-line model + "how to fix a boundary violation" into agent rules *referencing the mechanical check* — the rule text explains, the gate enforces. - Record the architecture decision as an ADR (`docs-adr`) so a future session knows the layering was chosen, by whom, and why the rejected alternative lost. --- ## Definition of Done - [ ] Intended model recovered from the repo + confirmed with the user (or the no-structure finding raised) - [ ] Rules installed: layer direction, feature isolation via public surfaces, no cycles, forbidden edges (incl. server-only → client), no orphans, dep hygiene - [ ] Existing violations grandfathered into a shrink-only baseline; burndown filed worst-first - [ ] Check in the aggregator gate + local hooks with one shared command - [ ] Graph visualization generated into docs with a regeneration schedule - [ ] Agent rules updated to state the model and point at the gate; decision recorded via `docs-adr` - [ ] Deliberate-violation probe: a test import that breaks each rule class fails CI ## Output format 1. **Architecture model** — ten-line statement of layers, directions, features, special zones 2. **Rule set** — rule | what it forbids | why (mapped to the model) 3. **Grandfathered baseline** — count by rule | worst-first burndown 4. **Wiring** — gate job, hook parity, graph location, agent-rule text added 5. **Probe evidence** — violation per rule class | CI result Applied directly (enhance-family). Pause for approval only on the model confirmation and before committing the baseline.