Repository navigation
Description
🔥 P0: @copilot accidentally deleted 361 source files on dev branch
Incident
Commit 1ab2f5c (2026-03-26 01:46 PST) was pushed directly to dev by the @copilot coding agent while fixing a broken docs link (issue #610). The commit message says "fix broken link" but the actual diff is:
- 6 files modified (the intended docs fix)
- 361 files DELETED — the entire SDK and CLI source code
367 files changed, 292 insertions(+), 69,245 deletions(-)
What Was Deleted
packages/squad-sdk/src/— entire SDK (storage, config, agents, runtime, coordinator, hooks, etc.)packages/squad-cli/src/cli/commands/— all 26 CLI commandspackages/squad-cli/src/cli/core/— all 14 core modulespackages/squad-cli/src/cli/shell/— entire shell infrastructurepackages/squad-sdk/templates/— all template files including workflows- Multiple test files
Impact
devbranch is broken. Any checkout after1ab2f5cis missing the entire codebase.- All PRs targeting
devcannot build or test. - No release artifacts corrupted (npm publish is disabled).
- Parent commit
28ea025is fully intact — recovery is trivial.
Root Cause
@copilot pushed directly to dev with no PR. The agent likely had an incomplete working tree (missing files appeared as deletions) and used git add . or git commit -a, bundling 361 deletions alongside the 6-file docs fix. No branch protection exists on dev, so there was no gate.
Recovery (one command)
# Option A: Revert
git revert 1ab2f5c --no-edit && git push origin dev
# Option B: Restore from parent
git checkout 28ea025 -- packages/squad-cli/ packages/squad-sdk/ test/ templates/
git commit -m "fix: restore files accidentally deleted in 1ab2f5c"
git push origin devPrevention — Recommended Action Items
Immediate
- Revert
devto restore the 361 deleted files - Enable branch protection on
dev— require PR + 1 approval before merge - Restrict
@copilotfrom direct push — agent should only open PRs, not push to protected branches
Short-term
- Add file-deletion guard to CI — fail if a commit deletes >50 files without
large-deletion-approvedlabel - Add source-tree canary check — verify key files (
packages/squad-sdk/src/index.ts, etc.) exist before build - Update
copilot-instructions.md— add: "Never usegit add .orgit commit -a. Always stage specific files." - Move CI on
devfrom push-trigger to PR-required — CI should gate merges, not observe them after
Medium-term
- Pre-commit hook warning on >20 file deletions
- @copilot PR template with checklist:
[ ] git status clean,[ ] no unintended deletions - Audit Copilot agent permissions — review write-access scope
Analysis
The structural conditions that enabled this:
devhas zero branch protection (mainis protected,devis not)- CI runs after push, not as a merge gate
@copilothas unrestricted write access todev- No anomaly detection for large file-count changes
This is an isolated incident (only 1 Copilot commit in recent history), but the conditions remain in place for every future agent action until the branch protection and CI gates are added.
Discovered By
@diberry — while rebasing PR #18 onto upstream/dev and encountering 78 modify/delete conflicts. Investigation traced to commit 1ab2f5c.
Activity
diberry commentedon Mar 26, 2026
cc @bradygaster — this is urgent. \dev\ HEAD (\1ab2f5c) is missing the entire SDK and CLI source (361 files deleted by @copilot's docs fix). Recovery is one command: \git checkout 28ea025 -- packages/squad-cli/ packages/squad-sdk/ test/ templates/ && git commit && git push. The parent commit \28ea025\ is fully intact. The key prevention fix is enabling branch protection on \dev\ so @copilot can only open PRs, not push directly.
docs(squad): log #631 investigation session
fix(ci): add deletion guard and source tree canary check (#631)
fix(security): add git safety rules to copilot-instructions.md (#631)
bradygaster commentedon Mar 26, 2026
✅ Resolved. Revert commit ac3dafe restored all 361 deleted files on dev. CI deletion guards and copilot git safety rules incoming via PRs.
docs(squad): close #631 incident response — revert, CI guards, git sa…
chore(scribe): merge 3 pending inbox decisions into decisions.md
docs(decisions): rescue two orphaned decision records and drain the i…