Claude can run a clean security review on your branch, then push a commit that review never saw.
You ask Claude to run /security-review, the built-in command that checks your branch for security holes, and it finds nothing.
Later you ask for one more change. Claude commits it and pushes, and nothing on the PR shows that the review is now out of date.
Timeline from a test repo
Here's that story in a small test repo for a made-up payments team. The block mixes two logs: git commits with their hashes, and prompts from ~/.claude/history.jsonl, the file where Claude Code records each prompt you type and when.
0e01735 is the extra change. The security review at 12:25 ran before that commit existed, so it never saw it. The test prompt at 14:45 came after it, so the tests are current and the security review is out of date. If Claude wrote in the PR description that the review came back clean, that line stays, because a description doesn't change when you push.
Both logs are staged. A script made the commits, and the two prompts were written into the history by hand, each in its own session, so neither check ran. The repo also has no origin remote, which /security-review needs because it reviews the diff between your branch and origin's default branch. The times show where the prompts would fall in a repo that has one.
GitHub can't see /security-review
Two of GitHub's features react to new code on a PR. Status checks from CI run again on every push, and a required one has to pass on the latest commit. Reviewer approvals get thrown out as stale when the PR's diff changes, if you tick "Dismiss stale pull request approvals when new commits are pushed" in branch protection.
/security-review is neither. It runs inside your Claude Code session and leaves nothing on the commit, so GitHub has nothing to mark out of date. The only record is whatever Claude typed into the description.
Lazy developer edition: move the check into CI
Set this up once per repo. The review then runs on every push, and GitHub won't merge until it has passed on the last commit.
Step 1: run Anthropic's security review Action on every push
Anthropic publishes a GitHub Action for this, claude-code-security-review. By default it skips a PR's later pushes. Its action.yml restores a marker file from the GitHub Actions cache, and when it finds one from an earlier run on the PR, it skips the review and logs this line:
The job still finishes green, so the new commit gets a passing check that reviewed nothing. That's lines 104 and 105 of action.yml. A later push gets reviewed again only if that cache entry is gone. run-every-commit: true makes it review every push.
Add your Anthropic API key as a repo secret. The command asks you to paste the key:
gh secret set CLAUDE_API_KEYSave this as
.github/workflows/security.yml:
That's the workflow from the Action's README, pinned to the commit linked above, with two things added. run-every-commit reviews each push. The last step, which needs the id: review above it, fails the job when Claude finds anything, because at that commit even a high-severity finding leaves the job green. Findings also show up as PR comments.
On a Claude Team or Enterprise plan, Anthropic's Code Review can review every push to a PR inside GitHub if you set it to "After every push". It won't review a PR from a fork on its own, and organizations with Zero Data Retention can't turn it on. Code Review is a research preview, "each review averages $15-25", and its check never blocks a merge, so it doesn't replace this step.
Step 2: require the security check before merging
- Open a PR so the workflow runs once. GitHub's docs say a required check "must have completed successfully in the chosen repository during the past seven days."
- Go to Settings → Branches → your branch protection rule. Tick "Require status checks to pass before merging" and search for
security, the job name above. - Tick "Do not allow bypassing the above settings", or admins can still merge around it.
GitHub's docs say "Required checks must pass on the latest commit SHA. Checks from earlier commits don't satisfy the requirement." (source). So the PR can't merge until the review has passed on Claude's last commit. Tests and lint go in CI the same way, each as a required job.
If your repo uses rulesets instead, it's under Settings → Rules → Rulesets: require the same check and leave the bypass list empty.
Step 3: flag local checks that ran before the last commit
For anything you still ask Claude to check inside Claude Code, add this line to your CLAUDE.md. When a check comes back "ran before the last commit", run it again:
When you open a PR or push to one, list in its description each check you ran on this branch and the commit it ran on (git rev-parse --short HEAD). If you committed after a check, write "ran before the last commit" next to it. Update the description with gh pr edit.Limits of this setup
- Each run bills your Anthropic API key, and the Action's README warns that reviewing every commit "may increase false positives on PRs with many commits."
- If Claude's review errors, the Action counts zero findings and the job passes. The job log shows a warning starting with "ClaudeCode" when that happens.
- The README says the Action "is not hardened against prompt injection attacks and should only be used to review trusted PRs."
- The
CLAUDE.mdline only works if Claude remembers it. If you push from your own terminal, nobody updates the description.
Shabash marks stale checks on the PR
Claude forgetting that line is why Shabash, the Mac app I'm building, notes on each PR that Claude Code opens or pushes to which of your team's checks ran after the last change. On this branch it would mark the security review out of date, because 0e01735 came after it.



