Skip to main content

One command

Runs, in order: format:checkcheck:alltest:scriptslinttypechecktestbuild, and reports all failures at the end so you fix everything in one pass. It runs on the host Node toolchain — no Docker and no Postgres — because unit and component tests mock the database. That means it works in Docker-less web sessions too. Every step must exit 0.

The guards

npm run check:all runs every guard: Each guard exists because a specific class of defect reached review more than once.

Git hooks

Installed on npm install: Bypass with --no-verify when you have a reason. The hooks are a safety net, not the gate.

CI is change-aware

CI classifies the PR’s changed files:
A separate Quality Gate job verifies that every skip was sanctioned by that classification and fails closed otherwise, so the fast path can never weaken the gate for a code change. The classifier fails closed on an empty file list, too: misclassifying code as docs would silently skip the gate, while misclassifying docs as code merely costs runner minutes.

Working with the fast path

  • Docs-only pushes may run gate:fast instead of the full gate. A diff the classifier reports as docs_only=true cannot affect tests or the build, so running them locally proves nothing. This is the only sanctioned exception.
  • Do not dilute a docs-only PR. One code file forfeits the fast path for the whole PR. Ship documentation changes separately when they are not coupled to code — but a genuinely coupled change (a new rule plus the guard that enforces it) stays in one PR.
  • Do not drive-by edit prisma/ in unrelated PRs; any file under it pulls in the Postgres leg.
  • When extending the docs-only pattern list, change scripts/classify-pr-paths.sh and its test file together. Misclassifying code as docs is the failure mode those tests exist to prevent.

Before every commit

The pre-commit hook already formats staged files; this is the belt-and-braces version for when hooks are bypassed.
Never skip the gate because “the change is tiny”. CI mirrors it exactly — running it locally means fixing problems quietly instead of in a PR thread.