Skip to content

Commit be36f9b

Browse files
Merge remote-tracking branch 'origin/main' into feat/issue-sweep
# Conflicts: # AGENTS.md
2 parents 31c246b + d3fe2e4 commit be36f9b

3 files changed

Lines changed: 285 additions & 58 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This is a **Claude Code plugins repository** containing production-ready hooks f
1717
| **content-guards** | Pre/PostToolUse | Bash, Write, Edit | Token limits, markdown/README validation, webfetch guard, issue/PR backlog limits, public-repo leakage guard |
1818
| **git-guards** | PreToolUse | Bash, Edit, Write, NotebookEdit | Blocks dangerous git/gh commands and file edits on main branch |
1919
| **git-workflows** | Command/Skill | `/sync-main`, `/git-flow-next`, `/troubleshoot-rebase`, `/troubleshoot-precommit`, `/troubleshoot-worktree`, `/pre-commit-architecture` | Local git sync, branching model, and rebase/pre-commit/worktree troubleshooting |
20-
| **github-workflows** | Command/Skill | `/ship`, `/finalize-pr`, `/refresh-repo`, `/prune-branches` (incl. `--sweep` and `--prune-stale` modes), `/rebase-pr`, `/merge-pr` (incl. `--squash`/`-s`), `/pr-sweep`, `/issue-sweep`, `/resolve-pr-threads`, `/gh-cli-patterns`, `/shape-issues`, `/trigger-ai-reviews` | GitHub PR/issue management workflows, cross-repo workspace sweep, stale-branch pruning, risk-ranked open-PR sweep-to-zero, and issue sweeps that reconcile open issues against reality |
20+
| **github-workflows** | Command/Skill | `/ship`, `/finalize-pr`, `/refresh-repo`, `/prune-branches` (incl. `--sweep` and `--prune-stale` modes), `/rebase-pr`, `/merge-pr` (incl. `--squash`/`-s`), `/pr-sweep`, `/issue-sweep`, `/resolve-pr-threads`, `/gh-cli-patterns`, `/shape-issues`, `/trigger-ai-reviews` | GitHub PR/issue management workflows, cross-repo workspace sweep, stale-branch pruning, parallel open-PR sweep-to-zero, and issue sweeps that reconcile open issues against reality |
2121
| **infra-orchestration** | Skill | `/orchestrate-infra`, `/sync-inventory`, `/test-e2e` | Cross-repo infrastructure orchestration for Terraform and Ansible |
2222
| **code-standards** | Skill | `/code-quality-standards`, `/review-standards` | Code quality standards, documentation formatting, testing philosophy, and review guidelines |
2323
| **git-standards** | Skill | `/git-workflow-standards`, `/pr-standards` | Git workflow standards, branch hygiene, PR creation guards, workaround vs fix classification, and issue linking |
Lines changed: 110 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,142 @@
11
---
22
name: pr-sweep
3-
description: "Drive open PRs toward zero across one or many repos by risk-ranking every open PR, auto-merging the low-risk mergeable ones, and surfacing the rest with the exact reason each is held. Use when open PRs have piled up and you want them triaged and cleared in one pass. Batches over the existing /merge-pr and /finalize-pr per PR — it decides which PRs are safe to merge and delegates the merge, it does not reimplement merging."
3+
description: "Use when open pull requests have piled up in one repo or across an owner's repos and you want the pile triaged and driven toward zero in one pass — including when most of them are bot- or teammate-authored. Also use when a sweep must run many repos in parallel without racing approvals or flooding CI."
44
---
55

66
# PR Sweep
77

8-
Take a pile of open PRs and drive it to zero: merge what is safe, surface what is
9-
not with a specific reason. This is triage-and-clear, distinct from
10-
`/prune-branches --sweep` (which deletes dead branches and worktrees). This
11-
skill acts on **open PRs**; that one acts on **repo/worktree state**.
8+
Drive a pile of open PRs toward zero: merge what is safe, repair what is
9+
cheaply repairable, and surface the rest with a concrete reason each. This is
10+
triage-and-clear on **open PRs**; `/prune-branches --sweep` acts on
11+
**repo/worktree state** and is a different job.
1212

13-
It does not reimplement merging. It **risk-ranks**, then hands each merge to
14-
`/merge-pr` (which itself runs the readiness gate and calls `/finalize-pr`).
15-
Merges use `/merge-pr`'s default (merge commit) — this sweep never passes
16-
`--squash`.
13+
This skill decides **which** PRs move and in **what order**. It never
14+
reimplements merging: each merge is delegated to `/merge-pr`, each repair to
15+
`/finalize-pr`.
1716

18-
> **State warning**: PR status, CI, and mergeability change between invocations.
19-
> Re-list and re-check every PR in this run; never act on a cached list.
17+
## Invariants
2018

