fix(skills): approve after trivial follow-up to COMMENTED review - #1659
worktrunk-bot wants to merge 2 commits into
Conversation
The review-pr skill assumed the prior bot review was always APPROVED when skipping trivial incremental changes. When the prior review was COMMENTED (requesting changes), the bot said "existing approval stands" but no approval existed, leaving the PR without bot approval. Extract LAST_REVIEW_STATE alongside LAST_REVIEW_SHA in the preflight, and after resolving threads on trivial follow-ups, submit an approval when the prior state was non-APPROVED. Evidence: 2 occurrences (PR #1655 run 23401754507, plus 1 historical). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rror The `(.body | length > 0 or .state == "APPROVED")` expression has a jq pipe precedence bug: `|` has the lowest precedence in jq, so `.state` resolves against the body string (pipe output), not the review object. This causes `Cannot index string with string "state"` when the bot's prior review has an empty body (every `--approve -b ""` approval). Fix: `((.body | length) > 0 or .state == "APPROVED")` — parenthesizing the pipe scopes it correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Pushed a fix for a jq pipe precedence bug in the Bug: Fix: Reproduction# Bug: errors on empty-body APPROVED review
echo '[{"author":{"login":"bot"},"body":"","state":"APPROVED","commit":{"oid":"abc"}}]' | \
jq '[.[] | select(.author.login == "bot" and (.body | length > 0 or .state == "APPROVED"))]'
# jq: error: Cannot index string with string "state"
# Fix: works correctly
echo '[{"author":{"login":"bot"},"body":"","state":"APPROVED","commit":{"oid":"abc"}}]' | \
jq '[.[] | select(.author.login == "bot" and ((.body | length) > 0 or .state == "APPROVED"))]'
# [{"author":{"login":"bot"},"body":"","state":"APPROVED","commit":{"oid":"abc"}}]Found via review-reviewers analysis of run 23402604135, which identified the precedence issue during self-review of this PR. Related tracking entry: "jq pre-flight failure in LAST_REVIEW_SHA" (1 prior occurrence). |
worktrunk-bot
left a comment
There was a problem hiding this comment.
The jq precedence fix is correct — | binds looser than or, so the original (.body | length > 0 or .state == "APPROVED") would error on empty-body approvals. The extra parens fix it.
The LAST_REVIEW_STATE logic correctly identifies the gap where trivial follow-ups to COMMENTED reviews left PRs without approval.
One concern: the new approve path (lines 63-68) doesn't account for self-authored PRs. Step 5 says "Do NOT attempt gh pr review --approve — GitHub rejects self-approvals," but the new trivial-approve path unconditionally says to submit an approval when LAST_REVIEW_STATE != APPROVED. A bot executing this on its own PR would hit a GitHub API error. Consider adding a PR_AUTHOR != BOT_LOGIN guard or a note to skip for self-authored PRs.
| ```bash | ||
| gh pr review <number> --approve -b "" | ||
| ``` | ||
| Then proceed to step 6 (monitor CI). |
There was a problem hiding this comment.
This path doesn't check for self-authored PRs. Step 5 says "Do NOT attempt gh pr review --approve — GitHub rejects self-approvals." Consider:
| Then proceed to step 6 (monitor CI). | |
| gh pr review <number> --approve -b "" |
Skip this step for self-authored PRs (PR_AUTHOR == BOT_LOGIN) —
GitHub rejects self-approvals.
Summary
LAST_REVIEW_STATEalongsideLAST_REVIEW_SHAin the review-pr skill preflightRoot cause
The review-pr skill's incremental review path (lines 53-58) said "the existing
review stands" and explicitly instructed "do not submit a new approval." This
assumed the prior review was always APPROVED. When the prior review was
COMMENTED (i.e., the bot had requested changes), the bot correctly identified
the trivial follow-up but skipped submitting an approval, leaving the PR in
limbo.
Evidence
2 confirmed occurrences of "Bot falsely claims prior approval exists":
Run 23401754507 (2026-03-22T11:08Z) — PR feat: add directional template vars to all two-worktree hooks #1655 (
template-vars). Priorbot review was state
COMMENTED. Bot concluded "existing approval stands"but no approval existed. PR left without bot approval.
1 historical occurrence tracked in review-reviewers tracking issue review-reviewers tracking: 2026-03 #1611
(original detail entry lost to tracking comment overwrite, but the finding
was carried forward in cumulative tallies across 15+ hourly runs).
Gate assessment:
Test plan
{sha, state}fromgh pr view --json reviews🤖 Generated with Claude Code