Skip to content

Instantly share code, notes, and snippets.

@futzlarson
Last active March 13, 2026 20:01
Show Gist options
  • Select an option

  • Save futzlarson/4bc58ffa5064dfb3c0c39e5f671a19c7 to your computer and use it in GitHub Desktop.

Select an option

Save futzlarson/4bc58ffa5064dfb3c0c39e5f671a19c7 to your computer and use it in GitHub Desktop.
Claude PR Review: GitHub App vs GitHub Actions vs Local Skill (Laravel Boost)

Claude PR Review: GitHub App vs GitHub Actions vs Local (Laravel Boost)


Option 1 β€” GitHub App (github.com/apps/claude)

Installed once at the org level via claude.ai/admin-settings/claude-code. Reviews are posted as inline PR comments.

Triggers

  • Auto on PR open/push (configurable)
  • Manual: comment @claude review on any open PR

What it does

  • Runs a fleet of specialized agents over your full codebase (not just the diff)
  • Tags findings by severity: Normal πŸ”΄, Nit 🟑, Pre-existing 🟣
  • Supports follow-up comments (@claude explain this)
  • Customizable via CLAUDE.md (shared rules) and REVIEW.md (review-only rules)
  • Prompts are proprietary β€” Anthropic has not published them

Cost: ~$15–25/review, billed through claude.ai per token. Research preview for Teams/Enterprise plans only. Set a monthly spend cap at claude.ai/admin-settings/usage.


Option 2 β€” GitHub Actions (anthropics/claude-code-action@v1) βœ… Deployed

Two workflows are live: an automated review on every PR, and an interactive responder for @claude mentions.

claude-review.yml β€” Automated review

Triggers on PRs to dev, qa, uat. Posts a comment with findings via track_progress: true, parses a structured outcome, logs to Jarvis, and escalates to Slack if not approved.

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches: [dev, qa, uat]

Prompt (references CLAUDE.md + project-specific checks):

  • Potential bugs or logic errors
  • Security vulnerabilities
  • Performance concerns
  • Breaking changes
  • Silent failures β€” early returns, empty guards, catch blocks that swallow errors without throwing or logging
  • Query scoping β€” logic that could return zero/all rows, or incorrect withoutGlobalScopes use that bypasses tenant isolation

Outcome parsing
Claude outputs REVIEW_OUTCOME: approved or REVIEW_OUTCOME: not_approved at the end of every review. The workflow parses this from PR comments/reviews posted after the job started.

Slack escalation
When not_approved, a second job posts a Slack alert with PR title, author, branch, and a link β€” flagging it for human review.

Jarvis logging
Every review (approved or not) is logged to an internal endpoint with repo, PR number, author, commit SHA, and outcome.

