Git worktrees
Worktrees live in .claude/worktrees/ and are provisioned by name from the main
checkout:
just worktree-up NAME # URL, migrated + seeded database, test database, CSSjust worktrees # list them with URL, database and sidecar statusjust worktree-down NAME # remove it along with its sidecar, route and databasesjust worktree-prune # drop sidecars and databases whose worktree is goneEach gets https://<slug>.<project>.dev.localhost and its own dev database, so
bin/console in a worktree never touches the main development database. Log in
with the seeded dev@loupe.test / password, or admin@loupe.test for the
admin area.
Rules that prevent real damage
Never remove one with a bare git worktree remove. That leaves the sidecar
container, the Traefik route and both databases behind, and the route then
serves 502s. Use just worktree-down.
Never match worktrees by directory name. A worktree called Feature_X owns
the slug feature-x; looking for a directory of that name would declare a live
worktree orphaned and drop its databases. The tooling matches on the derived
slug for exactly this reason.
Run just recipes from the worktree in a subshell, so the working directory
dies with the command:
( cd .claude/worktrees/<name> && just worktree-up )Running tests in parallel
PHPUnit’s database is app_test<TEST_TOKEN>, so exporting a unique TEST_TOKEN
per worktree gives each its own schema. just worktree-up writes one for you.
The e2e suite is the exception and cannot be parallelised — Mailpit is shared.
Warm the cache before an e2e run
( cd .claude/worktrees/<name> && bin/worktrees/compose-exec.sh bin/console cache:warmup )A run started against a cold var/cache/dev, or one whose cache is rebuilt
mid-flight by a concurrent just cs, produces false failures that look like
unrelated flaky specs: a request that never completes, a submit button left
disabled, and no validation errors — because the container-load fatal happens
before the logger exists, so nothing is logged at all.
If a spec fails and then passes in isolation, count the container hashes in
var/cache/dev/. More than one means a rebuild happened during the run. That is
a diagnosis, not a licence to re-run until green.