Use git worktrees to isolate parallel agent tasks in this repository.
metadata
{"short-description":"Git worktree workflow"}
worktree
Use git worktrees for parallel agent changes. Each agent task gets an isolated copy of the repo.
When to use
Parallel feature work (multiple agents building different features simultaneously)
Risky or experimental changes you want to isolate from main
Any task where file conflicts with other agents are likely
Branch naming convention
<type>/<domain>-<short-description>
Type
When
feat/
New feature, route, page, or domain entity
fix/
Bug fix
refactor/
Restructure without behavior change
test/
Test-only changes
chore/
Config, tooling, CI, docs
Examples:
feat/tenancy-team-members-api
feat/tenancy-role-store-port
fix/tenancy-auth-middleware-wiring
refactor/billing-credit-service
test/tenancy-inv-ten-003-disabled-member
Keep names under 50 chars. Use the spec domain as prefix when working from a design doc.
Worktree lifecycle
1. Create (single command)
# Runnable from the primary checkout OR from inside any existing worktree
./scripts/worktree/create.sh feat/tenancy-team-members-api
# Optional second arg: base branch (defaults to main)
./scripts/worktree/create.sh fix/billing-refund main
create.sh resolves the primary checkout via git rev-parse --git-common-dir,
runs git worktree add from there, and then calls setup.sh against the new
worktree. That single invocation gives you:
A unique WORKTREE_PORT_OFFSET so every port (dev server, integration API,
web slots) is offset from its default.
Secrets seeded from the primary checkout's .env (R2, Sentry, Resend,
etc.), with empty values healed on re-run. Non-empty worktree-local
overrides are preserved.
Raw git worktree add is blocked for Claude and Codex agents. The
project-scoped hooks call .claude/hooks/block-raw-git-worktree-add.sh,
including commands like git -C <repo> worktree add, and deny them with
instructions to use create.sh instead. Other git worktree subcommands
(list, remove, prune, lock, unlock, move, repair) pass
through untouched. If you genuinely need the raw command for a recovery
scenario, set ALLOW_RAW_GIT_WORKTREE_ADD=1 in the environment.
Always use ./scripts/worktree/create.sh; do not invoke git worktree add
directly. A worktree created without setup.sh will have no port offset,
no seeded secrets, and no Postgres schema, and both pnpm dev and
pnpm test:integration will fail from it.
1b. Re-run setup against an existing worktree (idempotent heal)
# Re-applies port allocations and pulls fresh secrets from the primary
./scripts/worktree/setup.sh .worktrees/team-members-api
setup.sh refuses to run against the primary checkout — that path uses
base ports and sources its .env via cp .env.example .env.
2. Work
Run pnpm type-check freely — no shared state conflicts.
pnpm dev works after running setup.sh — unique ports prevent conflicts with other worktrees.
pnpm test:integration works in parallel across worktrees. The
shared API server in scripts/test/vitest-global-setup.ts binds to
4100 + WORKTREE_PORT_OFFSET, and each worktree gets its own Postgres
schema, so multiple worktrees can run integration tests at the same
time without stepping on each other. No lock file is involved.
Do NOT modify Docker infrastructure — shared across all worktrees via the tx-agent-kit project name.
3. Quality gate before signaling done
pnpm type-check:quiet # must pass — zero errors
4. Merge back
# From main worktree
git merge feat/tenancy-team-members-api
# Or cherry-pick specific commits
git cherry-pick <sha>
One task per worktree. Don't mix unrelated changes.
Branch from main unless explicitly told otherwise.
Use create.sh (never raw git worktree add). It allocates unique ports, seeds secrets, and creates the Postgres schema.
Commit before signaling done. The orchestrating agent needs commits to merge.
Remove stale worktrees after merge. Don't leave orphan worktrees around.
TDD applies in worktrees too. Write failing tests first, then implement.
Port allocation reference
Every port-scoped service uses base + WORKTREE_PORT_OFFSET, where the
offset is derived deterministically from the worktree name by
scripts/worktree/lib/ports.sh. The primary checkout has offset 0.
Non-worktree-scoped secrets (R2, Sentry DSNs, Resend, Temporal Cloud,
etc.) are seeded from the primary checkout's .env.
Agent swarm pattern
When an orchestrator launches multiple agents in parallel worktrees:
Each agent gets a unique worktree + branch with a descriptive name
Agents run pnpm type-check, pnpm lint, pnpm test, and
pnpm test:integration freely in parallel — the WORKTREE_PORT_OFFSET
mechanism isolates each worktree's shared API server and Postgres schema