Tuning notes (learned in production):

  • track_progress: true is required β€” without it the action runs but posts nothing, causing the outcome parser to always default to not_approved
  • --max-turns 20 is the sweet spot: 10 caused error_max_turns (the action's built-in setup uses several turns before the actual review), 58 turns ran uncapped on the first attempt ($0.86, mostly permission-denied retries)

Re-triggering

  • Push a new commit
  • GitHub UI β†’ Checks tab β†’ Re-run job
  • gh run rerun <run-id>

Cost: ~$0.50–$3/review with claude-sonnet-4-6. Billed to your ANTHROPIC_API_KEY.

claude-interactive.yml β€” @claude mentions

Responds to @claude comments on any PR or issue. No prompt set β€” auto-detects from the comment content.

@claude why did this change break the auth flow?
@claude suggest a fix for the N+1 query on line 42
@claude review this for security issues

Cost: Same API key billing, per-mention usage.

Option 2+ β€” Actions + Laravel Boost (not yet implemented)

@v1 supports --mcp-config via claude_args, meaning you can wire up Laravel Boost in CI and give Claude access to your live database schema, Tinker, and Artisan during the review β€” catching things static analysis can't:

  • "This query will do a full table scan"
  • "This migration drops a column still referenced in a model"
  • "This relationship will cause an N+1"

The repo already has .mcp.json (Boost configured as php artisan boost:mcp) and docker-compose.yaml (Postgres + Redis). What's needed:

  1. Boot the full Laravel stack in CI using services: (Postgres, Redis) + PHP setup + migrations
  2. Pass --mcp-config .mcp.json to the action via claude_args
  3. A .env.ci with credentials pointing at the CI database container

Trade-offs: Adds ~2–3 min of CI setup time. High-value for PRs touching models, migrations, or queries. Overkill for frontend/config changes.


Option 3 β€” Local Pre-PR Review Skill (Recommended Complement)

A Claude Code skill invoked locally before pushing. Unlike Options 1 and 2, this runs inside your Claude Code session β€” all Laravel Boost MCP tools are available. Claude can validate queries against your live database schema, run Tinker, and check that migrations align with real table structure.

Usage: /review-pr main or /review-pr dev before gh pr create.

.claude/skills/review-pr/SKILL.md

---
name: review-pr
description: "Reviews staged/uncommitted changes or a branch diff before creating a PR. Checks for bugs, security issues, performance concerns, and adherence to project conventions in CLAUDE.md."
argument-hint: "[base-branch]"
---

# Pre-PR Code Review

Review the current branch diff against $ARGUMENTS (default: `main`) for issues
that should be resolved before opening a PR.

## Steps

1. Run `git diff $ARGUMENTS...HEAD` to get the full diff.
2. Run `git log $ARGUMENTS...HEAD --oneline` to understand the commit scope.
3. For any modified Laravel files, use the `database-schema` or `tinker` Boost
   tools to validate model/query correctness.
4. Review against the conventions in CLAUDE.md.

## What to Check

- Potential bugs or logic errors
- Security vulnerabilities
- Performance concerns
- Breaking changes
- Silent failures β€” early returns, empty guards, or catch blocks that swallow errors without throwing or logging
- Query scoping issues β€” logic that could unintentionally return zero rows or all rows, or incorrect use of `withoutGlobalScopes`/`withGlobalScope` that bypasses tenant isolation or authorization filters

## Report Format

### Critical Issues πŸ”΄
Bugs, security vulnerabilities, or breaking changes. Must be resolved before merging.

### Warnings 🟑
Logic concerns, missing edge cases, or performance issues. Should be reviewed.

### Convention Violations 🟣
Deviations from CLAUDE.md or project patterns. Address if time allows.

### Approved βœ…
Note if no critical issues are found and the PR is ready to open.

Be specific: include file paths and line references.

At the very end, output exactly one of:
REVIEW_OUTCOME: approved
REVIEW_OUTCOME: not_approved

Cost: Cheaper than Option 2 per run β€” scope is limited to your branch diff. Boost tool calls add minimal overhead.

Actioning review feedback with /pr-comments

After a review posts (from CI or a peer), use the built-in /pr-comments command to pull all PR comments into your Claude Code session:

/pr-comments

Claude reads the comments and can explain findings, suggest fixes, or make changes directly. A natural end-to-end workflow:

  1. /review-pr dev β€” catch issues before pushing
  2. Push β†’ CI review posts comment, Slack alert fires if not approved
  3. /pr-comments β€” action the feedback locally with Boost available

Summary

GitHub App Actions @v1 βœ… Actions @v1 + Boost Local Skill
Status Not installed Live Not yet implemented Not yet created
Trigger Auto or @claude review Auto on push/PR + @claude Auto on push/PR Manual (/review-pr)
Codebase context Full repo (agents) Diff only Diff + live DB Full repo + live DB
Interactivity Yes Yes (claude-interactive.yml) Yes Yes (full session)
CLAUDE.md Native βœ… Referenced in prompt βœ… Referenced in prompt Native
Slack escalation No βœ… On not_approved βœ… On not_approved No
Jarvis logging No βœ… Every review βœ… Every review No
Laravel Boost No No Yes Yes
Cost ~$15–25 (claude.ai) ~$0.50–$3 (API key) ~$1–5 (API key) ~$0.50–$2 (API key)
Best for Post-push safety net Current CI gate Model/migration PRs Pre-push, early catch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment