Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/contamination-guard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
---

ci: add PR contamination prevention guard

New diff-guard CI check warns when single-commit PRs touch 30+ files
(likely branch contamination). Updated copilot-instructions with branch
creation and staging safety rules.
4 changes: 4 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

---

### ⚠️ Quick Check
- [ ] If SDK/CLI source files changed: completed the applicable Changeset step below (`npx changeset add` / `.changeset/*.md`, direct `CHANGELOG.md` entry for maintainers, or `skip-changelog` label for no user-facing changes)

### PR Readiness Checklist

> The PR readiness bot will validate these automatically after push.
Expand All @@ -17,6 +20,7 @@
#### Branch & Commit
- [ ] Branch created from `dev` (not `main`)
- [ ] Branch is up to date with `dev` (`git fetch upstream && git rebase upstream/dev`)
- [ ] Verified diff contains only intended changes (`git diff --cached --stat`)
- [ ] PR is **not** in draft mode (mark ready when checks pass)
- [ ] Commit history is clean (squash fixups before review)

Expand Down
30 changes: 30 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ Before pushing any commit, verify:
3. `npm run build` — build succeeds with your changes
4. Commit message references the issue: `Closes #N`

### Branch Contamination Prevention
- When creating PR branches, always branch from the latest upstream dev: `git fetch upstream && git checkout dev && git rebase upstream/dev && git checkout -b <branch>`
- NEVER use `git reset --soft` to squash on branches behind dev — it picks up all the delta between your branch and dev, contaminating the commit
- To squash safely: use `git rebase -i` or amend the single commit with `git commit --amend`
- Before committing, ALWAYS verify the diff: `git diff --cached --stat` should show ONLY your intended files
- If you see unexpected files in the diff, unstage them: `git reset HEAD <file>`

### Red Flags — STOP and Ask
If you see any of these, STOP immediately and comment on the issue asking for guidance:
- More than 20 files in your diff
Expand Down Expand Up @@ -116,6 +123,29 @@ When reviewing or creating PRs, consult these skills for domain-specific checkli

Read the relevant skill(s) before submitting or reviewing a PR that touches their domain.

## PR Scope Rules

Scope is determined by PR labels, not by branch name. Continue using the squad branch convention: `squad/{issue-number}-{slug}`.
- **Repo-health PRs** (label `repo-health`): Only modify `.github/`, `scripts/`, root config files, test files, and docs. NEVER modify files under `packages/*/src/`.
- **Product PRs** (label `fix` or `feat`): May modify product source code. Must include changesets when required by the rules below.
- If a task requires both infrastructure and product changes, create separate PRs.

## Changeset Requirement

Any PR that modifies files under `packages/squad-cli/src/` or `packages/squad-sdk/src/` MUST include a changeset file.

- Run `npx changeset add` and select the affected package(s)
- Or manually create `.changeset/{descriptive-name}.md` with format:
```
---
'@bradygaster/squad-cli': patch
---
Brief description of the change
```
- Use `patch` for bug fixes, `minor` for new features, `major` for breaking changes
- The `changelog-gate` CI check will fail without this
- Escape hatch: add the `skip-changelog` label (use sparingly)

## Decisions

If you make a decision that affects other team members, write it to:
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/squad-repo-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,33 @@ jobs:
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
exit $EXIT_CODE

# ─── Diff Size Guard (WARNING) ─────────────────────────────────────
diff-guard:
name: Diff Size Guard
runs-on: ubuntu-latest
timeout-minutes: 2
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR head (data only — not executed)
run: git fetch origin ${{ github.event.pull_request.head.sha }}
- name: Check for likely contamination
run: |
git fetch origin dev --quiet
FILE_COUNT=$(git diff --name-only origin/dev...${{ github.event.pull_request.head.sha }} | wc -l)
COMMIT_COUNT=$(git rev-list --count origin/dev..${{ github.event.pull_request.head.sha }})

# Heuristic: if a single-commit PR touches more than 30 files, it's likely contaminated
if [ "$COMMIT_COUNT" -le 2 ] && [ "$FILE_COUNT" -gt 30 ]; then
echo "::warning::⚠️ This PR has $COMMIT_COUNT commit(s) but touches $FILE_COUNT files."
echo "::warning::This may indicate branch contamination from broad staging (--all or .) on a stale branch."
echo "::warning::Please verify all changed files are intentional: git diff --name-only origin/dev...${{ github.event.pull_request.head.sha }}"
else
echo "✅ Diff looks proportional: $COMMIT_COUNT commit(s), $FILE_COUNT file(s)."
fi

# ─── Squad File Leakage (WARNING) ───────────────────────────────────
squad-leakage:
name: Squad File Leakage
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ GitHub Actions runs on every push:
2. **Test:** `npm test`
3. **Lint:** `npm run lint`
4. **Changeset status:** `npm run changeset:check` (ensures PRs include a changeset)
5. **Diff Size Guard:** Warns when a single-commit PR touches 30+ files (likely branch contamination from staging all files at once on a stale branch). Always use explicit `git add <file>` instead.

All checks must pass before merge.

Expand Down
Loading