Ready for Merge
This is the mandatory gate before merging any PR in this repository. Do not tell the user a PR is ready to merge until every step below has been completed and passes.
Address Greptile as soon as a PR exists. When you open or update a PR, run Step 2 in the same turn: fetch Greptile comments, fix valid findings, reply, and resolve threads. Do not leave Greptile feedback for a later merge pass.
This skill never merges the PR. Merging is the user's decision alone — do not run
gh pr merge (or click-through equivalents) even if everything passes, and even if merging was
approved earlier in the conversation. The skill ends by handing the PR back to the user.
Work against the PR for the current branch (gh pr view --json number,url,headRefName). If no
PR exists, stop and tell the user.
Step 1 — Code review with fixes, scaled to the PR
Look at the PR's diff (gh pr diff <number> --stat and the diff itself) and pick the
code-review effort level that matches its breadth and risk — don't default to the maximum:
- low — mechanical or single-concern changes: a flag flip, a docstring/docs edit, a dependency bump, a few-line fix with an obvious test.
- medium — a small focused change: one behavior touched across a handful of files, new code paths that are well covered by tests. Most small PRs land here.
- high — a multi-file feature, changes to shared infrastructure, or anything where a subtle interaction with existing callers is plausible.
- xhigh — large or risky PRs: core engine/provider seams, data-loss or security surface, broad refactors, anything hard to roll back once merged.
State the level you chose and why in one sentence, then run the code-review skill with args
<level> --fix.
Let it finish and apply its fixes before moving on. If it applied changes, re-run the project gate afterwards (see Step 3).
Step 2 — Resolve every review comment on the PR
Fetch all comments and review threads on the PR — from Cursor (bugbot), Greptile, any other bot reviewers, and human reviewers:
gh pr view <number> --comments
gh api repos/{owner}/{repo}/pulls/<number>/comments --paginate
gh api graphql -f query='...reviewThreads(first: 100){ nodes { isResolved comments(first: 50){ nodes { author { login } body path line } } } }...'
For every single comment, without exception:
- Read it and decide whether it is valid.
- If valid: fix the code, then reply to the thread stating what was changed (reference the fix commit).
- If invalid or out of scope: reply to the thread explaining why — never silently ignore it.
- Mark the thread resolved (GraphQL
resolveReviewThread) once addressed.
The step is done only when zero unresolved review threads remain. Re-check with the GraphQL query above; do not assume.
This process is iterative — poll for reviewers, don't sleep blind
Every time you push fixes, Cursor and Greptile re-review the PR and humans may leave new comments. One pass is never enough. After each push:
- Poll for reviewer reaction instead of sleeping a fixed 3 minutes: check every ~20 seconds
for new comments or review threads (same queries as Step 2), and stop polling as soon as a
new bot review lands — bots usually post within 60–90 seconds. Cap the wait at 3 minutes;
a capped wait with no new activity counts as a quiet window.
start=$(date +%s); while [ $(( $(date +%s) - start )) -lt 180 ]; do # re-fetch comments/threads; break out early if anything new appeared sleep 20 done - If new unresolved comments appeared, handle them exactly as in Step 2 (fix or reply, then resolve), push, and repeat from 1.
- Only exit the loop when a quiet window produces zero new comments and zero unresolved threads.
Step 3 — AGENTS.md compliance
Read AGENTS.md in full and audit the PR's complete diff (gh pr diff <number>) against every
rule. In particular verify:
- Checks are clean, scoped to the diff:
uv run ruff check .anduv run ty check(both fast) always; pytest targeted at the packages the PR touches (uv run pytest exp/<pkg>/ -q) during fix iterations. Run the fulluv run pytest -qonly once, before the final hand-off, and only when the PR touchesexp/code at all (docs/skills-only diffs skip it). - Module docstrings and Google-style docstrings on significant classes/functions.
- Tests live inline next to the code (
foo.py→foo_test.py); new behavior has a test or eval that would catch its regression. - No
Any, baredict/object, or untyped**kwargswhere a concrete type is practical. - NO new top-level directory or file, of any name, unless the PR description records that a
human granted permission for that exact name (AGENTS.md rule 5). The tracked top level is
closed:
exp/,docs/,.claude/,.github/. Reusable code goes inexp/(shared contracts inexp/common/and runtime adapters inexp/runtime/), finished reports indocs/, and scratch work outside the repo entirely. Benchmark data is a dependency, never a directory. - Imports at module scope, fail-fast; no silent
ImportErrorfallbacks. - End-to-end verification was actually done for anything with a runtime surface — drive it, don't just trust exit codes.
- Visuals (if any) follow the brand system.
Fix any violation found. Do not rationalize a violation as pre-existing if the PR touches that code.
Step 4 — Report back and hand off — do NOT merge
Push any fixes made in Steps 1–3, then report a checklist to the user:
-
/code-review <level> --fixcompleted (state the level chosen and why; N findings, M fixed) - All review comments resolved (list each commenter and how their comments were handled)
- AGENTS.md audit clean (note any rules that required fixes)
- Checks green (lint/types always; tests scoped to the diff, one full run before hand-off
when the PR touches
exp/) - Final polled quiet window after the last push produced zero new comments
If every box is checked, end by telling the user:
Hey — everything is done, ready for you to merge:
then stop. Do not merge the PR yourself under any circumstances; the merge button belongs to the user. If anything cannot be resolved, report it as a blocker instead.