21-
## Scope
22-
23-
- `/pr-sweep` — open PRs in the current repo.
24-
- `/pr-sweep --org <owner>` — open PRs authored by you across the owner's repos
25-
(`gh search prs --owner <owner> --author @me --state open`).
19+
These four hold in every mode. They are the difference between a sweep and a
20+
stampede.
2621

27-
Always list first, act second. State the count before touching anything.
22+
1. **Triage is read-only and confers no merge authority.** Classifying a PR
23+
never merges it.
24+
2. **A merge happens only against an execution order that pins the head
25+
commit.** If the head moved since triage, the order is void — re-triage.
26+
This is what makes an approval round impossible to race.
27+
3. **Serialize within a repo; parallelize across repos.** Merge ordering,
28+
broken-base diagnosis, and repo-wide gates are all repo-scoped.
29+
4. **Cap concurrent merges globally** (default 2–3). Every merge triggers CI,
30+
and CI capacity is finite and shared.
2831

29-
## Step 1: List and gather signal
32+
Never pass `--admin`. Never merge a draft. Never bypass a failing check —
33+
repair it or hold the PR.
3034

31-
For every open PR, collect the merge-decision signals in one pass:
35+
> **State warning**: PR status, CI, and mergeability change constantly, and
36+
> `mergeable`/`mergeStateStatus` are computed lazily — a first query often
37+
> returns `UNKNOWN`. Re-query before classifying, and never act on a list
38+
> gathered earlier in the session.
3239
33-
```bash
34-
gh pr view <N> --json number,title,url,isDraft,mergeable,mergeStateStatus,\
35-
reviewDecision,additions,deletions,changedFiles,labels,baseRefName,headRefName
36-
```
37-
38-
Also resolve whether the repo is git-flow (default branch `develop`) — a
39-
`develop → main` promotion PR is never swept (see Hold reasons).
40+
## Merge method is not this skill's business
4041

41-
## Step 2: Risk-rank each PR
42+
`/merge-pr` resolves the merge method from the repo's capabilities and the
43+
branching model — see **git-flow-next** (git-workflows) for which method each
44+
target branch requires. This skill passes no method flag and states no
45+
default. A promotion PR into a production branch is never swept: hold it and
46+
point at `/promote-release`.
4247

43-
Rank by blast radius and confidence, low to high:
48+
## Scope
4449

45-
| Risk | Signals |
50+
- `/pr-sweep` — open PRs in the current repo.
51+
- `/pr-sweep --org <owner>` — open PRs across the owner's repos, **all
52+
authors**. Bot and teammate PRs are usually the bulk of a real pile.
53+
- `--author <login>` — optional filter. Do not default to "mine": some token
54+
types (app installation tokens) carry no user identity, so a self-filter
55+
silently returns nothing.
56+
57+
Command shapes live in **gh-cli-patterns**. List first, act second, and state
58+
the count before touching anything.
59+
60+
## Phases
61+
62+
Run all five in order. Phases 1 and 3 fan out; 0, 2, and 4 are the lead's.
63+
64+
- **Phase 0 — Manifest (lead).** Enumerate repos × open PRs in one pass.
65+
Report the count. Spawn one worker per repo, capped (default 4 concurrent).
66+
- **Phase 1 — Triage (workers, parallel, read-only).** Each worker classifies
67+
every PR in its repo and detects repo-level conditions (broken base,
68+
repo-wide gate). Output: one report block per repo. No writes.
69+
- **Phase 2 — Approval (lead, one round).** Batch **all** escalations into a
70+
single round — one short paragraph per PR: identity, diffstat, state, and
71+
the specific yes/no question. No diffs. Then issue per-repo execution
72+
orders: `(PR number, head OID)` plus any ordering constraints.
73+
- **Phase 3 — Execute (workers).** Continue the *same* worker by message so it
74+
keeps its triage context. Per repo, serially: take a merge-budget slot,
75+
assert the head OID still matches, delegate to `/merge-pr`, wait on
76+
merge-triggered CI with an event-driven monitor, release the slot. `FIX`
77+
items go to `/finalize-pr`, then back through triage.
78+
- **Phase 4 — Verify and report (lead).** Wait for merge-triggered CI to
79+
settle, then attribute every red by timestamp against merge time before
80+
claiming a clean sweep.
81+
82+
The lead does exactly two blocking things: the Phase 2 round and the Phase 4
83+
aggregation. It never re-derives repo state itself.
84+
85+
## Classification
86+
87+
Every PR gets exactly one verdict.
88+
89+
| Verdict | Meaning |
4690
| --- | --- |
47-
| **Low** (auto-merge candidate) | `mergeable == MERGEABLE`, CI clean (`mergeStateStatus` CLEAN), not draft, no unresolved threads, small diff, docs/config/test-only or a bot dependency bump from a trusted source |
48-
| **Medium** (surface, do not auto-merge) | app/library code, larger diff, passing CI but no review, or any label like `needs-review`/`blocked` |
49-
| **High** (surface, flag loudly) | touches auth/secrets/migrations/infra, failing or pending CI, conflicts, or a `develop → main` promotion |
50-
51-
The bar for **auto-merge** is deliberately conservative: low risk **and** nothing
52-
held. When unsure, rank up — a surfaced PR costs a glance; a wrongly-merged one
53-
costs a revert.
91+
| **MERGE** | Mergeable, checks green, not draft, no unresolved threads, and either low blast radius or an approved escalation. |
92+
| **FIX** | One delegated `/finalize-pr` away from mergeable — unresolved review threads, a stale rollup, a repairable check. Re-triage after. |
93+
| **HOLD** | Cannot proceed without a decision or new work. Always carries a reason. |
94+
| **ESCALATE** | Mergeable but the *judgment* is not the sweep's to make. Goes to Phase 2 as a question, never as an assumption. |
5495

