Shared Git State in Parallel Agent Worktrees
Overview
When deploying multiple AI coding agents across isolated Git worktrees, it is common to assume complete independence. While worktrees provide separate filesystems, working directories, and HEAD pointers, they share a single underlying object database and branch namespace. This shared architecture introduces subtle failure modes when multiple agents execute git commands concurrently. Understanding these shared state hazards prevents unexpected ref corruption and silent failures during automated workflows.
Shared Ref Layer and Mutable State
The core problem stems from how Git structures worktrees. Although each worktree maintains its own checked-out files and staging index, all worktrees in a repository point to the same .git directory. The object database, reflogs, and branch references are globally mutable across the entire repository. When one agent executes a destructive command like git reset --hard or git branch -D , the mutation immediately propagates to the shared object store. Sibling worktrees referencing those same commits or branches observe the change instantly, which can break active diffing, rebasing, or logging operations. Consider a scenario where Agent A and Agent B are spawned in parallel. If Agent A performs a destructive force reset on a shared tracking branch, Agent B can experience sudden ref invalidation.
Failure Mode Taxonomy
The following table outlines the primary failure taxonomy, their triggers, their blast radius, and their corresponding defensive patterns.
| Failure Mode | Trigger | Blast Radius | Defensive Pattern |
|---|---|---|---|
| Cross-Worktree Ref Mutation | git reset --hard or git branch -D inside an active worktree | Immediate invalidation of refs in sibling worktrees | Restrict agents to non-destructive commands; delegate all ref pruning to the orchestrator |
| Branch Creation Race | Concurrent git worktree add calls attempting to create identical branch names | Silent failure or hard error in the second agent spawn | Use orchestrator-assigned unique suffixes or agent-id branch prefixes |
| Reflog Contamination | Frequent concurrent commits and fast-forwards to the same local branch | Confused log histories and difficult rollbacks | Isolate working branches strictly per agent instance |
Preventing Branch Name Collisions
Preventing Branch Name Collisions Branch name collisions represent another frequent point of failure in automated orchestration. Git prohibits checking out the same branch in more than one worktree simultaneously. If an automation script spawns two agents and both attempt to create or check out agent/fix-login , the second operation fails. Relying on agents to pick their own names or depending solely on static task descriptions often results in race conditions. To eliminate this collision window at the naming layer, branch creation must be owned by the orchestrator prior to spawning the agent. Injecting a short unique suffix into the branch name ensures uniqueness without sacrificing readability.
Orchestrator Script Example
#!/usr/bin/env bash
set -euo pipefail
TASK_NAME = "fix-login"
UNIQUE_SUFFIX = "a7b3"
BRANCH_NAME = "agent/ ${ TASK_NAME } - ${ UNIQUE_SUFFIX } "
WORKTREE_PATH = ".worktrees/ ${ TASK_NAME } - ${ UNIQUE_SUFFIX } "
git branch " ${ BRANCH_NAME } " main
git worktree add " ${ WORKTREE_PATH } " " ${ BRANCH_NAME } "
echo "Spawned agent in worktree at ${ WORKTREE_PATH } on branch ${ BRANCH_NAME } "
This script demonstrates how an orchestrator can provision an isolated worktree with a collision-safe branch name before handing execution over to an agent process. By preventing agents from executing branch creation or deletion commands directly, the repository maintains structural integrity.
Securing Multi-Agent Workflows
Securing Multi-Agent Workflows Managing shared Git state effectively requires treating the object database as a global resource that only a centralized orchestrator should modify. Agents should be constrained to local commits within their assigned branch. Once an agent completes its task, the orchestrator verifies the changes, merges the results, and handles branch deletion during the cleanup phase. Adopting this defensive lifecycle prevents race conditions and ensures that parallel workflows scale reliably without stepping on each other refs.
Overview
When deploying multiple AI coding agents across isolated Git worktrees, it is common to assume complete independence. While worktrees provide separate filesystems, working directories, and HEAD pointers, they share a single underlying object database and branch namespace. This shared architecture introduces subtle failure modes when multiple agents execute git commands concurrently. Understanding these shared state hazards prevents unexpected ref corruption and silent failures during automated workflows.
Shared Ref Layer and Mutable State
The core problem stems from how Git structures worktrees. Although each worktree maintains its own checked-out files and staging index, all worktrees in a repository point to the same .git directory. The object database, reflogs, and branch references are globally mutable across the entire repository. When one agent executes a destructive command like git reset --hard or git branch -D , the mutation immediately propagates to the shared object store. Sibling worktrees referencing those same commits or branches observe the change instantly, which can break active diffing, rebasing, or logging operations. Consider a scenario where Agent A and Agent B are spawned in parallel. If Agent A performs a destructive force reset on a shared tracking branch, Agent B can experience sudden ref invalidation.
Comments
No comments yet. Start the discussion.