Repository navigation
Description
Problem Statement
Squad agents can add files to (or remove files from) a PR that are unrelated to the original PR's purpose. This is a design-level issue — not a single bug, but multiple overlapping contamination vectors in Squad's git operations, Scribe's commit patterns, and the default no-worktree architecture.
Investigation Summary
A deep codebase investigation identified 7 distinct root causes across three severity tiers.
🔴 HIGH RISK — Active contamination vectors
1. git add . in Agent Spawn Templates
The issue lifecycle template (issue-lifecycle.md:234) instructs agents to run git add . when addressing PR review feedback — this stages EVERYTHING in the working directory, not just the agent's work.
| Location | Pattern | What it stages |
|---|---|---|
.squad-templates/issue-lifecycle.md:234 |
git add . |
ALL files in cwd |
.copilot/skills/git-workflow/SKILL.md:102 |
git add -A |
ALL changes in working tree |
Scenario: Agent works on issue #42, modifies src/auth.ts. Meanwhile, another session left .squad/agents/dallas/history.md dirty. Agent runs git add . → stages BOTH the intended fix AND the unrelated history change. PR includes files the agent never touched.
2. Scribe's Broad git add .squad/ Pattern
Scribe runs after every work batch and executes git add .squad/ — a recursive add of the ENTIRE .squad/ directory tree.
| Location | Pattern |
|---|---|
.squad-templates/scribe-charter.md:64 |
git add .squad/ |
.squad-templates/squad.agent.md:885 |
git add .squad/ && commit |
.copilot/skills/windows-compatibility/SKILL.md:42 |
git add .squad/ |
Scenario: Agent A on branch squad/42-fix-auth modifies .squad/agents/ripley/history.md. Agent B on a different task modifies .squad/agents/dallas/history.md in the same working directory. Scribe runs git add .squad/ → stages BOTH history files. PR for issue #42 now shows dallas's history change.
3. No Worktree Isolation by Default
Worktree mode is opt-in (SQUAD_WORKTREES=1). By default, all agents work in the same repository directory. When multiple issues are worked concurrently:
- All agents share the same working tree and git index
- File writes from one issue's agents are visible to another issue's agents
- Scribe's
git add .squad/captures changes from ALL concurrent work
Evidence: packages/squad-sdk/src/agents/history-shadow.ts:17-23 explicitly acknowledges concurrent append to same history.md as a known pattern, with only in-process mutex protection (no cross-process locking).
🟡 MEDIUM RISK — Structural contamination patterns
4. merge=union State Accumulation
.gitattributes configures merge=union on append-only files:
.squad/decisions.md merge=union
.squad/agents/*/history.md merge=union
.squad/log/** merge=union
.squad/orchestration-log/** merge=union
When branches merge, .squad/ state from ALL branches combines. PRs show decisions/history from unrelated work after rebase. Intentional design, but surprising to PR reviewers.
5. Scribe Creates New Files Every Session
Every Scribe run creates NEW files:
| File Pattern | Created When |
|---|---|
.squad/orchestration-log/{timestamp}-{agent}.md |
Every agent batch |
.squad/log/{timestamp}-{topic}.md |
Every session |
.squad/decisions-archive.md |
When decisions.md > 20KB |
.squad/agents/{name}/history-archive.md |
When history.md > 12KB |
These appear as "new files" in PR diffs even though they're operational state.
6. Decision Inbox Lifecycle Timing
Agents write to .squad/decisions/inbox/{name}-{slug}.md. Scribe merges and deletes them. If Scribe fails or timing is off, inbox files persist in the PR. (Mitigated by .gitignore covering inbox, but the timing gap creates confusion.)
🟢 LOW RISK — Edge cases
7. Template Sync Side Effects
scripts/sync-templates.mjs copies from .squad-templates/ to three mirror locations. If triggered during agent work, mirror files get updated and could appear in a PR. (Squad-project-specific.)
Existing Safeguards (What's Already Working)
| Safeguard | Effective? |
|---|---|
.gitignore excludes orchestration-log/, log/, inbox/, config.json |
✅ Yes |
squad-promote.yml blocks .squad/ on preview/main |
✅ Yes |
merge=union prevents merge conflicts |
✅ Yes (but causes accumulation) |
Scribe scoped to git add .squad/ |
🟡 Partial — still too broad |
| Worktree isolation (when enabled) | ✅ Yes (but opt-in) |
| In-process mutex for history.md | 🟡 Same-process only |
Proposed Fixes
| # | Root Cause | Proposed Fix |
|---|---|---|
| 1 | git add . in issue-lifecycle |
Replace with git add -- {specific files} or agent-tracked file list |
| 2 | Scribe's broad git add .squad/ |
Replace with explicit file list targeting only files Scribe actually modified |
| 3 | No worktree isolation by default | Consider worktrees-by-default, or add PR readiness check for unrelated .squad/ changes |
| 4 | merge=union accumulation |
Add PR readiness check that flags .squad/ changes unrelated to the PR's issue |
| 5 | Scribe creates new files every session | Already mitigated by .gitignore for most files |
| 6 | Decision inbox timing | Already mitigated by .gitignore |
| 7 | Template sync | Gate sync behind explicit command |
Files Investigated
.squad-templates/squad.agent.md(Scribe spawn template).squad-templates/scribe-charter.md(Scribe git operations).squad-templates/issue-lifecycle.md(agent git add patterns).copilot/skills/git-workflow/SKILL.md(git workflow skill).copilot/skills/windows-compatibility/SKILL.md(Windows git patterns)packages/squad-sdk/src/agents/history-shadow.ts(concurrent write mutex)packages/squad-sdk/src/resolution.ts(worktree resolution)packages/squad-cli/src/cli/core/detect-squad-dir.ts(worktree detection).gitattributes(merge=union config).gitignore(excluded.squad/paths).github/workflows/squad-promote.yml(release safeguards)- All
.github/workflows/squad-*.yml(workflow git operations)
Activity
github-actions commentedon Apr 3, 2026
🏗️ Squad Triage — Flight (Lead)
Issue: #777 — PR file contamination: Squad adds/removes unrelated files from PRs
Assigned to: FIDO (Quality Owner)
Reason: Issue relates to testing/quality work
@copilot evaluation: 🔴 Not suitable — issue involves work outside the coding agent's capability profile.
Team roster:
squad:flightsquad:proceduressquad:eecomsquad:fidosquad:paosquad:capcomsquad:controlsquad:surgeonsquad:boostersquad:gncsquad:networksquad:retrosquad:incosquad:guidosquad:telemetrysquad:voxsquad:dskysquad:simssquad:handbooksquad:ralphsquad:copilotdiberry commentedon Apr 3, 2026
Clarification: Product vs. Repo-Local Scope
This issue spans two distinct scopes — changes to Squad the product (affecting all users) and changes local to the Squad repo itself. The PRD should be restructured to reflect this.
Squad the Product (ships to all users via npm)
These are template/SDK changes that propagate to every
squad initinstallation:git add ..squad-templates/issue-lifecycle.md.squad-templates/scribe-charter.md,.squad-templates/squad.agent.mdpackages/squad-cli/src/cli/core/init.ts, SDK codeRepo-Local (only affects bradygaster/squad development)
These are skills/scripts that guide agents working on the Squad codebase itself:
.copilot/skills/git-workflow/SKILL.md.copilot/skills/windows-compatibility/SKILL.mdscripts/sync-templates.mjsCould Be Either/Both
.github/workflows/squad-pr-hygiene.ymlImpact
The PRD should be restructured into two tracks:
This matters for prioritization: product fixes have multiplicative impact (every user benefits), while repo-local fixes only help this repo.
fix: eliminate PR contamination from broad git staging (#777)
fix: eliminate PR contamination from broad git staging (#777)
fix: eliminate PR contamination from broad git staging (#777)
fix: eliminate PR contamination from broad git staging (#777)
fix: eliminate PR contamination from broad git staging (#777) (#783)