Skip to content

Claude PR review

How the automated Claude review of pull requests works in this repo, how to trigger it, and what it treats as blocking.

The workflow is .github/workflows/claude-code-review.yml. It follows the same design as the Claude review workflows in syrf and cluster-gitops. Only the review prompt is specific to this repo.

Prerequisites

Reviews cannot run until an org or repo admin has done both of these:

  1. Add the CLAUDE_CODE_OAUTH_TOKEN secret. This repository does not have one yet. The Claude GitHub App is already installed across the organisation.
gh secret set CLAUDE_CODE_OAUTH_TOKEN -R camaradesuk/camarades-infrastructure
  1. Give this repository access to the juniper-ci runner group. The job runs on the organisation's shared self-hosted pool, like the review jobs in the other CAMARADES repos. That runner group only admits selected repositories, and this one is not on the list yet. Until it is added, review jobs stay queued. To add it, go to Organisation settings → Actions → Runner groups → juniper-ci → Repository access, or run:
gh api -X PUT orgs/camaradesuk/actions/runner-groups/3/repositories/1094727642

1094727642 is this repository's ID (gh api repos/camaradesuk/camarades-infrastructure --jq .id).

A workflow triggered by pull_request runs the copy of the workflow on the PR branch. However, the PR that introduced this workflow was opened and pushed before the secret and runner access existed. It therefore cannot review itself. The first real review will be on the next PR after merge, once both prerequisites are in place.

Triggering a review

Trigger When it runs
Automatic A same-repo, non-draft, human-authored PR is opened, pushed to, reopened, or marked ready for review.
claude-review label Adding the label to any same-repo PR, including drafts and bot-authored PRs. To run it again, remove the label and add it back.
/claude-review [model] comment A PR comment containing /claude-review from an owner, member or collaborator. The workflow adds an "eyes" reaction to show it saw the request. To choose the model, put /claude-review alone on a line, optionally followed by one of sonnet (default), opus, fable or haiku, for example /claude-review opus. An unknown word fails the run with an error.

Automatic and label-triggered reviews always use sonnet. Each alias resolves to the latest model of its family. haiku runs without --effort high because Haiku 4.5 does not support effort levels. A comment that only mentions the command inside other text uses sonnet.

PRs from forks are never reviewed, because they do not receive secrets. A new request on the same PR cancels any review still in progress for it. Ordinary comments, including the review's own summary, never cancel a review.

A PR that changes no files, such as the empty commit a new branch starts with, is skipped.

What the reviewer does

  • It reviews the PR's merge ref (refs/pull/<N>/merge) read-only. It does not run Terraform and has no cloud credentials.
  • Terraform plan. For changes to terraform/lambda/**, it reads the ### Terraform plan comment that the terraform workflow posts (see Terraform CI/CD). It then checks every planned create, update, replace and destroy against what the PR says it does. That comment is edited in place on every push and carries no commit SHA. The reviewer therefore treats it as current only once the plan (lambda) check has completed for the PR's head commit. If the plan is missing or still running, the reviewer lists that under Questions rather than guessing. The root GCP module (terraform/*.tf) is not planned in CI, so for changes there the reviewer looks for the author's local plan in the PR description.
  • Re-reviews. When an earlier Claude summary names a Reviewed commit:, the reviewer only looks at what changed since that commit. It ignores anything merged in from main. Earlier blocking findings that are still open are repeated under Blocking.

What blocks

Each finding is labelled [blocking] or [non-blocking]. The verdict is request changes only when at least one blocking finding is open. Blocking means one of these:

  • A planned destroy or replace the PR does not explicitly acknowledge. This matters most for stateful or in-use resources: S3 buckets and their notification config, IAM roles and users in use, Lambda functions, the GKE cluster and node pool, and state backends.
  • IAM privilege widened beyond what the PR says it needs. Examples are wildcard actions or resources, a broadened iam:PassRole, removed conditions, a widened SyRFS3NotifierLambdaBoundary, or new or broadened trust (cross-account, OIDC, Workload Identity). Recent PRs here grant exact ARNs, action lists and trust subjects, and the reviewer holds new changes to that standard.
  • Secrets or credentials in code, variable defaults, outputs or docs.
  • A change that fights another owner of a resource. Examples are reverting attributes ACK now owns, removing or narrowing an ignore_changes handover block (ADR-010), deleting a removed { lifecycle { destroy = false } } block before its apply has run, or re-declaring a resource released to ACK, or S3ReadAccess drifting from the SyRF s3-notifier chart (see the README's Contributing section).
  • A backend or state configuration change.
  • A change without the tests the repo already has for that area. This covers the mocked terraform test contracts in terraform/lambda/tests/, including the s3_notifier_ingress_read_policies parity pin. Weakening an assertion also counts.
  • Stale docs for behaviour the PR changes.

Everything else is non-blocking. That includes pattern-reuse and guard suggestions, naming, comments and style.

Output

  • Only blocking findings are posted as inline review threads, because unresolved threads are treated as merge blockers. Non-blocking findings and questions go in the summary comment only.
  • There is one summary comment per review, with ### Blocking, ### Non-blocking and optional ### Questions sections, followed by a Reviewed commit: <sha> line and a Verdict: line.
  • The reviewer never writes to the repository. Its tool allowlist permits only comments, gh pr diff, gh pr view, this PR's review comments and, on a re-review, a single compare range.
  • The job summary of each run records the model, turns, duration and token usage.