Clean clone to green gate
This page is the real, literal path from a fresh clone to a passing gate — no steps skipped, no commands invented beyond what's in CLAUDE.md and scripts/gate.mjs.
Prerequisites
Node 24
pnpm 11
Docker (for the local PostgreSQL instance, via Compose)
Runtime support policy (standing rule, CLAUDE.md "Runtime support policy"): runtimes ship only on Active LTS lines — Node 24 today. The next Current line (Node 26) runs as a non-blocking CI evidence job (
gate-node-nextinci.yml) and is adopted only once it reaches LTS; Maintenance LTS is the floorenginesmay accept.ffmpeg on your
PATH(orLOOMBRE_FFMPEGpointing at a binary). Without it, several worker test suites (probe/session/subtitle/battery integration) silently skip rather than fail, so a clean-looking localpnpm test/pnpm gaterun can hide real coverage gaps. SetLOOMBRE_REQUIRE_FFMPEG=1to turn that silent skip into a hard failure —LOOMBRE_REQUIRE_FFMPEG=1 pnpm gate:fullis exactly what CI runs, so it's the closest local match to what a PR is actually checked against.
1. Install dependencies
pnpm install2. Bring up the database and set it up
docker compose -f docker-compose.dev.yml up -d
pnpm db:migrate
pnpm db:seedThe first command brings up PostgreSQL (host port 5442) and Adminer (a web-based database browser, host port 8080) via docker-compose.dev.yml, detached so this terminal is free again immediately. db:migrate applies every migration in packages/db. db:seed loads a small, deterministic dataset so the app has something to browse. (There's also pnpm db:reset, if you need to drop and recreate the schema from scratch — and a separate db:seed-large target used by the performance harness, not needed for everyday development.)
3. Start the dev environment
pnpm devpnpm dev re-runs the same docker compose up -d from step 2 (a harmless no-op if it's already running) and then starts the server, worker, and web client in watch mode via Turborepo. pnpm dev stays running — it's not a one-shot setup step, it's your dev environment for the rest of this session — so open a second terminal for everything below.
Once it's up:
| What | Where |
|---|---|
| Web client | http://localhost:3000 |
| API server | http://localhost:3001 |
| Adminer (database browser) | http://localhost:8080 |
| PostgreSQL | localhost:5442 |
4. Run the tests
(From the second terminal.)
pnpm testRuns every workspace package's test suite via Turborepo. DB-backed suites never touch the database you just set up in step 2: each resolves its own connection to a separate <database>_test database (derived from DATABASE_URL, or LOOMBRE_TEST_DATABASE_URL if you've set one — see packages/db/src/testing.ts's resolveTestDatabaseUrl), auto-created on first use. packages/db/scripts/migrate.mjs reset (the drop-and-recreate-schema step every self-sufficient live-DB suite runs in its own beforeAll) enforces this: it refuses to run against any database whose name doesn't contain _test, unless LOOMBRE_ALLOW_RESET=1 is set — which is exactly what lets pnpm db:reset (step 2) reset your real dev database on purpose. Net effect: it's safe to run pnpm test while pnpm dev (step 3) is up and your dev database has real browsable data in it. Those auto-created _test databases are never dropped automatically, so they accumulate over many test runs — run pnpm db:cleanup-test-dbs (dry run by default; pass --execute to actually drop) occasionally to sweep the disposable ones off your Postgres server.
If you're working specifically on playback decision logic:
pnpm test:matrixRuns only the playback-engine's offline test matrix — see Playback engine & matrix law for what that actually is, and Authoring a matrix case if you're adding to it.
5. Run the gate
pnpm gateThis is the fast inner-loop default, stopping at the first failing step: codegen → sdk-drift → version-stamp → oasdiff → depcruise → runtime-imports → license-check → go-licenses-check → dep-audit → lint → typecheck → test → playback-matrix → installers-test → scripts-test → db:migrate-check → grep-gates → docs-build (see scripts/gate.mjs for the exact step list and the reasoning behind each step's position — it's a short, heavily-commented file, worth reading once).
5a. Before you push or open a PR: run the full gate
pnpm gate:fullpnpm gate:full runs everything pnpm gate runs, plus a 19th step, web-build-budget: a production build of apps/web and a check of its bundle size against the docs/PLAN.md §9.3 budget. This step is genuinely slow (a full Next.js production build), which is why it's not in the fast pnpm gate — but CI runs pnpm gate:full, not the fast gate, so a green pnpm gate alone does not guarantee a green PR. Run LOOMBRE_REQUIRE_FFMPEG=1 pnpm gate:full (see "Prerequisites" above) for the closest local match to what CI itself enforces.
Where to go next
- Making a contract change (a new or modified endpoint)? See Contract-first workflow.
- Touching playback decisions? See Playback engine & matrix law.
- Not sure what a term in this guide means? Check the Glossary.
CONTRIBUTING.mdat the repository root has the PR-level expectations (feedback-loop-first, the matrix regression law, contract-first rules) distilled into one page.