Skip to content

Commit 0f9cca4

Browse files
authored
fix(skills): prevent /review from spamming @greptileai when already approved (#628)
* fix(skills): prevent /review from spamming @greptileai when already approved The review skill's re-trigger logic only checked for emoji reactions on reply comments, missing the case where Greptile's initial review was already positive with no inline comments (e.g. thumbsup + no comments). This caused repeated @greptileai triggers on PRs like #621. Replace the single emoji-on-reply check with a proper decision matrix: - Thumbsup on trigger + no inline comments + >15min = approved, skip - <15min since trigger = wait, don't re-trigger - Outstanding inline comments after addressing = re-trigger * fix(skills): address Greptile review feedback on decision matrix (#628) - Exclude greptile-apps[bot] from trigger comment filter to prevent matching Greptile's own response bodies containing @greptileai - Add null guard: check trigger_count before querying reactions API to avoid 404 when no prior @greptileai comment exists - Add two missing decision matrix branches: "thumbsup + inline comments" and "no thumbsup + >15 min + no inline comments" - Add elapsed-time computation using python3 + date for reliable minute calculation * fix(skills): handle first-ever @greptileai trigger in decision matrix (#628) When trigger_count is 0 (no prior @greptileai comment), the flow was falling through to Check 2 which skips re-triggering if no code changes were made in response to Greptile comments. For a brand-new PR this is trivially true, so the first trigger would never fire. Now the trigger_count=0 branch posts @greptileai directly and proceeds to the wait-and-recheck loop.
1 parent 3929746 commit 0f9cca4

1 file changed

Lines changed: 53 additions & 10 deletions

File tree

.claude/skills/review/SKILL.md

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,60 @@ After addressing all comments for a PR:
201201

202202
### 2g. Re-trigger reviewers
203203

204-
**Greptile:** Before re-triggering, check if your last reply to Greptile already has a positive emoji reaction (thumbs up, check, party, etc.) from `greptileai`. A positive reaction means Greptile is satisfied with your fix — do NOT re-trigger in that case, move on. Only re-trigger if there is no positive reaction on your last comment:
204+
**Greptile:** Only re-trigger if Greptile has outstanding concerns that you addressed. Before posting `@greptileai`, run these checks — if any says "skip", do NOT re-trigger:
205205

206-
```bash
207-
# Check reactions on your most recent comment to see if Greptile already approved
208-
gh api repos/optave/codegraph/issues/<number>/comments --paginate \
209-
--jq 'reverse | .[] | select(.user.login != "greptileai") | {id: .id, body: .body[0:80], reactions_url: .reactions_url}' | head -1
206+
1. **Check if the last `@greptileai` trigger was already approved.** Find the most recent `@greptileai` comment (from anyone), then check if Greptile reacted to it with a thumbsup (+1). If it did, check whether Greptile posted any new inline review comments *after* that reaction. If thumbsup exists AND no new inline comments AND more than 15 minutes have passed since the trigger — Greptile approved. **Skip re-triggering.**
210207

211-
# If no positive reaction from greptileai, re-trigger:
212-
gh api repos/optave/codegraph/issues/<number>/comments \
213-
-f body="@greptileai"
214-
```
208+
```bash
209+
# Count prior @greptileai trigger comments (excluding Greptile's own responses)
210+
trigger_count=$(gh api repos/optave/codegraph/issues/<number>/comments --paginate \
211+
--jq '[.[] | select(.body | test("@greptileai")) | select(.user.login != "greptile-apps[bot]")] | length')
212+
213+
if [ "$trigger_count" -eq 0 ]; then
214+
# No prior trigger exists — first-ever run. Skip approval check AND check 2.
215+
# Trigger Greptile for the first time (there are no prior comments to "respond to").
216+
echo "No prior @greptileai trigger found. Triggering Greptile for the first time."
217+
gh api repos/optave/codegraph/issues/<number>/comments -f body="@greptileai"
218+
# After posting, proceed to step 2h (wait and re-check).
219+
else
220+
# Find the last @greptileai trigger comment (excluding Greptile's own responses)
221+
trigger_comment=$(gh api repos/optave/codegraph/issues/<number>/comments --paginate \
222+
--jq '[.[] | select(.body | test("@greptileai")) | select(.user.login != "greptile-apps[bot]")] | last | {id: .id, created_at: .created_at}')
223+
trigger_id=$(echo "$trigger_comment" | jq -r '.id')
224+
trigger_time=$(echo "$trigger_comment" | jq -r '.created_at')
225+
226+
# Check if greptile-apps[bot] thumbsupped the trigger comment
227+
thumbsup_count=$(gh api repos/optave/codegraph/issues/comments/$trigger_id/reactions \
228+
--jq '[.[] | select(.user.login == "greptile-apps[bot]" and .content == "+1")] | length')
229+
230+
# Count Greptile inline comments created after the trigger
231+
inline_count=$(gh api repos/optave/codegraph/pulls/<number>/comments --paginate \
232+
--jq "[.[] | select(.user.login == \"greptile-apps[bot]\" and .created_at > \"$trigger_time\")] | length")
233+
234+
# Compute elapsed minutes since the trigger
235+
trigger_epoch=$(python3 -c "from datetime import datetime; print(int(datetime.fromisoformat('$trigger_time'.replace('Z','+00:00')).timestamp()))")
236+
now_epoch=$(date -u +%s)
237+
elapsed_minutes=$(( (now_epoch - trigger_epoch) / 60 ))
238+
echo "Minutes since trigger: $elapsed_minutes"
239+
fi
240+
```
241+
242+
**Decision logic:**
243+
- Thumbsup exists AND no new inline comments AND >15 min since trigger → **Greptile approved. Skip re-triggering.**
244+
- Thumbsup exists AND new inline comments exist → **Treat inline comments as outstanding concerns. Address them (step 2e), then re-trigger.** (Greptile sometimes thumbsups but still leaves nit comments.)
245+
- Thumbsup exists AND no new inline comments AND <15 min since trigger → **Greptile is still processing. Wait until 15 min have passed**, then re-check. Do NOT post another `@greptileai`.
246+
- No thumbsup AND <15 min since trigger → **Greptile hasn't responded yet. Wait until 15 min have passed**, then re-check.
247+
- No thumbsup AND >15 min AND new inline comments exist → **Greptile has concerns. Address them (step 2e), then re-trigger.**
248+
- No thumbsup AND >15 min AND no new inline comments → **Greptile never responded. Re-trigger once** (it may have missed the notification).
249+
250+
2. **Check if you actually addressed any Greptile feedback.** If you made no code changes in response to Greptile comments (e.g., you only fixed CI or Claude comments), there's nothing new for Greptile to review — **skip re-triggering.**
251+
252+
3. **Only if both checks above indicate outstanding concerns**, re-trigger:
253+
254+
```bash
255+
gh api repos/optave/codegraph/issues/<number>/comments \
256+
-f body="@greptileai"
257+
```
215258

216259
**Claude (claude-code-review / claude bot):** Only re-trigger if you addressed something Claude specifically suggested. If you did:
217260

@@ -270,7 +313,7 @@ If any subagent failed or returned an error, note it in the Status column as `ag
270313
- **Never force-push** unless fixing a commit message that fails commitlint. Amend + force-push is the only way to fix a pushed commit title (messages are part of the SHA). This is safe on feature branches. For all other problems, fix with a new commit.
271314
- **Address ALL comments from ALL reviewers** (Claude, Greptile, and humans), even minor/nit/optional ones. Leave zero unaddressed. Do not only respond to one reviewer and skip another.
272315
- **Always reply to comments** explaining what was done. Don't just fix silently. Every reviewer must see a reply on their feedback.
273-
- **Don't re-trigger Greptile if already approved.** If your last reply to a Greptile comment has a positive emoji reaction from `greptileai`, it's already satisfied — skip re-triggering.
316+
- **Don't re-trigger Greptile if already approved.** If Greptile thumbsupped the last `@greptileai` trigger and posted no new inline comments, it's approved — skip re-triggering. If less than 15 minutes have passed since the last trigger, **wait** — do NOT post another `@greptileai`. Only re-trigger after confirming Greptile has outstanding concerns and you addressed them.
274317
- **Only re-trigger Claude** if you addressed Claude's feedback specifically.
275318
- **No co-author lines** in commit messages.
276319
- **No Claude Code references** in commit messages or comments.

0 commit comments

Comments
 (0)