55-
## Step 3: Auto-merge the low-risk set
96+
Rank up when unsure. A surfaced PR costs a glance; a wrongly-merged one costs
97+
a revert.
5698

57-
For each low-risk PR, delegate — do not merge by hand:
99+
## Hold reasons (never auto-merge)
58100

59-
- Invoke **`/merge-pr <N>`** (no `--squash`). It re-runs the readiness gate, calls
60-
`/finalize-pr` for soft blocks, and aborts on hard stops. Trust its refusal: if
61-
it declines, the PR moves to the surfaced list with that reason.
62-
- Never pass `--admin`, never bypass a failing check, never merge a draft.
101+
- Draft, merge conflicts, or checks failing for a real (non-infrastructure)
102+
reason.
103+
- A promotion PR into a production branch — use `/promote-release`.
104+
- Changes touching auth, secrets, migrations, permissions, or live infra — a
105+
human decides.
106+
- An explicit human "do not merge", or a review-gate label. A prior human
107+
refusal outranks the sweep.
108+
- `/merge-pr` refused — carry its reason forward verbatim.
109+
- A PR another session is actively working (recently pushed, in flight).
63110

64-
## Step 4: Report
111+
## Report
65112

66113
```text
67114
PR Sweep — <scope>
68-
Swept (merged): <N> — <title> (× each)
69-
Held: <N> — <reason: draft | CI red | conflicts | needs review | promotion | high-risk>
115+
Merged: <repo#N> — <title>
116+
Fixed+merged: <repo#N> — <what was repaired>
117+
Held: <repo#N> — <reason>
118+
Escalated: <repo#N> — <question> → <decision>
119+
Repo findings: <broken base | repo-wide gate | infra failure>
70120
Open before → after: <b> → <a>
71121
```
72122

73-
Every PR is either merged or listed with a concrete reason — never silently
74-
skipped. If nothing is low-risk, say so; a sweep that merges nothing is a valid
75-
outcome, not a failure.
123+
Every PR is merged or listed with a concrete reason — never silently skipped.
124+
A sweep that merges nothing is a valid outcome. File follow-ups per the
125+
project's issue-routing convention, and end a run that is blocked on a human
126+
decision by naming that decision.
76127

77-
## Hold reasons (never auto-merge)
128+
## Mechanics
78129

79-
- Draft, failing/pending CI, merge conflicts, unresolved review threads.
80-
- `develop → main` promotion PRs — use `/promote-release`.
81-
- Anything touching auth, secrets, DB migrations, or live infra — a human decides.
82-
- `/merge-pr` refused — carry its reason forward verbatim.
130+
Diagnosis and parallel-protocol detail — lazy state, `UNSTABLE` vs `BLOCKED`,
131+
broken-base proof, repo-wide gates, infrastructure-failure signatures, worker
132+
and order schemas: see [references/sweep-mechanics.md](references/sweep-mechanics.md).
83133

84134
## Related Skills
85135

86-
- **merge-pr** (github-workflows) — performs each merge; this skill decides which.
87-
- **finalize-pr** (github-workflows) — PR metadata/soft-block handling, via merge-pr.
88-
- **prune-branches** (github-workflows) — the repo/worktree sweep; complementary, not this.
89-
- **promote-release** (github-workflows) — the correct path for held promotion PRs.
136+
- **merge-pr** (github-workflows) — performs each merge and owns method resolution.
137+
- **finalize-pr** (github-workflows) — drives one PR to mergeable; the `FIX` delegate.
138+
- **resolve-pr-threads** (github-workflows) — review-thread resolution.
139+
- **gh-cli-patterns** (github-workflows) — canonical command shapes and queries.
140+
- **promote-release** (github-workflows) — the held-promotion path.
141+
- **git-flow-next** (git-workflows) — the branching model that decides merge method.
142+
- **prune-branches**, **refresh-repo** (github-workflows) — complementary cleanup.

0 commit comments

Comments
 (0)