~/blogtwo-agents-two-indexes-one-git-config.md
cchu@nycu:~/blog$ cat two-agents-two-indexes-one-git-config.md
2026.08.284 min[agents][git][developer-tools][worktrunk]

Two Agents, Two Indexes, One Git Config

A scratch-repository experiment with Worktrunk shows which parts of parallel agent work are isolated, which remain shared, and why dirty removal refuses to proceed.

Give two coding agents the same checkout and each can rewrite the other's files before either makes a commit. Separate worktrees address that immediate problem. They also create a misleading visual cue: two directories look like two fully independent environments.

I used Worktrunk to create both directories, edited the same filename differently in each, staged only one copy, and changed a repository setting. File contents and staging stayed separate. The setting appeared in both worktrees.

This August 28 retrospective was reproduced on September 12, 2026. Worktrunk 0.75.0 was pinned to 1c5c63ba91d73f1fdde85cd235c8d77449ab863d, from August 27.

The Setup Fits in a Small Repository

The experiment used a fresh local repository with one tracked file, agent.txt, containing base. It had no remote and no real project credentials. I built the wt executable with Rust 1.97.1:

cargo +1.97 build --locked --bin wt
Finished dev profile in 6m 31s

That is a development build time on my Windows machine, not a runtime performance result. The build completed with a linker-message warning.

Worktrunk accepts an explicit user configuration file. I supplied one that placed new worktrees under the experiment's temporary directory. Then I invoked the following command for each of agent-a and agent-b:

wt --config fixture.toml switch --create agent-a \
  --base main --no-cd --no-hooks --format json

The command names a branch, creates its worktree, and can emit a structured result. In a normal interactive setup, Worktrunk also handles navigation and lifecycle hooks. Here, --no-cd and --no-hooks kept the experiment focused on repository behavior. The pinned switch command documentation describes these options.

Three Checks, Then a Refused Removal

First I wrote agent-a into one copy of the file and agent-b into the other. The main checkout still contained base. Then I ran git add agent.txt only inside agent-a. A cached diff listed the file there and returned no filenames in agent-b.

Finally I set a harmless key, probe.shared=yes, through git config --local in agent-a. Reading the same key from agent-b returned yes. This fresh repository used Git's ordinary repository configuration; I did not enable separate worktree configuration.

ProbeObserved result
Different edits to agent.txtEach directory retained its own bytes
Stage the edit in agent-aOnly its index contained a staged change
Set a local repository config key in agent-aagent-b read the same value
Remove dirty agent-a without forceExit 1; edited file remained

The removal command was wt remove agent-a --foreground --no-hooks --format json, with the same isolated config. Its diagnostic identified the uncommitted change. The removal implementation builds and validates removal plans before dispatching them.

Even with JSON output requested, this failure arrived as a text diagnostic on stderr and empty stdout. A caller should check the exit status before trying to decode a success object. My Python harness also needed explicit UTF-8 decoding: the default Windows CP950 decoder could not read the diagnostic's symbols.

Separate worktree files and indexes connect to shared repository state; services and ports live outside that isolation.

What to Give Each Agent

Worktrunk's convenience is useful because the branch becomes the handle for creating, finding and removing a checkout. An orchestrator can assign a branch and working directory without repeatedly rebuilding those operations from raw Git commands. The complete probe retains its scratch directory so the resulting worktrees can be inspected.

The experiment also gives a practical scope for the word “isolated.” It demonstrated separate file contents and indexes. It did not provision separate service accounts, databases or network namespaces. Two applications launched from those directories can still request the same port or connect to the same development database. Those resources need their own allocation if the agents will run integration tests.

For a parallel coding setup, I would record the worktree path and branch alongside each agent's port and test database name. The first pair is handled by the repository workflow; the second pair belongs to the application environment. Cleanup should check both the Git state and any processes the task started.

The successful refusal is useful feedback in that workflow. A finished chat does not imply a clean checkout. If an agent leaves an uncommitted fix, an orchestrator should surface it for review instead of treating directory removal as routine housekeeping.