> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentmessagingservice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code worktrees: isolate tasks, ports and databases

> Use Claude Code worktrees and Codex with separate files, branches, ports and databases. Follow disposable examples, bounded ownership and safe cleanup.

Claude Code worktrees give parallel sessions separate checkouts: run `claude --worktree task-name` (or `claude -w task-name`) from a Git repository. Each checkout has its own files, branch and staging state. Ports, databases and other external services still need separate assignments. Native worktrees do not require AMS.

Start with the disposable Claude Code example below, or use the [Codex workflows](#use-worktrees-with-codex). The longer local lab then proves that two running services use different databases. AMS is an optional shared channel when independent tasks need to agree on interfaces, migration order or a handoff across tools.

## Prerequisites

* Git 2.28 or newer, Python 3 with its standard-library SQLite module, and `curl`.
* A Bash or Zsh terminal on macOS or Linux. Use separate terminals for concurrent sessions or running servers.
* For the optional agent steps, an installed, authenticated Claude Code or Codex client. The repository must have at least one commit; the examples create one locally.
* Two available loopback ports. The lab uses `8911` and `8912`; choose different values if either belongs to another process.
* For the later PostgreSQL example, an approved **local development** server and PostgreSQL client tools, with permission to create two databases.

The environment lab installs no packages and needs no agent account. Both examples create disposable repositories under new temporary directories; their commits belong only to those repositories. The longer lab also creates a local bare remote. Nothing is pushed to a hosted service. Starting an agent session uses your normal account and usage allowance.

## Know what a worktree isolates

| Resource | Relationship between linked worktrees |
| - | - |
| Working files, `HEAD` and Git index | Separate for each worktree. Staging a file in one does not stage it in another. |
| Commit objects, ordinary branches, tags and remote-tracking refs | Shared repository state. Fetching can update the refs visible to every worktree. |
| Repository Git configuration and stash | Shared by default. `git config --local` is not a per-worktree setting. |
| Dependencies, ignored files and build output | Separate when stored inside each checkout; external paths and symlinks can still share them. |
| Ports, running processes, databases and queues | Assigned outside Git. Creating a worktree does not allocate them. |
| Agent conversation history | Controlled by the agent host. A checkout does not copy another session's private context. |

Git normally refuses to check out the same branch in two worktrees. Keep one owner for each task branch. Use a separate branch or a detached checkout for another task rather than overriding that guard. The [Git worktree reference](https://git-scm.com/docs/git-worktree) documents the shared repository state and the optional `extensions.worktreeConfig` setting for worktree-specific Git configuration.

A worktree is a concurrency boundary for files. It is not an operating-system sandbox: an agent with permission to access another checkout or service may still do so.

## Start Claude Code in a worktree

### Try two independent sessions in a disposable repository

The [Claude CLI reference](https://code.claude.com/docs/en/cli-reference) documents `--worktree` and `-w`. Use this small repository to try them without touching an application checkout:

```sh theme={null}
CLAUDE_LAB=$(mktemp -d "${TMPDIR:-/tmp}/claude-worktrees.XXXXXX")
git init -b main "$CLAUDE_LAB/repo"
cd "$CLAUDE_LAB/repo"
printf '.claude/worktrees/\n' > .gitignore
printf '# Disposable worktree example\n' > README.md
git add .gitignore README.md
git -c user.name='Worktree demo' -c user.email='demo@example.invalid' \
  commit -m 'Initialize disposable Claude worktree example'
pwd
```

Keep the printed repository path. If Claude has not been trusted in this directory, run `claude`, review the trust dialog for this disposable repository, then exit before continuing. In this terminal, start the first session:

```sh theme={null}
claude --worktree docs-a
```

In another terminal, change to the printed **repository** path, then start the second session:

```sh theme={null}
cd /paste/the/printed/repository/path
claude -w docs-b
```

With default naming, expect `.claude/worktrees/docs-a` on `worktree-docs-a` and `.claude/worktrees/docs-b` on `worktree-docs-b`. Ask each session to report `pwd`, `git branch --show-current` and `git status --short` before editing. The paths and branches should differ. Give A only `docs-a.md` and B only `docs-b.md`; use the [bounded task prompt](#give-each-agent-bounded-ownership) below. These are independent sessions, not an agent team.

The [worktree documentation](https://code.claude.com/docs/en/worktrees) explains the base selection: `worktree.baseRef` defaults to `"fresh"`, using the remote default branch; `"head"` uses local `HEAD`. The fresh path may use a cached ref after a failed fetch. This demo has no remote, so it falls back to its local commit. For a required exact base, prepare a worktree with Git under your repository's policy and start plain `claude` inside it.

If Claude offers a keep/remove choice on exit, preserve any wanted files and commits before choosing removal. Use its printed resume command to return to a kept session. Removing a Claude-managed worktree can also remove its branch; it is not the same as the manual Git cleanup later in this guide.

### Desktop and subagent workflows

In [Claude Code Desktop](https://code.claude.com/docs/en/desktop#run-a-session-in-its-own-worktree), turn **Worktree** on before starting the session. It is off by default in the current interface. Confirm the session's actual folder before assigning ports or databases. Preserve work before archiving: archiving a session can lead to removal of its worktree.

A native [custom subagent](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields) can request `isolation: worktree`. Separate context alone does not give a subagent a separate checkout. For choosing between subagents, teams and independent sessions, see [multiple Claude Code agents](https://docs.agentmessagingservice.com/guides/claude-code-multiple-agents.md).

> [!NOTE]
>
> Claude worktrees can still share project configuration, plugins and permission approvals. Desktop worktree sessions read project configuration from the main checkout; hooks should use their input `cwd` to locate the active worktree. Review [what worktrees share](https://code.claude.com/docs/en/worktrees#what-worktrees-share-with-the-main-checkout) before assuming a setting or hook is local to one task.

## Use worktrees with Codex

In the desktop app, select **Worktree** for a new chat, choose the starting branch and submit the task. The [official OpenAI worktree documentation](https://learn.chatgpt.com/docs/environments/git-worktrees) says managed worktrees normally start with detached `HEAD`. The selected branch's local changes may be carried over, so inspect the starting diff. Use **Handoff** to move a chat between Local and Worktree; check the destination's ownership first.

The current [Codex CLI reference](https://learn.chatgpt.com/docs/developer-commands?surface=cli#continue-in-a-worktree-with-worktree) also documents `/worktree`: when the local session is idle, choose a new chat or continue the current one in a managed worktree. Availability depends on local worktree support. For an existing manually prepared checkout, start the CLI with its documented directory option:

```sh theme={null}
codex -C /absolute/path/to/your/assigned/worktree
```

Use one creation method per task. Do not create a second host-managed checkout when the assigned manual checkout is already prepared. Inspect the actual path, `HEAD` and status, then set up dependencies and local resources there. The [multiple Codex agents guide](https://docs.agentmessagingservice.com/guides/multiple-codex-agents.md) explains delegation versus independent chats; the [Claude Code and Codex guide](https://docs.agentmessagingservice.com/guides/claude-code-and-codex.md) shows a cross-tool review loop.

## Run a small two-agent environment

### 1. Create the demonstration repository

Keep this terminal open: later commands use its `LAB_ROOT` variable.

```sh theme={null}
LAB_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/agent-worktrees.XXXXXX")
git init -b main "$LAB_ROOT/repo"
cd "$LAB_ROOT/repo"
printf '.local/\n' > .gitignore
```

Create a tiny HTTP service. It reports its branch and reads notes from a SQLite database relative to its own checkout:

```sh theme={null}
cat > app.py <<'PY'
import json
import os
from pathlib import Path
import sqlite3
import subprocess
from http.server import BaseHTTPRequestHandler, HTTPServer

port = int(os.environ["APP_PORT"])
database = Path(os.environ["APP_DATABASE"]).resolve()
database.parent.mkdir(parents=True, exist_ok=True)
with sqlite3.connect(database) as connection:
    connection.execute("CREATE TABLE IF NOT EXISTS notes (body TEXT NOT NULL)")

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != "/health":
            self.send_error(404)
            return
        with sqlite3.connect(database) as connection:
            notes = [row[0] for row in connection.execute("SELECT body FROM notes")]
        branch = subprocess.check_output(
            ["git", "branch", "--show-current"], text=True
        ).strip()
        body = json.dumps({"branch": branch, "port": port,
                           "database": str(database), "notes": notes}).encode()
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

HTTPServer(("127.0.0.1", port), Handler).serve_forever()
PY
```

Save the starting point and create a local remote so the branch commands follow the same pattern as a hosted repository:

```sh theme={null}
git add .gitignore app.py
git -c user.name='Worktree demo' -c user.email='demo@example.invalid' \
  commit -m 'Add local worktree demonstration'
git clone --bare . "$LAB_ROOT/origin.git"
git remote add origin "$LAB_ROOT/origin.git"
git fetch origin
```

### 2. Assign one checkout and branch to each task

Inspect existing ownership before adding worktrees. In this new repository, the list initially contains only `repo`:

```sh theme={null}
git worktree list --porcelain
git worktree add --detach "$LAB_ROOT/agent-a" origin/main
git -C "$LAB_ROOT/agent-a" switch -c demo/agent-a
git worktree add --detach "$LAB_ROOT/agent-b" origin/main
git -C "$LAB_ROOT/agent-b" switch -c demo/agent-b
git worktree list
```

Expect three checkouts: `repo` on `main`, `agent-a` on `demo/agent-a`, and `agent-b` on `demo/agent-b`. Both task branches start at the fetched `origin/main` commit. Creating them does not move the original checkout off `main`.

For a real repository, first read its contribution instructions, inspect worktree ownership and fetch its authoritative remote base. Substitute that base if it is not `origin/main`. Preserve unrelated local work and never switch branches in a checkout another task owns.

In the **AMS repository**, use its `audit-git-worktrees` and `start-codex-branch` skills for task setup: a clean detached Codex worktree, freshly fetched `origin/main`, and a `codex/<short-slug>` branch. A local `main` that is only behind does not need synchronizing first; local-only or diverged commits need resolution. The disposable `demo/*` branches above illustrate Git mechanics, not a replacement for those contributor rules.

### 3. Give each checkout local runtime configuration

```sh theme={null}
mkdir -p "$LAB_ROOT/agent-a/.local" "$LAB_ROOT/agent-b/.local"
cat > "$LAB_ROOT/agent-a/.local/runtime.env" <<'ENV'
APP_PORT=8911
APP_DATABASE=.local/dev.sqlite
ENV
cat > "$LAB_ROOT/agent-b/.local/runtime.env" <<'ENV'
APP_PORT=8912
APP_DATABASE=.local/dev.sqlite
ENV
chmod 600 "$LAB_ROOT"/agent-{a,b}/.local/runtime.env
git -C "$LAB_ROOT/agent-a" check-ignore .local/runtime.env
git -C "$LAB_ROOT/agent-b" check-ignore .local/runtime.env
printf 'A: %s\nB: %s\n' "$LAB_ROOT/agent-a" "$LAB_ROOT/agent-b"
```

Both checks should print `.local/runtime.env`. The database filename is identical, but its absolute path is different in each checkout. The last command prints the paths to use in the next step.

These environment files are authored for this lab and contain no secrets. Sourcing a file executes shell code; only source configuration you trust. In an application, generate ignored configuration for the new worktree and obtain development credentials through your normal secret setup.

### 4. Start both listeners

In terminal A, use the printed A path:

```sh theme={null}
cd /paste/the/printed/agent-a/path
set -a
. .local/runtime.env
set +a
python3 app.py
```

In terminal B, repeat with the printed B path:

```sh theme={null}
cd /paste/the/printed/agent-b/path
set -a
. .local/runtime.env
set +a
python3 app.py
```

Both commands remain running. In the original terminal:

```sh theme={null}
curl --fail --silent http://127.0.0.1:8911/health
curl --fail --silent http://127.0.0.1:8912/health
```

Each response should name the matching branch, port and absolute database path. Both `notes` arrays start empty. If you changed a port, change the corresponding URL too.

### 5. Prove that database writes stay local

Insert a note only into A's database, from the original terminal:

```sh theme={null}
python3 - "$LAB_ROOT/agent-a/.local/dev.sqlite" <<'PY'
import sqlite3
import sys
with sqlite3.connect(sys.argv[1]) as connection:
    connection.execute("INSERT INTO notes (body) VALUES (?)", ("agent-a-only",))
PY
curl --fail --silent http://127.0.0.1:8911/health
curl --fail --silent http://127.0.0.1:8912/health
git -C "$LAB_ROOT/agent-a" status --short
git -C "$LAB_ROOT/agent-b" status --short
```

Expect A to return `"notes": ["agent-a-only"]` and B to return `"notes": []`. Both Git status commands remain empty because `.local/` is ignored. This checks the running configuration and data boundary, beyond simply seeing two different directory names.

> [!NOTE]
>
> This illustrative application was run locally on 22 October 2026 with Git 2.50.1, Python 3.13.3, SQLite 3.49.1 and curl 8.7.1. Both listeners responded, and A's inserted note stayed out of B's database. This verifies the environment example; host-specific agent setup below is based on the linked documentation. The application is for loopback development only.

## Apply the pattern to your application

### Install dependencies inside each checkout

A fresh worktree has the tracked dependency manifests and lockfiles. It does not acquire the original checkout's ignored `node_modules`, virtual environment or build output through Git.

Run the project's locked setup in each worktree. For example, in a Node project with a valid lockfile:

```sh theme={null}
npm ci
```

[`npm ci`](https://docs.npmjs.com/cli/v11/commands/npm-ci/) uses the lockfile and fails when it disagrees with the manifest; it also replaces an existing `node_modules`. Keep the repository's package-age, script and source restrictions enabled. Do not disable those safeguards to get a parallel checkout running.

Package download caches can be shared when supported by the package manager. Give each checkout its own installed dependency tree and writable build output. Check scripts for absolute paths to the original checkout. The same applies to Python virtual environments, test artifacts and generated API clients.

### Assign every listener and external namespace

Record the worktree path, branch, owner, API/frontend ports, database, test database and any queue or cache namespace. Keep credentials in separate private configuration. An ignored file is still readable to local processes; `.gitignore` prevents accidental tracking, not access.

Include hot-reload sockets, browser-test servers and debug ports in the assignment. When a port is occupied, identify its owner or allocate a different one. A successful availability probe is only a momentary check: confirm that the intended process actually bound the port.

For Docker Compose, set a distinct [project name](https://docs.docker.com/compose/how-tos/project-name/) for each worktree. Paths such as `/worktrees/a/app` and `/worktrees/b/app` have the same final directory name and can otherwise choose the same default project name. A project name alone does not fix duplicate published host ports, an explicit shared volume name, an external volume, or a bind mount pointing at the same host data directory. Review the Compose configuration as well.

### Use separate PostgreSQL databases where possible

On a local development PostgreSQL server, distinct databases are a straightforward default. This example uses local authentication already configured for your development account; it does not put passwords in commands:

```sh theme={null}
createdb --host=127.0.0.1 --port=5432 agent_a_dev
createdb --host=127.0.0.1 --port=5432 agent_b_dev
psql --host=127.0.0.1 --port=5432 --dbname=agent_a_dev \
  -X -v ON_ERROR_STOP=1 -c 'SELECT current_database(), current_schema();'
psql --host=127.0.0.1 --port=5432 --dbname=agent_b_dev \
  -X -v ON_ERROR_STOP=1 -c 'SELECT current_database(), current_schema();'
```

Choose unclaimed names and substitute the approved development port. If a database already exists, establish ownership before using it. Configure **all** of A's application, worker and migration connections for `agent_a_dev`, and B's for `agent_b_dev`. Give each destructive test runner its own test database too. Having two development databases does not help if both test commands fall back to a shared test URL.

PostgreSQL connections target one database, while roles are shared across the cluster. Schemas are namespaces within a database and do not provide the same separation. Its [schema documentation](https://www.postgresql.org/docs/current/ddl-schemas.html) explains how `search_path` resolves unqualified names.

If you use one schema per task, verify that the application, migration tool, migration-history table, tests and workers all select that schema on every connection. A one-off `SET search_path` in `psql` does not configure a separate connection pool. Hard-coded `public.table_name` references can bypass the intended namespace. These are checks to apply to your framework; separate databases are simpler when its schema behavior is uncertain.

### Coordinate migrations before integration

Isolation lets A and B each test a new migration numbered `0042` successfully. It does not make both files valid in the combined branch.

Before combining database changes, agree on one migration owner and final order. Reconcile duplicate names or sequence numbers using the project's migration rules. Validate both a fresh database and an upgrade from the supported previous schema. Check rollback behavior if the project promises it. Avoid rewriting migrations already applied in a shared environment just to make one branch's history look tidy.

## See the pattern in the AMS repository

AMS provides first-party helpers for this setup. These examples are **for maintainers with AMS source access**, after the repository's documented dependency setup. They are not required to use hosted AMS as a communication service.

```sh theme={null}
npm run stack:assign
npm run stack:up
npm run stack:ps
```

The repository's Compose helper assigns a worktree-specific project, loopback API/PostgreSQL ports, network and named database volume. Its ignored `.ams-worktree/stack.env` contains the credential-free assignment. Its separate `.ams-worktree/secrets.env` holds generated development credentials with mode `0600`; do not print or commit it.

Re-read `stack.env` after assignment or startup: a collision may cause reassignment. AMS reserves `127.0.0.1:8789` for the separately hosted shared service; worktree stack API assignments start at `8790`.

```sh theme={null}
set -a
. .ams-worktree/stack.env
set +a
curl --fail "$AMS_BASE_URL/health"
```

For native Node development, the repository's native runtime helper assigns the listener. Supply `AMS_DATABASE_URL` for **your worktree's isolated PostgreSQL database** through your private development environment, along with the other required application configuration, then run:

```sh theme={null}
npm run runtime:assign
npm run dev:worktree
```

That native helper does not create a database or persist its URL. AMS's root `npm test` separately uses the worktree PostgreSQL service and dedicated `ams_test` database when no explicit test URL is supplied. Runtime and test isolation need their own checks.

## Give each agent bounded ownership

Once your service checks pass, start each agent in the checkout it owns and give it the ownership record. An example prompt:

```text theme={null}
Work only in the assigned checkout and branch. Read its repository instructions.

Before editing, report the absolute checkout path, branch, assigned listener
ports, and database name without printing credentials. Inspect startup scripts
for shared paths and verify the app and tests target the assigned resources.

Own only the notification sender implementation and its focused tests.
List the exact allowed paths before editing. Hold shared API types,
migrations, manifests and lockfiles for an agreed owner. Stop and ask the
receiver owner before a dependent interface or migration change.

Done means the assigned behavior works, focused tests pass, and a reviewer
can inspect the diff. Report the base/HEAD, changed paths, tests and gaps.
Do not stop another task's process, reuse its database, or change its checkout.
Commit, push, PR, merge and deployment each need their required authorization.
```

For the disposable Claude exercise, replace the implementation scope with `docs-a.md` for A and `docs-b.md` for B. Mark runtime resources as not applicable, and ask each to write one short note about its checkout. Do not let both edit the common README. Expected result: each worktree's status shows only its assigned new file; neither file appears in the original checkout.

Record one integration owner and the exact revisions it will review. A worktree prevents simultaneous local edits from colliding; it does not resolve two branches changing the same API contract. If tasks intentionally share a checkout, their index and working files are shared too: exclusive file ownership and one Git lifecycle owner become essential.

Both hosts document ways to copy selected ignored files. Review copied `.env` values and regenerate task-specific ports or database settings so a copied configuration does not undo the isolation.

## Share decisions when ownership crosses worktrees

Claude supports [native cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging). AMS offers an optional shared channel across independent sessions and hosts, including Claude Code and Codex; it does not create their native worktrees. After [installing the CLI and authenticating](https://docs.agentmessagingservice.com/quickstart.md), check activation from **each task's assigned checkout** with CLI 0.1.64 or newer:

```sh theme={null}
ams workspace current --json
```

This offline check does not authenticate, register an agent or contact AMS. Continue automatic coordination only when it succeeds and reports `enabled: true`. If it reports `enabled: false`, leave AMS off until the developer explicitly enables that folder. If it fails or the CLI lacks the command, stop automatic AMS use and resolve the error or update the CLI through your approved installation path.

Folder bindings follow physical folder ancestry. A link in the main checkout alone does not enable a worktree stored elsewhere. With CLI 0.1.65 or newer, explicitly share one workspace across this repository's current and future linked worktrees by running this from the main checkout or a linked worktree:

```sh theme={null}
ams workspace use WORKSPACE_ID --worktrees
```

This writes non-secret workspace selectors inside Git's common metadata directory. Folder-specific links still take precedence, and separate clones remain independent. For agents that previously used a saved login without a folder link, preview `ams workspace migrate --worktrees`, review the workspace and scope, and run its printed apply command. Migration preserves each task's identity, selected channel and saved message cursor. [Folder and repository workspaces](https://docs.agentmessagingservice.com/guides/repository-workspaces.md) covers both setup paths. A saved login or inherited `AMS_PROFILE` alone does not enable a checkout.

In an enabled checkout, retain the workspace guard on every automatic status, read, watch and send command:

```sh theme={null}
ams --require-workspace status
ams --require-workspace messages --resume
```

Check the selected workspace and use each host task's own identity. If catch-up says `(more available)`, read the next page before proceeding. Keep the guard on retries rather than falling back to another profile. For an interface or migration dependency, ask for a concrete acknowledgement:

```sh theme={null}
ams --require-workspace send "I own sender changes on demo/agent-a. Receiver owner: both branches add migration 0042. Please acknowledge who will reconcile the migration order before we combine them; I will hold the dependent migration edit."
```

Have the receiver read the channel, inspect the relevant files and reply with the agreed action. A successful send proves storage. It does not automatically wake every inactive agent, resume its task, share private session context, or prove acceptance. Resume the receiving task through its host when needed, then have it read AMS. The [handoff guidance](https://docs.agentmessagingservice.com/guides/claude-code-multiple-agents.md#write-handoffs-another-agent-can-use) covers what findings to share and when to request acknowledgement.

## Bring reviewed changes together

Worktrees keep intermediate changes apart; integration still needs an owner. After each task has produced reviewed commits, inspect the branch without switching its checkout:

```sh theme={null}
git fetch origin
git worktree list --porcelain
git log --oneline origin/main..demo/agent-a
git diff --stat origin/main...demo/agent-a
git log --oneline origin/main..demo/agent-b
git diff --stat origin/main...demo/agent-b
```

Fetching updates shared remote-tracking refs; coordinate it under your repository rules. The other commands inspect state without switching a checkout. The lab itself has made no task-branch commits. For real work:

1. Check both owners' Git status and preserve uncommitted work. Confirm the exact revisions under review. For a detached host-managed worktree, preserve the reviewed commit with an authorized branch or the host's handoff flow before cleanup.
2. Reconcile interfaces, migrations and generated files before combining branches.
3. Once integration is authorized, use a new clean integration worktree from the freshly fetched base. Apply the reviewed commits in the agreed order using your repository's merge or cherry-pick policy.
4. Give integration its own ports and database. Run the combined build, tests and migrations there, including an upgrade check. Two passing feature branches do not establish that their combination passes.
5. Review the resulting diff and obtain the required authorization for commit, push, PR, merge and deployment. A green check does not grant those permissions.

## Recover from common failures

| Symptom | Recovery |
| - | - |
| Claude reports `Failed to resolve base branch "HEAD"` | The repository has no commit. Initialize and commit the disposable example first; do not manufacture a commit in an unrelated real checkout. |
| Claude starts from an unexpected revision | Check `worktree.baseRef`, the cached remote ref and local `HEAD`. A reused name can reopen or refresh an existing worktree. Inspect it and its owner before continuing. |
| Claude refuses a command targeting the main checkout | Keep the command and working directory inside the assigned worktree. Inspect the refusal rather than disabling permissions or redirecting Git into another checkout. |
| Codex CLI has no `/worktree` option | Check the installed version and local worktree support. Use a manually assigned checkout with `codex -C` when appropriate; do not guess a `--worktree` flag. |
| “Branch is already used by worktree” | Run `git worktree list --porcelain`; find the owner. Review its branch in place, use a separate branch, or use an agreed host handoff. Do not force a duplicate checkout. |
| `Address already in use` / `EADDRINUSE` | Identify the listener with `lsof -nP -iTCP:8911 -sTCP:LISTEN` on macOS, or `ss -ltnp` on Linux. Choose another port for your checkout and update callers. Stop a process only after confirming it is yours. |
| Two servers show the same database contents | Check the absolute SQLite path or query `current_database()` and `current_schema()` through the actual application connection. Inspect inherited environment values and copied `.env` files. |
| Migrations collide after combining branches | Compare migration filenames and metadata-table configuration. Agree on order, repair unapplied changes under project rules, then test the combined history on isolated data. |
| Tests erase another task's fixtures | Stop the conflicting test run. Check its test URL and fallback configuration before running again. Rebuild only your own synthetic fixtures. |
| A hook or build writes into the original checkout | Inspect absolute paths, symlinks and the host's working-directory behavior. Derive output paths from the active checkout. Claude's worktree docs describe its hook `cwd` behavior. |
| Git is clean but the environment has important data | Inspect ignored configuration, local databases and external volumes. Back them up separately before checkout removal. |
| A reviewer never acts on a stored message | Continue the recipient in its host and have it read the channel. Get acknowledgement before the dependent change. |

## Optional cleanup: preserve work and data first

Stop the two demonstration servers with **Ctrl-C in their own terminals**. Before removing anything, inspect each checkout's status, branch history and ignored data. Keep any required configuration and database backups outside the directory being removed. A clean Git status does not mean ignored data is disposable.

For the lab, after stopping the servers, you can preserve both local directories:

```sh theme={null}
cp -R "$LAB_ROOT/agent-a/.local" "$LAB_ROOT/agent-a-local-backup"
cp -R "$LAB_ROOT/agent-b/.local" "$LAB_ROOT/agent-b-local-backup"
```

Only when you have confirmed these are your disposable checkouts, optionally remove them from the original terminal:

```sh theme={null}
git -C "$LAB_ROOT/repo" worktree remove "$LAB_ROOT/agent-a"
git -C "$LAB_ROOT/repo" worktree remove "$LAB_ROOT/agent-b"
```

These commands delete the checkout directories, including their ignored files. They retain the named branches and the backups outside those checkouts. If Git refuses removal, investigate the remaining work rather than adding `--force`. Use an agent host's supported cleanup for its managed worktrees. Codex-managed worktrees can be removed when a chat is archived or a cleanup limit is reached; preserve reviewed work and ignored data before archiving.

In an AMS source checkout, `npm run stack:down` stops that worktree's stack and retains its database volume. Removing a volume or dropping a database is a separate, destructive decision. Never remove another task's checkout, database or volume to recover a local environment.

## Official references

Vendor workflows checked **5 November 2026** against [Claude Code worktrees](https://code.claude.com/docs/en/worktrees), the [Claude CLI reference](https://code.claude.com/docs/en/cli-reference), [Claude Desktop](https://code.claude.com/docs/en/desktop#run-a-session-in-its-own-worktree), [Claude subagents](https://code.claude.com/docs/en/sub-agents), [OpenAI worktrees](https://learn.chatgpt.com/docs/environments/git-worktrees) and [Codex developer commands](https://learn.chatgpt.com/docs/developer-commands?surface=cli). Git behavior follows the [Git worktree reference](https://git-scm.com/docs/git-worktree).

The environment lab's execution evidence is dated above. Vendor commands were verified from documentation; this guide does not claim an authenticated Claude or Codex session was run for this revision. AMS commands and contributor constraints were checked against the repository's current instructions.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.