Skip to content

Commit fddabad

Browse files
committed
feat(babysit-prs): add skill to drive a PR through review to a clean 5/5
Ships (via /ship's sync check), waits for Greptile/Cursor Bugbot, triages every open thread (fix real findings, push back on false positives), replies + resolves each thread, re-triggers review, and loops until Greptile is 5/5 with zero open threads.
1 parent 9b964ad commit fddabad

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
name: babysit-prs
3+
description: Drive a PR to a clean review (Greptile 5/5, zero open threads) — ships if needed, triggers Greptile/Cursor Bugbot, fixes real findings, replies to and resolves every thread, and loops until clean
4+
---
5+
6+
# Babysit PRs
7+
8+
Owns a PR end-to-end through review: ship it, wait for the automatic review round, and if it
9+
isn't already clean, drive fix → reply → resolve → re-review cycles until Greptile reports 5/5
10+
and there are zero open comment threads. Designed to be run under `/loop` (no fixed interval —
11+
let it self-pace on review latency) so it survives across multiple wakeups in the same session.
12+
13+
## When to use
14+
15+
- The user says "babysit this PR", "keep working the reviews until it's clean", or similar
16+
- As the natural follow-up to `/ship` when the user wants the review loop automated rather than
17+
manually re-triggering reviews and answering comments themselves
18+
19+
## Inputs
20+
21+
Needs a PR number. If none is given and there's no open PR for the current branch, run `/ship`
22+
first (which includes the `origin/staging` sync check — see `.agents/skills/ship/SKILL.md`) to
23+
create one.
24+
25+
## Definition of "clean"
26+
27+
Both must hold:
28+
1. The latest Greptile summary comment reports **Confidence Score: 5/5**
29+
2. `reviewThreads` (GraphQL, see below) has **zero threads with `isResolved: false`**
30+
31+
Do not stop early on "no new comments this round" alone — a thread can be open from an earlier
32+
round. Always check both conditions freshly after every push.
33+
34+
## Loop
35+
36+
1. **Check current state** before doing anything:
37+
```bash
38+
gh pr view <n> --json comments -q '.comments[] | select(.author.login=="greptile-apps") | .body' | tail -1
39+
gh api graphql -f query='
40+
query { repository(owner: "<owner>", name: "<repo>") { pullRequest(number: <n>) {
41+
reviewThreads(first: 50) { nodes { id isResolved path line
42+
comments(first: 5) { nodes { id databaseId author { login } body } } } } } } }'
43+
```
44+
If Greptile is 5/5 and every thread's `isResolved` is `true`, stop — report the outcome (see
45+
"Reporting" below) and skip the rest of this list.
46+
47+
2. **If no review has run yet** (fresh PR, no Greptile/Cursor comments): they usually run
48+
automatically on PR open — confirm via `gh pr checks <n>` (look for `Cursor Bugbot` /
49+
`Greptile Review`) and wait for that first round before doing anything else.
50+
51+
3. **If a review round has landed and it isn't clean**: for every thread where
52+
`isResolved: false`, triage the finding on its own merits — this is the part that requires
53+
judgment, not a mechanical loop:
54+
- **Real bug**: fix it in the cleanest way available. Match the codebase's existing
55+
conventions for that kind of problem before inventing a new one (e.g. an SSRF-prone
56+
user-supplied-host fetch should use whatever `validateUrlWithDNS`/`secureFetchWithPinnedIP`
57+
pattern the rest of the codebase already uses for that exact situation — grep for a sibling
58+
integration solving the same problem first). Never patch around a finding with a
59+
workaround, a broad try/catch, or a suppression comment — fix the actual cause.
60+
- **False positive**: don't change code. Reply with the specific reason it doesn't apply
61+
(cite the type definition, the established pattern it matches, or the doc it follows) so
62+
the reviewer bot and a human skimming later both understand why it was left as-is.
63+
- **Already fixed by an earlier finding in the same round**: note that and resolve without a
64+
duplicate code change.
65+
66+
4. **Reply to every thread individually** before resolving it — never resolve silently:
67+
```bash
68+
gh api repos/<owner>/<repo>/pulls/<n>/comments/<databaseId>/replies -f body="<what was done and why>"
69+
```
70+
Then resolve via GraphQL (needs the thread `id` from step 1, not the comment id):
71+
```bash
72+
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<threadId>"}) { thread { isResolved } } }'
73+
```
74+
75+
5. **Before pushing, re-run the sync check** from `/ship` step 2
76+
(`git fetch origin staging && git log --oneline origin/staging..HEAD` should list only this
77+
session's commits) — a babysit loop that runs over a long session is exactly the scenario
78+
where a branch can drift. Then run the repo's lint/typecheck/boundary-validation gates the
79+
same way `/ship` does before committing.
80+
81+
6. **Commit and push** the round's fixes as one commit (`--force-with-lease` only if step 5's
82+
sync check required a rebuild).
83+
84+
7. **Re-trigger review** by posting `@greptile` and `@cursor review` as **two separate PR
85+
comments** — never combine them into one comment, each bot only responds to its own mention:
86+
```bash
87+
gh pr comment <n> --body "@greptile"
88+
gh pr comment <n> --body "@cursor review"
89+
```
90+
91+
8. **Wait for the new round**, then go back to step 1. Pace the wait with `ScheduleWakeup` using
92+
a fallback delay of ~250–300s (Greptile/Cursor typically take 1–3 minutes) — never busy-poll
93+
in a sleep loop. Pass the same `/loop babysit PR <n>` prompt on each wakeup so the loop
94+
resumes correctly.
95+
96+
9. **Stop conditions**: clean state reached (see above), or the same unresolved finding survives
97+
two consecutive rounds with no new information (surface it to the user instead of looping
98+
forever), or the user interrupts.
99+
100+
## Reporting
101+
102+
When the loop ends, summarize: how many rounds it took, what was actually fixed (one line each),
103+
what was pushed back on as a false positive and why, and the final Greptile score / thread count.
104+
105+
## Hard rules
106+
107+
- Never post the two re-review mentions as a single combined comment.
108+
- Never resolve a thread without replying to it first.
109+
- Never fix a finding with a hacky workaround — if the clean fix isn't obvious, find the sibling
110+
pattern elsewhere in the codebase solving the same class of problem and match it.
111+
- Never silently drop a finding — every thread gets either a code fix or a reasoned reply.
112+
- Always re-run the `/ship`-style sync check before every push in the loop, not just the first.

0 commit comments

Comments
 (0)