diff --git a/.github/workflows/claude_auto_reviewer.yml b/.github/workflows/claude_auto_reviewer.yml index e5d76b2f2..44510efc0 100644 --- a/.github/workflows/claude_auto_reviewer.yml +++ b/.github/workflows/claude_auto_reviewer.yml @@ -1,6 +1,14 @@ name: Claude Auto Review + +# Code-level review on every non-draft PR into stage: bugs, security, performance, and CLAUDE.md +# "Review red flags" only. The Claude Change Verifier workflow owns "what does this change do" +# and acceptance-criteria QA — this workflow must never duplicate that. Findings land as inline +# comments; each run posts a fresh single-line verdict comment (deliberately NOT updated in +# place) so the PR timeline shows the review history: "1 blocker" → fix commits → "no blockers". + on: pull_request: + branches: [stage] types: [opened, synchronize, reopened, ready_for_review] jobs: @@ -24,20 +32,72 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | - REPO: ${{ github.repository }} - PR NUMBER: ${{ github.event.pull_request.number }} + You are the CODE reviewer for this pull request. A separate "QA Review" workflow + already summarizes what the change does and validates it against the linked issue's + acceptance criteria. Do not duplicate it: no change summary, no restating the diff, + no judging whether the PR satisfies its issue, no test-coverage suggestions. + + Inputs: + REPO = ${{ github.repository }} + PR_NUMBER = ${{ github.event.pull_request.number }} + REPORT_FILE = ${{ github.workspace }}/review-comment.md + + Read the diff (gh pr diff --repo ) and the checked-out source, and + look only for, in priority order: + 1. Bugs — logic errors, crashes, broken edge cases, regressions. + 2. Security issues. + 3. Performance problems (re-render perf matters in this repo — see CLAUDE.md). + 4. Violations of the "Review red flags" list in CLAUDE.md. - Please review this pull request with a focus on: - - Code quality and best practices - - Potential bugs or issues - - Security implications - - Performance considerations + Report only findings you are confident are real. No style nits, no praise, no + speculative "consider…" advice without a concrete failure mode. An empty review is + a valid and common outcome. - Note: The PR branch is already checked out in the current working directory. + For each finding, post one inline comment with + mcp__github_inline_comment__create_inline_comment (confirmed: true), shaped as: + **<🔴 or 🟡> ** + + Severity: 🔴 Blocker — will break something. 🟡 Warning — likely problem or a + red-flag violation. - Use `gh pr comment` for top-level feedback. - Use `mcp__github_inline_comment__create_inline_comment` (with `confirmed: true`) to highlight specific code issues. - Only post GitHub comments - don't submit review text as messages. + Then write the verdict to REPORT_FILE with the Write tool. It is exactly two lines + (keep the HTML marker verbatim as the first line) and nothing else — no table, no + list of findings, no prose: + + + ## Code Review — + + where is exactly one of: + ✅ No blockers + ✅ No blockers · 🟡 M warning(s) — see inline comments + 🔴 N blocker(s) · 🟡 M warning(s) — see inline comments + Never write a zero count — omit that segment instead. + + The inline comments ARE the review; the verdict comment only answers "can this + merge?". Do not post the verdict comment yourself and do not reply in chat. claude_args: | - --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Read,Grep,Glob" + --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Read,Write,Grep,Glob" + --model claude-sonnet-4-6 + --max-turns 20 + + # Always post a NEW verdict comment (never update in place): each push's verdict lands in + # the PR timeline between the commits it reviewed, preserving the review history. + - name: Post review verdict + if: always() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + PR: ${{ github.event.pull_request.number }} + run: | + set -euo pipefail + FILE="$GITHUB_WORKSPACE/review-comment.md" + if [ ! -s "$FILE" ] || ! grep -q '' "$FILE"; then + echo "::warning::review-comment.md missing or malformed; skipping verdict comment." + exit 0 + fi + BODY=$(cat "$FILE") + PAYLOAD=$(BODY="$BODY" python3 -c 'import os,json,sys; sys.stdout.write(json.dumps({"body": os.environ["BODY"]}))') + printf '%s' "$PAYLOAD" | gh api -X POST "repos/$REPO/issues/$PR/comments" --input - --silent + echo "Posted review verdict comment."