From 2ad742974357ee2888808e4d1a818a5bd589fc4a Mon Sep 17 00:00:00 2001 From: Claude Code Bot Date: Fri, 1 May 2026 16:58:42 -0700 Subject: [PATCH] feat: minimize PASS review comments via GraphQL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the verdict check, when verdict is PASS, locate the just-posted claude-blocking-review comment for the current SHA and minimize it as RESOLVED. BLOCK comments stay un-minimized — humans need to see them. Why: downstream tooling (post-push-status.sh) scrapes bot comments to surface unresolved findings, but it has no way to distinguish PASS from BLOCK on its own. Minimizing PASS comments lets the scraper skip them via the GraphQL isMinimized field (coordinating PR in claude-config). The comment body is preserved in the PR thread under the standard "Resolved" disclosure, so the audit trail is intact. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/claude-blocking-review.yml | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/claude-blocking-review.yml b/.github/workflows/claude-blocking-review.yml index e2376b0..43b26a9 100644 --- a/.github/workflows/claude-blocking-review.yml +++ b/.github/workflows/claude-blocking-review.yml @@ -552,3 +552,69 @@ jobs: echo "**Verdict:** UNKNOWN (unexpected format — defaulting to PASS)" >> "$GITHUB_STEP_SUMMARY" exit 0 fi + + - name: Minimize PASS review comment + if: always() && steps.doc-check.outputs.skip != 'true' + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + PR_NUMBER: ${{ inputs.pr_number }} + SHA: ${{ github.event.pull_request.head.sha || github.sha }} + run: | + # Minimize PASS comments so downstream scrapers (post-push-status.sh + # and similar tooling) don't treat them as unresolved findings. BLOCK + # comments must remain visible — humans need to act on them. The + # comment body is preserved in the PR thread under a collapsed + # "Resolved" disclosure, so the audit trail is intact. + + # Skip if the [skip-claude-review] escape hatch was used. + PR_BODY=$(gh pr view "$PR_NUMBER" --json body -q .body 2>/dev/null || echo "") + if echo "$PR_BODY" | grep -qE '\[skip-claude-review(\]|:)'; then + echo "[skip-claude-review] override active — nothing to minimize." + exit 0 + fi + + VERDICT_FILE="/tmp/review-verdict.txt" + if [ ! -f "$VERDICT_FILE" ]; then + echo "No verdict file — nothing to minimize." + exit 0 + fi + if ! head -1 "$VERDICT_FILE" | grep -q "VERDICT: PASS"; then + echo "Verdict is not PASS — leaving comment visible." + exit 0 + fi + + OWNER="${REPO%/*}" + NAME="${REPO#*/}" + + # Locate the just-posted claude-blocking-review comment for this exact + # SHA. `last: 20` is plenty — the comment was posted seconds ago. + COMMENT_ID=$(gh api graphql \ + -f query='query($owner: String!, $name: String!, $number: Int!) { + repository(owner: $owner, name: $name) { + pullRequest(number: $number) { + comments(last: 20) { + nodes { id body isMinimized } + } + } + } + }' \ + -f owner="$OWNER" -f name="$NAME" -F number="$PR_NUMBER" \ + --jq ".data.repository.pullRequest.comments.nodes[] | select(.isMinimized == false) | select(.body | startswith(\"