← ClaudeAtlas

dependency-directionlisted

Enforce the @repo/* import direction in a Turborepo workspace. Concrete violations + fixes. Composes with core:hexagonal-architecture and the boundary-direction-check hook.
voidcorp-core/void-harness · ★ 0 · Code & Development · score 76
Install: claude install-skill voidcorp-core/void-harness
# dependency-direction Use when adding an `import` statement that crosses a package boundary, or when fixing a `boundary-direction-check` hook violation. This skill is the **operational guide** for the rules core `hexagonal-architecture` and `boundary-direction-check` enforce mechanically. ## The rule ``` @repo/core → nothing internal @repo/auth → @repo/core @repo/db → @repo/core @repo/ui → @repo/core @repo/<feat> → @repo/core (and only @repo/core) apps/<app> → any @repo/* ``` **No `@repo/*` package imports another `@repo/*` except `@repo/core`.** All composition happens at the app level. If `@repo/billing` needs the user, it defines a port; the consuming app wires `@repo/auth`'s adapter into that port. This sounds restrictive. It is. It is what keeps the monorepo from collapsing into a hairball. ## Why core is the only allowed dependency `@repo/core` ships **primitives** with no internal deps: - `logger` (pino) - `env` (Zod-validated env) - `errors` (typed error classes) - `Result`, `Option`, `pipe` (functional utilities) These are leaf utilities. Everything else is composition. ## Common violation: `@repo/billing` wants the user **Wrong**: ```ts // packages/billing/src/billing.service.ts import { db } from '@repo/db'; // ✗ import { getCurrentUser } from '@repo/auth'; // ✗ export async function cancelSubscription() { const user = await getCurrentUser(); await db.update(subscriptions)... } ``` **Right** —