Skip to content

Coordinator should detect concurrent background spawns on a shared worktree and warn (or auto-isolate) — real-world git-race incident observed #1014

Closed

Description

@steveisok

Note

This issue was drafted by GitHub Copilot in collaboration with the issue author. The incident details, root-cause analysis, and mitigation options are captured from a real Squad session on a downstream project.

Summary

When two or more background agents (spawned via task with mode: "background") run concurrently against the same git worktree, global-scope git operations from one agent (git stash, git clean, git restore) can wipe untracked files created by the other agent. Squad already supports per-stream worktree isolation (SQUAD_WORKTREES=1), but the default is off — and the coordinator gives no warning when it spawns parallel background agents into a shared worktree, so the race is silent until it bites.

This report proposes either (a) switching the default when parallel background spawns are detected, or (b) surfacing a one-line warning so the operator can opt in.

Real-world incident (dotnet/runtime-style port, April 2026)

  • Setup: Squad wave with two concurrent background streams — Parker (Stream A, adding new files under src/) and Lambert (Stream C.1, editing src/.../Validators.cs). Both running on the same worktree, worktrees: false.
  • What happened: Between two of Parker's tool calls, Lambert's commit workflow invoked a git cleanup command (git stash or equivalent). Parker's three untracked files were swept up and cleared. Parker's subsequent git status showed unrelated Lambert modifications, no trace of his own work.
  • Recovery: Parker recreated the files from the same content and committed immediately. No production-code loss. But the incident is real and would have been worse if Parker hadn't been in the middle of an active session with the content still in context.
  • User response: Switched the remainder of that wave to serial execution. Two subsequent single-agent waves completed clean. No repeat incidents, but the parallelism benefit was lost.

Why the current default is a footgun

  1. Squad already encourages parallel background spawns. The governance doc explicitly says "Spawn all independent agents as mode: "background" in a single tool-calling turn" and "When in doubt, default to background." This is correct — parallelism is the main throughput lever.
  2. The worktree-mode opt-in is documented but easy to miss. SQUAD_WORKTREES=1 and worktrees: true in config are both supported, but nothing in the spawn flow surfaces them unless the user knows to look.
  3. The race is probabilistic. It fires only when agent A has untracked files at the exact moment agent B runs a global-scope git command. This means teams will parallelise happily for many waves before hitting it, then lose trust in the model when they do.
  4. The failure mode is silent corruption, not a hard error. Git doesn't complain; the files just vanish. Only the in-session agent context has any memory of what should exist. Recovery depends on the agent noticing and re-creating — which is unreliable across silent-success and context-compaction edge cases.

Proposed mitigations (pick one — not all)

Option A — Warn-only (cheap, low-risk). When the coordinator is about to spawn ≥2 background agents in a single tool-calling turn AND worktree mode is not enabled, emit a visible warning before spawning:

⚠️  Launching 3 parallel background agents in shared-worktree mode.
   Global-scope git operations (stash/clean/restore) from one agent can
   affect another agent's untracked files. Enable worktree isolation
   with `SQUAD_WORKTREES=1` or `worktrees: true` in your squad config.

This gives the user a one-shot decision point. Implementation cost: trivial (coordinator already knows the spawn count and the worktree mode at that moment).

Option B — Auto-enable worktree isolation when N ≥ 2. Flip the default so that any turn with ≥2 concurrent background spawns auto-creates per-stream worktrees, unless the user has explicitly set worktrees: false. Higher value, higher cost (coordination overhead, node_modules linking, merge-back at wave close). Already largely built — just needs auto-activation logic.

Option C — Agent-side defensive discipline guidance. Update spawn prompts to tell agents "commit untracked files immediately; do not rely on leaving them untracked across tool calls." This is agent discipline, not infrastructure. Won't stop a determined git clean from another stream, but raises the bar. Cheap but weakest.

Recommendation: Start with Option A (warn-only) as a v0.9.2 change. It's the cheapest move that converts the silent failure into a visible decision point. Promote to Option B once there's usage data showing people turn worktrees on after seeing the warning — or leave them the choice permanently. Option C is worth adding to spawn prompts regardless.

Non-goals

  • Not asking for full serial-execution-by-default — that kills the parallelism value prop.
  • Not asking to abolish worktrees: false as a supported mode — single-agent waves and solo-dev flows benefit from the simpler model.
  • Not asking for file-locking or git-wrapper interception — both are more invasive than the root problem.

Additional context

  • The downstream decision log capturing this incident at the project level (with full option analysis) is available if useful — happy to share the D74 excerpt separately rather than inlining it here.
  • The incident classifier I'd use: Severity: Medium — possible but rare at current workflow scale; grows in likelihood with stream count.

What we tried

  • Defensive discipline (Option C approximation): Worked for the affected wave only because the user caught it in-session and switched to serial for the remaining streams. Not a general solution.
  • Reading the docs: SQUAD_WORKTREES=1 is documented in squad.agent.md. It works when enabled. The gap is purely "nobody knew to enable it until after the incident."

Version

Observed on Squad v0.9.1.

Activity

  1. omercangumus commented on Jul 14, 2026

    @omercangumus
    Contributor

    picking this up as the warn-only path from the issue — keep shared-worktree mode working, but make 2+ background spawns without worktree isolation visibly call out the git-race risk before launch. auto-isolate (option B) stays a follow-up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triagedIssue has been triagedwave:2-soonWave 2 — next 2-4 weeks

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions