# PARALLEL-SESSIONS.md — when several sessions share this repo

> Read this **alongside `KICKOFF-PROMPT.md`**, not instead of it. The kickoff
> says what to build; this file says how to not collide with the other sessions
> while building it. It applies whenever `git worktree list` shows more trees
> than the hub — a standing reality since 2026-07-30 — not only when the
> operator announces a second session.

Multiple Claude Code sessions work from this same repo. You are one of them.
The others are invisible to you, they are doing different work, and their
commits can land under you at any moment. Everything below follows from that.

## Lane file contract — the same three files for every lane

A lane's `<slug>` is chosen at lane creation and used unchanged everywhere
(current slug table: `plans/kickoff-prompts/README.md`). Each lane owns:

| file | role | volatility |
|---|---|---|
| `plans/kickoff-prompts/<slug>.md` | session opener — identity, mission, pointers | near-static |
| `plans/rethink/<slug>-handoff.md` | lane state — current truth, next in order | rewritten every session |
| `plans/rethink/<slug>-kickoff.md` | the work-package plan the lane executes | one per package |

The opener never holds state; the handoff never holds mission prose; the plan
is the work order (**no plan on disk = no execution**). The handoff outranks
the shared `HANDOFF.md` for its lane; the shared file stays lane-agnostic.
Read only YOUR lane's files — the others are other lanes' orders. A terminal
lane closing out keeps no handoff.

**Mass-prompting:** the orchestrator writes a directive into `HANDOFF.md`'s
top ORDER block on `main` and pushes; every lane meets it at its next
rebase + orient. Orders land at session start — a mid-flight lane is nudged
only by the operator directly.

## 1. Get yourself your own root directory before you do anything

Ask the operator one question first — skipped if your kickoff prompt already
names your lane: **"Which lane am I, and what is my task?"**

Then look before you build:

```bash
git worktree list        # local only — often empty; worktrees never sync
                         # between machines, only branches do
git branch -a            # this is the real record of existing work
```

- If a **local worktree** already covers your scope, move into it and update it:
  `git fetch origin && git rebase origin/main`. Do not create a second one.
- If a **remote branch** already covers your scope, attach a worktree to it
  rather than starting a rival branch:
  ```bash
  git worktree add ../channels-manager-<scope> --track origin/<branch>
  ```
- **Only when nothing matches**, create fresh from main:
  ```bash
  git worktree add ../channels-manager-<scope> -b work/<scope> origin/main
  ```

Then actually move in: use your `EnterWorktree` tool if you have one; otherwise
**stop**, tell the operator the exact path, and wait for him to `cd` there or
open a session in it. Do not start working from the shared checkout in the
meantime.

From that point every file you read or write lives under **your** directory. The
original checkout is a **hub, not a workspace** — nobody works in it. Never
`git checkout` / `switch` / `stash` / `reset` there, and never touch the other
session's directory.

## 2. `main` is the deploy branch

`main` is what gets deployed. You never deploy from your work branch. Deploying
= merge to `main`, then run the deploy loop from `main` (`CLAUDE.md` §
Runtime & deploy).

Before you merge or deploy: **tell the operator and wait.** Only one session
deploys at a time — two half-deployed merges arriving from different directions
is how prod breaks. Push your work branch often so the other session can see it.

## 3. When the operator says "pull main into your branch"

The other session pushed. Pull, then **read what arrived** — that diff is free
information about work you didn't do:

```bash
git fetch origin
git log --oneline HEAD..origin/main
git diff --stat HEAD...origin/main      # then read the parts that matter
git rebase origin/main
```

Judge from the diff; don't re-read the world. Files it didn't touch are exactly
as you left them. What earns your attention is the **overlap**: anything you are
mid-edit on, anything you call into, and contracts that moved — shared types,
Prisma schema, API routes, env keys, anything under `packages/shared`. If a
symbol or file you were relying on is gone, the other session removed it
deliberately: **say so and ask, don't reconstruct it.**

Then tell the operator in one line what landed and whether it changes your task,
and re-run typecheck/build if the diff touched code you depend on.

## 4. Shared state git does not protect — announce before touching

Your worktree isolates files. It isolates nothing else; you are both on one
machine hitting one server.

- **`.git` itself — every worktree shares it, so `index.lock` contention is
  normal.** Never delete the lock while any `git` process is alive: wait and
  retry. But a lock HOURS old with zero git processes (`tasklist | grep -i git`
  empty) is a crash artifact, not contention — delete it, report that you did,
  and carry on. (A 0-byte lock from 07-30 blocked the hub's pull for four days
  because this clause was missing.)
- the VPS, `pm2` processes, anything published to the live docroot
- **Prisma migrations** — one session authors migrations at a time. Ask first.
  Two parallel migrations wedge the database.
- `packages/shared/dist`, and the pnpm store / `node_modules`
- **the PID cap** — never run bare `pnpm test`, and remember the other session
  may be running tests while you do (`CLAUDE.md` § Testing)
- `HANDOFF.md`, `plans/rethink/scope-board.md` and other high-traffic docs:
  write in your own clearly-marked block and expect to rebase them

## 5. Stay in your lane

Do the task you were given. If you spot something broken in the other session's
area, **report it — don't fix it.** Two agents fixing the same thing is worse
than neither fixing it.
