Disciplines · Conventions

Code Conventions Ratchet

job.

3sections2 minread

On this page

Enforcement mechanism for two 2026-07-16 monorepo-architecture-audit findings that could not be closed by a one-shot migration:

  • R-11 (DRY / shared-lib adoption): the canonical platform layer exists (@oshun/logging, @oshun/database, @oshun/cache, @oshun/config), but hundreds of files predate it and re-implement or bypass it. Migrating them is per-domain feature work; what must not happen is the debt growing.
  • F-1 (test-file suffix): the workspace convention is colocated *.spec.ts (the plurality at audit time). ~12.6k *.test.ts files are grandfathered; renaming them wholesale would churn thousands of vitest configs and diffs for no behavioral gain.

Mechanism#

tools/conventions/check-conventions-ratchet.mjs runs in the ci.yml quality job. It compares the current tree against the committed baseline (tools/conventions/conventions-ratchet-baseline.json):

Rule Kind Fails when Fix
raw-pino-import file set a file not in the baseline imports pino directly (outside libs/shared) import from @oshun/logging
raw-pg-pool file set a new file constructs new Pool( from pg use @oshun/database
raw-ioredis-client file set a new file constructs new Redis( from ioredis use @oshun/cache
direct-process-env file set a new production file reads process.env directly use @oshun/config (typed schema)
local-circuit-breaker-class file set a new file defines its own CircuitBreaker class use @oshun/resilience
local-sleep-def file set a new file defines its own sleep/delay use @oshun/resilience
test-dot-test-suffix count the tracked *.test.ts(x) count under libs/+apps/ grows name new test files *.spec.ts

File-set rules are strict set-ratchets: a new file entering the set fails CI even if another file left it. Existing (grandfathered) files pass; migrating one off the raw dependency is always welcome.

Tightening#

When a change removes grandfathered occurrences, tighten the baseline in the same PR:

bash
node tools/conventions/check-conventions-ratchet.mjs --update-baseline
git add tools/conventions/conventions-ratchet-baseline.json

The checker prints a reminder whenever counts drop below the baseline.

Scope notes#

  • Tests (*.spec.ts, *.test.ts, __tests__/), *.config.ts, and e2e trees are excluded from the shared-lib rules — test doubles and config loaders at dependency boundaries are legitimate.
  • libs/shared/** is excluded: the shared layer is where the raw dependencies are supposed to live.
  • Related policy: docs/conventions/server-frameworks-and-deps.md (sanctioned frameworks and overlapping-dependency policy, audit R-17).