Repository navigation
Description
Summary
squad upgrade overwrites .github/agents/squad.agent.md unconditionally, with no customization warning and no version check. If the bundled template is older than what is on disk, the coordinator is silently downgraded — including reverting merged, committed hardening.
This is not hypothetical. It happened in this repo on 2026-08-02 and shadowed #1537.
What happened
.github/agents/squad.agent.md was written to disk at 20:58:35 with pre-merge content. Four minutes later, cd6961e9 merged #1537 (squad/dispatch-enforcement, @tamirdresher) into dev.
Because the file was already dirty, git left it alone. The working copy then sat byte-identical to the pre-merge commit:
on-disk 2c9b5993
parent 1 2c9b5993 ← byte-identical (15af9864, pre-merge)
HEAD da59cb5f ← merge result, with the hardening
Nobody edited the file. It was written by tooling and then never advanced past the merge.
Consequence: every Copilot session in this repo since then loaded the stale coordinator. Verified by marker string — the on-disk copy contained work inline (fallback only — LAST RESORT), which does not exist in HEAD; HEAD instead says refuse, and carries the mandatory DispatchGuard bootstrap and the Direct-Mode whitelist. So Layer A tool restriction and DispatchGuard were both inert, silently, for a full day of sessions.
The irony is that the specific thing silently reverted was dispatch enforcement.
Root cause
packages/squad-cli/src/cli/core/templates.ts:33-38:
{
source: 'squad.agent.md.template',
destination: '../.github/agents/squad.agent.md',
overwriteOnUpgrade: true,
description: 'Squad coordinator agent prompt',
},Overwriting is correct by design for consumer repos — Squad owns this file. The defects are the absent guards:
- No customization warning. Skills get one —
upgrade.ts:744callswarnIfSkillCustomized(srcPath, destPath, entry.source)before copying. The coordinator file, which is the single highest-impact file in the system, gets no equivalent (upgrade.ts:1176). - No version/downgrade check. An older installed CLI happily overwrites a newer coordinator. Nothing compares the stamped version in the destination against the template's.
- No backup. The prior content is unrecoverable outside git.
Why this bites hardest in this repo
bradygaster/squad dogfoods itself. Any squad init / squad upgrade / npx @bradygaster/squad-cli run here overwrites the repo's own committed coordinator with whatever the installed CLI bundles — reverting merged PRs with no output indicating it happened.
Related: #1588 (unpinned SDK). Same family of problem — the installed artifact's contents are less pinned than they appear.
Suggested fix
At minimum, parity with the skills path:
- Warn when the destination differs from the last-installed template (mirror
warnIfSkillCustomized) - Compare the version stamp in the destination against the template; refuse or require
--forceon downgrade - Back up the previous file (e.g.
.squad/.backup/squad.agent.md.{version}) before overwriting - Consider refusing to self-overwrite when the target repo is the squad repo
Repro
# in a repo with a customized/newer .github/agents/squad.agent.md
npx @bradygaster/squad-cli@<older> upgrade
git diff .github/agents/squad.agent.md # silently reverted, no warning emittedFound via
Investigating an unexplained 80-line "deletion" in the working tree while verifying #1587. The file was restored with git checkout (provably lossless — old content is preserved at 15af9864).
Activity
bradygaster commentedon Aug 30, 2026
Related issue (Ralph triage): This is related to but not a duplicate of #1502. #1502 tracks the broader configurable runner/checkout umbrella; this issue is specifically the silent-overwrite/downgrade bug in \squad upgrade\ for .github/agents/squad.agent.md. Both should remain open and are tracked separately.
github-actions commentedon Sep 10, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 10, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 11, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 11, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 11, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 11, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 11, 2026
🔄 Ralph — Auto-Triage
Assigned to: EECOM
Reason: Matched module path "src/cli/" to primary owner "EECOM 🔧"
Source: module-ownership
github-actions commentedon Sep 13, 2026
🔄 Ralph — Auto-Triage
Assigned to: architect
Reason: No module, routing, or role keyword match — routed to Lead/Architect
Source: lead-fallback
github-actions commentedon Sep 24, 2026
📋 Assigned to cli-dev (CLI Engineer)
Issue: #1589 — fix(cli): squad upgrade silently overwrites and can downgrade .github/agents/squad.agent.md
cli-dev will pick this up in the next Copilot session.