Enter Merge Queue
Ensure a PR merges by looping through base updates, review handling, CI monitoring, and auto-merge until the PR is actually merged.
Setup
Determine the repository for all gh commands:
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
Always pass -R "$REPO" to gh commands.
Track these state flags:
has_bumped_version: Boolean, starts false. Set to true after version bump is applied.
has_waited_for_gemini: Boolean, starts false. Set to true after waiting once for Gemini.
gemini_can_review: Boolean, starts true. Set to false if PR contains only non-code files.
associated_issue_number: Number or null. Track the issue to mark needs-qa after merge.
Use polling jitter with ±20% randomization:
actual_wait = base_wait × (0.8 + random() × 0.4)
Workflow
Verify the PR exists and collect metadata.
gh pr view --json number,title,headRefName,baseRefName,url,state,labels,files,body -R "$REPO"
- Store
baseRefName for rebase.
- Detect
high-priority label.
- If all files are non-code types, set
gemini_can_review = false:
- Config:
.json, .yaml, .yml, .toml, .ini, .env*
- Docs:
.md, .txt, .rst
- Assets:
.png, .jpg, .svg, .ico, .gif
- Build/CI:
Dockerfile, .dockerignore, .gitignore
Handle issue tracking:
- Remove auto-close language from PR body (
Closes #, Fixes #, Resolves #).
- If no issue is referenced, search for an open issue referencing the PR number; create one if missing.
- When creating the issue, describe the work from the PR and add the
needs-qa label immediately.
- Store the issue number as
associated_issue_number.
Ensure you are on the PR head branch, not main.
Mark as queued in the UI and move the tmux window to the front:
setQueued.sh "(queued) #<pr-number> - <branch>"
Main loop until PR is merged:
4a. Yield to high-priority PRs unless the current PR has high-priority.
- List high-priority PRs and check their
mergeStateStatus.
- Yield if any high-priority PR is
CLEAN, BLOCKED, BEHIND, UNKNOWN, UNSTABLE, or HAS_HOOKS.
- Skip yielding if all high-priority PRs are
DIRTY.
4b. Check merge status:
gh pr view --json state,mergeStateStatus,mergeable -R "$REPO"
MERGED: exit loop.
BEHIND: update from base (4c).
BLOCKED or UNKNOWN: handle Gemini feedback while waiting for CI (4d/4e).
CLEAN: enable auto-merge (4f).
- Note: You can merge your own PRs once the branch is up to date, all required checks pass, and Gemini feedback is fully addressed. If blocked, confirm those three conditions before waiting longer.
4c. Rebase on base and bump version once:
git fetch origin <baseRefName> >/dev/null
git rebase -X theirs origin/<baseRefName> >/dev/null
If rebase conflicts:
- Prefer upstream changes and attempt an automatic resolution:
- List conflicts:
git diff --name-only --diff-filter=U
- For each conflicted file, checkout upstream:
git checkout --theirs <file>
- Stage all resolved files:
git add <file>
- Continue:
git rebase --continue
- If conflicts persist after preferring upstream:
- Run
git rebase --abort to restore the branch
- List the remaining conflicting files
- Clear the queued status with
clearQueued.sh
- Stop and ask the user for help.
If has_bumped_version is false, run bumpVersion.sh, stage the version files, amend the last commit with a GPG-signed message, and set has_bumped_version = true. Force push after rebase:
git push --force-with-lease >/dev/null
4d. Address Gemini feedback (parallel with CI):
IMPORTANT: Do NOT wait for CI to complete before addressing Gemini feedback. Handle Gemini feedback while CI is running to maximize efficiency.
Initial Gemini check (if has_waited_for_gemini is false):
gh pr view <pr-number> --json reviews -R "$REPO"
Poll every 30 seconds (with jitter) for up to 5 minutes for gemini-code-assist. Set has_waited_for_gemini = true after first review is found.
If Gemini reports unsupported file types, set gemini_can_review = false and continue to CI.
Address feedback while CI runs:
- Use
/address-gemini-feedback and /follow-up-with-gemini.
- Reply in-thread:
- List review comments:
gh api /repos/$REPO/pulls/<pr-number>/comments
- Reply in-thread:
gh api -X POST /repos/$REPO/pulls/<pr-number>/comments -F in_reply_to=<comment_id> -f body="...@gemini-code-assist ..."
- List general PR comments (issue comments):
gh api /repos/$REPO/issues/<pr-number>/comments
- Reply to general PR comments:
gh api -X POST /repos/$REPO/issues/<pr-number>/comments -f body="...@gemini-code-assist ..."
- Push commits before tagging Gemini with a hash so the hash links on GitHub and is reviewable.
- When replying that a fix is complete, include the commit hash (not just the message) and explicitly ask if the change addresses the issue (e.g., "Commit ... does this address the issue?").
- Analyze Gemini's sentiment in follow-up replies:
- If Gemini confirms/approves and does not request more changes, resolve the thread.
- If Gemini is uncertain or requests more work, keep the thread open and iterate.
- Never use
gh pr review or GraphQL review comment mutations to reply (they create pending reviews).
- Include relevant commit hashes in replies (not just titles).
- Do NOT wait for all threads to be resolved before proceeding to CI monitoring - continue to step 4e and handle remaining Gemini feedback in parallel.
4e. Wait for CI with adaptive polling and branch freshness checks:
git rev-parse HEAD
gh run list --commit <commit-sha> --limit 1 --json status,conclusion,databaseId -R "$REPO"
Poll cadence (with jitter):
- 0-5 min: every 1 min
- 5-15 min: every 2 min
- 15+ min: every 3 min
At each poll, check if the branch is behind:
gh pr view --json mergeStateStatus -R "$REPO"
If BEHIND, return to 4c immediately.
When CI completes:
- Pass: continue to 4f.
- Cancelled: rerun with
gh run rerun <run-id> -R "$REPO".
- Failed: run
/fix-tests, add tests for coverage failures, and re-run coverage locally.
4f. Enable auto-merge and wait:
If has_bumped_version is still false, perform the bump, amend, force push, and return to 4e.
gh pr merge --auto --merge -R "$REPO"
gh pr view --json state,mergeStateStatus -R "$REPO"
- Only enable auto-merge after:
- All required status checks pass
- Branch is up to date with
main (not BEHIND)
- Gemini feedback is fully addressed (per sentiment analysis)
- If auto-merge is unavailable, try a direct merge (same conditions) and continue polling.
Poll until MERGED. If BEHIND, return to 4c.
Refresh workspace after merge:
refresh.sh
Post-merge QA handling for associated_issue_number:
- Reopen the issue if closed.
- Ensure the
needs-qa label is applied.
- Prefer updating the issue body with merge status.
Report success with PR URL, a short description of the merged changes, and the associated issue status.
Keeping PR Description Updated
As you iterate, update the PR body with gh pr edit --body. Always remove auto-close language (Closes/Fixes/Resolves #...) and track the issue separately - all issues are marked needs-qa after merge. Always preserve the Claude-style format:
## Summary
- <verb-led, concrete change>
## Testing
- <command run or "not run (reason)">
## Issue
- #<issue-number>
Agent: <agent-id>
If there is no associated issue, use ## Related instead of ## Issue.
When updating the body, recompute the agent id and ensure the PR body ends with the evaluated value:
AGENT_ID=$(basename "$(git rev-parse --show-toplevel)")
Then ensure the PR body ends with Agent: ${AGENT_ID}. Add bullets for significant changes (CI fixes, Gemini feedback addressed).
Token Efficiency
Suppress stdout on git commands:
git push --force-with-lease >/dev/null
git push >/dev/null
git commit -S -m "message" >/dev/null
git fetch origin <baseRefName> >/dev/null
git rebase origin/<baseRefName> >/dev/null
Always use minimal --json fields and avoid redundant fetches.
1---2name: enter-merge-queue3description: Guarantee a PR merges by repeatedly rebasing from the base branch, fixing CI, addressing Gemini review feedback, enabling auto-merge, and waiting until the PR is merged. Use when you are asked to babysit a PR through the merge queue, resolve CI failures, handle Gemini review threads, or keep a branch up to date until merge.4---5
6# Enter Merge Queue
7
8Ensure a PR merges by looping through base updates, review handling, CI monitoring, and auto-merge until the PR is actually merged.
9
10## Setup
11
12Determine the repository for all `gh` commands:
13
14```bash
15REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
16```
17
18Always pass `-R "$REPO"` to `gh` commands.
19
20Track these state flags:
21
22- `has_bumped_version`: Boolean, starts `false`. Set to `true` after version bump is applied.
23- `has_waited_for_gemini`: Boolean, starts `false`. Set to `true` after waiting once for Gemini.
24- `gemini_can_review`: Boolean, starts `true`. Set to `false` if PR contains only non-code files.
25- `associated_issue_number`: Number or null. Track the issue to mark `needs-qa` after merge.
26
27Use polling jitter with ±20% randomization:
28
29```text
30actual_wait = base_wait × (0.8 + random() × 0.4)
31```
32
33## Workflow
34
351. Verify the PR exists and collect metadata.
36
37 ```bash
38 gh pr view --json number,title,headRefName,baseRefName,url,state,labels,files,body -R "$REPO"
39 ```
40
41 - Store `baseRefName` for rebase.
42 - Detect `high-priority` label.
43 - If all files are non-code types, set `gemini_can_review = false`:
44 - Config: `.json`, `.yaml`, `.yml`, `.toml`, `.ini`, `.env*`
45 - Docs: `.md`, `.txt`, `.rst`
46 - Assets: `.png`, `.jpg`, `.svg`, `.ico`, `.gif`
47 - Build/CI: `Dockerfile`, `.dockerignore`, `.gitignore`
48
49 Handle issue tracking:
50
51 - Remove auto-close language from PR body (`Closes #`, `Fixes #`, `Resolves #`).
52 - If no issue is referenced, search for an open issue referencing the PR number; create one if missing.
53 - When creating the issue, describe the work from the PR and add the `needs-qa` label immediately.
54 - Store the issue number as `associated_issue_number`.
55
562. Ensure you are on the PR head branch, not `main`.
57
583. Mark as queued in the UI and move the tmux window to the front:
59
60 ```bash
61 setQueued.sh "(queued) #<pr-number> - <branch>"
62 ```
63
644. Main loop until PR is merged:
65
66 4a. Yield to high-priority PRs unless the current PR has `high-priority`.
67
68 - List high-priority PRs and check their `mergeStateStatus`.
69 - Yield if any high-priority PR is `CLEAN`, `BLOCKED`, `BEHIND`, `UNKNOWN`, `UNSTABLE`, or `HAS_HOOKS`.
70 - Skip yielding if all high-priority PRs are `DIRTY`.
71
72 4b. Check merge status:
73
74 ```bash
75 gh pr view --json state,mergeStateStatus,mergeable -R "$REPO"
76 ```
77
78 - `MERGED`: exit loop.
79 - `BEHIND`: update from base (4c).
80 - `BLOCKED` or `UNKNOWN`: handle Gemini feedback while waiting for CI (4d/4e).
81 - `CLEAN`: enable auto-merge (4f).
82 - **Note**: You can merge your own PRs once the branch is up to date, all required checks pass, and Gemini feedback is fully addressed. If blocked, confirm those three conditions before waiting longer.
83
84 4c. Rebase on base and bump version once:
85
86 ```bash
87 git fetch origin <baseRefName> >/dev/null
88 git rebase -X theirs origin/<baseRefName> >/dev/null
89 ```
90
91 If rebase conflicts:
92 - Prefer upstream changes and attempt an automatic resolution:
93 - List conflicts: `git diff --name-only --diff-filter=U`
94 - For each conflicted file, checkout upstream: `git checkout --theirs <file>`
95 - Stage all resolved files: `git add <file>`
96 - Continue: `git rebase --continue`
97 - If conflicts persist after preferring upstream:
98 - Run `git rebase --abort` to restore the branch
99 - List the remaining conflicting files
100 - Clear the queued status with `clearQueued.sh`
101 - Stop and ask the user for help.
102
103 If `has_bumped_version` is `false`, run `bumpVersion.sh`, stage the version files, amend the last commit with a GPG-signed message, and set `has_bumped_version = true`. Force push after rebase:
104
105 ```bash
106 git push --force-with-lease >/dev/null
107 ```
108
109 4d. Address Gemini feedback (parallel with CI):
110
111 **IMPORTANT**: Do NOT wait for CI to complete before addressing Gemini feedback. Handle Gemini feedback while CI is running to maximize efficiency.
112
113 **Initial Gemini check** (if `has_waited_for_gemini` is `false`):
114
115 ```bash
116 gh pr view <pr-number> --json reviews -R "$REPO"
117 ```
118
119 Poll every 30 seconds (with jitter) for up to 5 minutes for `gemini-code-assist`. Set `has_waited_for_gemini = true` after first review is found.
120
121 If Gemini reports unsupported file types, set `gemini_can_review = false` and continue to CI.
122
123 **Address feedback while CI runs**:
124
125 - Use `/address-gemini-feedback` and `/follow-up-with-gemini`.
126 - Reply in-thread:
127 - List review comments: `gh api /repos/$REPO/pulls/<pr-number>/comments`
128 - Reply in-thread: `gh api -X POST /repos/$REPO/pulls/<pr-number>/comments -F in_reply_to=<comment_id> -f body="...@gemini-code-assist ..."`
129 - List general PR comments (issue comments): `gh api /repos/$REPO/issues/<pr-number>/comments`
130 - Reply to general PR comments: `gh api -X POST /repos/$REPO/issues/<pr-number>/comments -f body="...@gemini-code-assist ..."`
131 - **Push commits before tagging Gemini with a hash** so the hash links on GitHub and is reviewable.
132 - When replying that a fix is complete, **include the commit hash (not just the message) and explicitly ask if the change addresses the issue** (e.g., "Commit <hash> ... does this address the issue?").
133 - Analyze Gemini's sentiment in follow-up replies:
134 - If Gemini confirms/approves and does not request more changes, resolve the thread.
135 - If Gemini is uncertain or requests more work, keep the thread open and iterate.
136 - Never use `gh pr review` or GraphQL review comment mutations to reply (they create pending reviews).
137 - Include relevant commit hashes in replies (not just titles).
138 - **Do NOT wait for all threads to be resolved before proceeding to CI monitoring** - continue to step 4e and handle remaining Gemini feedback in parallel.
139
140 4e. Wait for CI with adaptive polling and branch freshness checks:
141
142 ```bash
143 git rev-parse HEAD
144 gh run list --commit <commit-sha> --limit 1 --json status,conclusion,databaseId -R "$REPO"
145 ```
146
147 Poll cadence (with jitter):
148 - 0-5 min: every 1 min
149 - 5-15 min: every 2 min
150 - 15+ min: every 3 min
151
152 At each poll, check if the branch is behind:
153
154 ```bash
155 gh pr view --json mergeStateStatus -R "$REPO"
156 ```
157
158 If `BEHIND`, return to 4c immediately.
159
160 When CI completes:
161 - Pass: continue to 4f.
162 - Cancelled: rerun with `gh run rerun <run-id> -R "$REPO"`.
163 - Failed: run `/fix-tests`, add tests for coverage failures, and re-run coverage locally.
164
165 4f. Enable auto-merge and wait:
166
167 If `has_bumped_version` is still `false`, perform the bump, amend, force push, and return to 4e.
168
169 ```bash
170 gh pr merge --auto --merge -R "$REPO"
171 gh pr view --json state,mergeStateStatus -R "$REPO"
172 ```
173
174 - Only enable auto-merge after:
175 - All required status checks pass
176 - Branch is up to date with `main` (not `BEHIND`)
177 - Gemini feedback is fully addressed (per sentiment analysis)
178 - If auto-merge is unavailable, try a direct merge (same conditions) and continue polling.
179
180 Poll until `MERGED`. If `BEHIND`, return to 4c.
181
1825. Refresh workspace after merge:
183
184 ```bash
185 refresh.sh
186 ```
187
188 Post-merge QA handling for `associated_issue_number`:
189 - Reopen the issue if closed.
190 - Ensure the `needs-qa` label is applied.
191 - Prefer updating the issue body with merge status.
192
1936. Report success with PR URL, a short description of the merged changes, and the associated issue status.
194
195## Keeping PR Description Updated
196
197As you iterate, update the PR body with `gh pr edit --body`. Always remove auto-close language (`Closes/Fixes/Resolves #...`) and track the issue separately - all issues are marked `needs-qa` after merge. Always preserve the Claude-style format:
198
199```text
200## Summary
201- <verb-led, concrete change>
202
203## Testing
204- <command run or "not run (reason)">
205
206## Issue
207- #<issue-number>
208
209Agent: <agent-id>
210```
211
212If there is no associated issue, use `## Related` instead of `## Issue`.
213
214When updating the body, recompute the agent id and ensure the PR body ends with the evaluated value:
215
216```bash
217AGENT_ID=$(basename "$(git rev-parse --show-toplevel)")
218```
219
220Then ensure the PR body ends with `Agent: ${AGENT_ID}`. Add bullets for significant changes (CI fixes, Gemini feedback addressed).
221
222## Token Efficiency
223
224Suppress stdout on git commands:
225
226```bash
227git push --force-with-lease >/dev/null
228git push >/dev/null
229git commit -S -m "message" >/dev/null
230git fetch origin <baseRefName> >/dev/null
231git rebase origin/<baseRefName> >/dev/null
232```
233
234Always use minimal `--json` fields and avoid redundant fetches.