Review and merge open PRs for claimed ba tasks as a cohesive batch
/plugin marketplace add open-horizon-labs/miranda/plugin install miranda@mirandaThis skill inherits all available tools. When active, it can use any tool Claude has access to.
The collective that processes in rhythm. Holistically review pending PRs, then squash-merge them as a cohesive batch.
/drummer
Read dive context (if available) for project background:
cat .wm/dive_context.md 2>/dev/null || echo "No dive context"
This provides architecture decisions, conventions, and session intent.
Find all PRs with drummer-merge label:
gh pr list --label drummer-merge --json number,title,headRefName,baseRefName,mergeable,additions,deletions
Only PRs with the drummer-merge label are eligible for merge.
This finds ALL labeled PRs, not just those for claimed tasks.
Build dependency graph and identify stacks:
baseRefName → [PRs targeting it]baseRefName = main (or master)main ← PR #42 (ba/abc-123) ← PR #43 (ba/abc-456)
main ← PR #44 (ba/xyz-789) [separate stack]
Select stack to process:
Batch review - evaluate all PRs in the selected stack together:
sg review on the combined changesMerge stack in dependency order (root first, then children):
For each PR in the stack, starting from the root:
a. Verify CI is passing:
gh pr checks <pr-number> --fail-on-error
If CI is failing, stop and report error.
b. Rebase onto its target branch:
git fetch origin
gh pr checkout <pr-number>
git rebase origin/<base-branch> # main for root, parent branch for children
c. If .ba/ conflict, resolve mechanically (each task = one line)
d. Push rebased branch:
git push --force-with-lease
e. Squash merge:
gh pr merge <pr-number> --squash
f. For child PRs in the stack (after parent merged):
gh pr edit <child-pr-number> --base main
gh pr checkout <child-pr-number>
git rebase origin/main
git push --force-with-lease
g. Verify task closure - After each merge:
git pull origin main
# Extract task ID from branch name: ba/abc-123 → abc-123
# Note: Assumes branch follows ba/<task-id> convention from mouse skill
task_id="${headRefName#ba/}"
ba show $task_id # Check status
# If not closed, fix it:
ba finish $task_id
# If any fixes were needed:
git add .ba/ && git commit -m "fix: close task ${task_id} after merge" && git push origin main
Squash merge can lose .ba/ changes during conflict resolution.
h. On merge failure - If any PR in the stack fails to merge:
Signal completion (MANDATORY) - This is the LAST thing you do:
# On success:
curl -sS -X POST "http://localhost:${MIRANDA_PORT}/complete" \
-H "Content-Type: application/json" \
-d "{\"session\": \"$TMUX_SESSION\", \"status\": \"success\"}"
# On error:
curl -sS -X POST "http://localhost:${MIRANDA_PORT}/complete" \
-H "Content-Type: application/json" \
-d "{\"session\": \"$TMUX_SESSION\", \"status\": \"error\", \"error\": \"<reason>\"}"
If you don't signal, Miranda won't know you're done and the session becomes orphaned.
When PRs target other PR branches (not main), drummer detects the stack and processes it:
Detection:
gh pr list --label drummer-merge --json number,title,headRefName,baseRefName,mergeable
baseRefName = main are rootsbaseRefName = ba/<task-id> are children targeting that parentGraph building:
adjacency[baseRefName] = [list of PRs targeting it]
Example:
adjacency["main"] = [PR #42, PR #44]
adjacency["ba/abc-123"] = [PR #43]
Stack 1: main ← #42 (ba/abc-123) ← #43 (ba/abc-456)
Stack 2: main ← #44 (ba/xyz-789)
Merge sequence (for Stack 1):
gh pr edit 43 --base maingit rebase origin/main && git push --force-with-leaseAfter processing:
Before: PR #43 → ba/abc-123 → main
PR #42 → main
PR #44 → main (separate stack)
After: PR #42 merged to main
PR #43 rebased onto main, merged to main
PR #44 remains for next drummer run
The holistic review checks what individual PR reviews can't:
.ba/issues.jsonl is line-per-task:
drummer-merge label (human approval gate)Note: The drummer-merge label must be created in the repo. This is opt-in per repo.
status: "success"status: "error" with detailsstatus: "error" with messagedrummer-merge label found → signal status: "success" (nothing to do)$ /drummer
Finding PRs with drummer-merge label...
Found 2 PRs:
PR #42 "Fix validation bug" → main (CI ✓)
PR #44 "Refactor validator" → main (CI ✓)
Building dependency graph...
Stack 1: main ← #42
Stack 2: main ← #44
2 independent stacks, processing Stack 1
Running batch review on Stack 1 (1 PR)...
Batch review complete: ✓ No issues
Processing PR #42 (Fix validation bug)...
Verifying CI... ✓
Rebasing onto main... clean
Squash merging... ✓
Verifying task closure... ✓
Merge complete.
Merged: 1 PR (#42)
Remaining: 1 PR (#44 - queued for next run)
Signaling completion...
Done.
$ /drummer
Finding PRs with drummer-merge label...
Found 3 PRs:
PR #42 "Fix validation bug" → main (CI ✓)
PR #43 "Add edge case tests" → ba/abc-123 (CI ✓)
PR #44 "Refactor validator" → main (CI ✓)
Building dependency graph...
Stack 1: main ← #42 (ba/abc-123) ← #43 (ba/abc-456)
Stack 2: main ← #44
2 stacks found, processing Stack 1 (2 PRs)
Running batch review on Stack 1...
Collecting diffs: +547 -103 across 8 files
Batch review complete: ✓ No issues
Processing stack root: PR #42 (Fix validation bug)...
Verifying CI... ✓
Rebasing onto main... clean
Squash merging... ✓
Verifying task closure... ✓
Processing stack child: PR #43 (Add edge case tests)...
Verifying CI... ✓
Updating base branch to main... done
Rebasing onto main... clean
Conflict in .ba/issues.jsonl (expected)
Resolving: keeping all task closures
Squash merging... ✓
Verifying task closure... ✓
Stack merged.
Merged: 2 PRs (#42, #43)
Remaining: 1 PR (#44 - queued for next run)
Signaling completion...
Done.
Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.