Skip to content

PR file contamination: Squad adds/removes unrelated files from PRs #777

Closed

Description

@diberry

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

  1. added
    squadSquad triage inbox — Lead will assign to a member
    on Apr 3, 2026
  2. github-actions commented on Apr 3, 2026

    @github-actions
    Contributor

    🏗️ 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:

    • Flight (Lead) → label: squad:flight
    • Procedures (Prompt Engineer) → label: squad:procedures
    • EECOM (Core Dev) → label: squad:eecom
    • FIDO (Quality Owner) → label: squad:fido
    • PAO (DevRel) → label: squad:pao
    • CAPCOM (SDK Expert) → label: squad:capcom
    • CONTROL (TypeScript Engineer) → label: squad:control
    • Surgeon (Release Manager) → label: squad:surgeon
    • Booster (CI/CD Engineer) → label: squad:booster
    • GNC (Node.js Runtime) → label: squad:gnc
    • Network (Distribution) → label: squad:network
    • RETRO (Security) → label: squad:retro
    • INCO (CLI UX & Visual Design) → label: squad:inco
    • GUIDO (VS Code Extension) → label: squad:guido
    • Telemetry (Aspire & Observability) → label: squad:telemetry
    • VOX (REPL & Interactive Shell) → label: squad:vox
    • DSKY (TUI Engineer) → label: squad:dsky
    • Sims (E2E Test Engineer) → label: squad:sims
    • Handbook (SDK Usability) → label: squad:handbook
    • Ralph (Work Monitor) → label: squad:ralph
    • @copilot (Coding Agent) → label: squad:copilot

    To reassign, remove the current squad:* label and add the correct one.

  3. diberry commented on Apr 3, 2026

    @diberry
    ContributorAuthor

    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 init installation:

    Work Item File Why it's product
    WI-1: Replace git add . .squad-templates/issue-lifecycle.md Product template — every Squad user gets this
    WI-2: Scope Scribe's git add .squad-templates/scribe-charter.md, .squad-templates/squad.agent.md Product templates
    WI-6: Worktree default packages/squad-cli/src/cli/core/init.ts, SDK code Product runtime
    WI-8: merge=union docs Product docs User-facing documentation

    Repo-Local (only affects bradygaster/squad development)

    These are skills/scripts that guide agents working on the Squad codebase itself:

    Work Item File Why it's repo-local
    WI-3: git-workflow skill .copilot/skills/git-workflow/SKILL.md Repo-specific skill
    WI-4: windows-compat skill .copilot/skills/windows-compatibility/SKILL.md Repo-specific skill
    WI-7: Template sync guard scripts/sync-templates.mjs Repo build tooling

    Could Be Either/Both

    Work Item File Notes
    WI-5: PR hygiene workflow .github/workflows/squad-pr-hygiene.yml Currently repo-local, but could become a product template

    Impact

    The PRD should be restructured into two tracks:

    1. Product track — ships with the next Squad release, fixes contamination for all users
    2. Repo-local track — fixes contamination for Squad's own development workflow

    This matters for prioritization: product fixes have multiplicative impact (every user benefits), while repo-local fixes only help this repo.

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

    go:needs-researchNeeds investigationsquadSquad triage inbox — Lead will assign to a member

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions