Recurring complexity violations and the rules that prevent them
Keep the codebase simple. These rules come from real violations found in this repository. Code review should check for each of them.
If an app needs a helper that a package already has, export it from the package and import it. Do not copy the code into the app. The app once carried byte-identical copies of the audit helpers from @concourse/auth; they drifted apart the moment one side changed.
Do not build generic, configurable modules for a handful of callers. Write the direct version first. Add options only when a real second caller needs them, and delete options no caller uses.
A file that holds one small function, plus a test file for it, is two files of overhead for one line of logic. Group small helpers into a domain module (for example lib/auth/http.ts) with one test file. Delete helpers nothing imports.
If a fact can be checked by introspection (for example Drizzle table configs) or by a verify task (for example pnpm db:diff), do not also assert it with regexes over generated SQL or other build output. Regex tests break on formatting changes and prove nothing extra. Reserve text assertions for facts only the text can show, like "the baseline migration contains no destructive statements."
Export a symbol only when another module imports it. When a symbol is used only inside its own file, remove export. Delete symbols nothing uses at all. Exceptions must be forced by the compiler (for example a type that consumers must be able to name) and should carry a comment saying so.
When the same list or block repeats across a configuration file, move it to the shared level. Environment variables that most tasks read belong in globalEnv in turbo.json, not copied into each task. Shared lint rules belong in one config that others extend.
These larger items are known and deferred, not endorsed:
packages/infra/src/bootstrap.ts is a single very large file of one-shot bootstrap phases. It should be split into one module per phase.apps/docs.concourse and apps/docs.tredis share most of their files byte for byte. The shared parts should move into a package.Recurring complexity violations and the rules that prevent them
Keep the codebase simple. These rules come from real violations found in this repository. Code review should check for each of them.
If an app needs a helper that a package already has, export it from the package and import it. Do not copy the code into the app. The app once carried byte-identical copies of the audit helpers from @concourse/auth; they drifted apart the moment one side changed.
Do not build generic, configurable modules for a handful of callers. Write the direct version first. Add options only when a real second caller needs them, and delete options no caller uses.
A file that holds one small function, plus a test file for it, is two files of overhead for one line of logic. Group small helpers into a domain module (for example lib/auth/http.ts) with one test file. Delete helpers nothing imports.
If a fact can be checked by introspection (for example Drizzle table configs) or by a verify task (for example pnpm db:diff), do not also assert it with regexes over generated SQL or other build output. Regex tests break on formatting changes and prove nothing extra. Reserve text assertions for facts only the text can show, like "the baseline migration contains no destructive statements."
Export a symbol only when another module imports it. When a symbol is used only inside its own file, remove export. Delete symbols nothing uses at all. Exceptions must be forced by the compiler (for example a type that consumers must be able to name) and should carry a comment saying so.
When the same list or block repeats across a configuration file, move it to the shared level. Environment variables that most tasks read belong in globalEnv in turbo.json, not copied into each task. Shared lint rules belong in one config that others extend.
These larger items are known and deferred, not endorsed:
packages/infra/src/bootstrap.ts is a single very large file of one-shot bootstrap phases. It should be split into one module per phase.apps/docs.concourse and apps/docs.tredis share most of their files byte for byte. The shared parts should move into a package.