To review a pull request with the Safeguard CLI, check it out locally, run safeguard review with --base set to the target branch, and scan any dependency changes. Then open the assistant in Plan mode to question the change, run the tests with your approval, fix what needs fixing, and gate the merge in CI.
You do not have to give up the assistant you already pay for to do this. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. If your team lives in a chat app, connect Claude or ChatGPT to the Safeguard MCP server and ask about a pull request's findings from there.
What you will have at the end of this guide:
- A repeatable routine for reviewing any pull request on your own machine, in its own worktree, without disturbing your current branch.
- A correctness and security review of the change from
safeguard review, checked against the exact set of files the pull request touched. - A dependency check that shows whether the change brought in new vulnerable or oddly licensed packages.
- Any fix you choose to make, done by the assistant with each edit and command approved by you, tests run and nothing pushed.
- A CI job that runs the same checks on every pull request and fails when a high severity finding arrives.
The examples use a sample service, payments-api, and a pull request numbered 482 that targets main. Swap in your own numbers and names.
What a pull request review should cover
A useful review answers five questions. Write them down, because it is easy to stop after the first.
- Is the change correct? Does it do what the description says, and does it handle the inputs it will really see?
- Is it safe? Does it open a new way in: unvalidated input, a weaker check, a query built from strings, a permission widened?
- What did it pull in? Any new or upgraded dependency brings its own code, its own vulnerabilities and its own licence.
- Does it still pass? Tests, build and lint, run by you, not just a green tick you did not look at.
- Is it the change you were told about? Lockfile churn, generated files and edits outside the stated scope deserve a question.
The table maps each question to a command. All of them run on your machine.
| Question | Command | When to run it |
|---|---|---|
| What changed, and where? | git diff --stat origin/main...HEAD or gh pr diff 482 --name-only | First, always |
| Is it correct and safe? | safeguard review --base origin/main | After checkout |
| What did it pull in? | safeguard findings sca --dir . and safeguard scan --dir . | When a manifest or lockfile changed |
| Does it still pass? | Your test command, run by the assistant with approval | Before you approve |
| Can I fix it myself? | The interactive assistant, in Ask or Auto mode | Only if you own the branch or were asked |
Two notes on git before you start. The git docs explain that git diff A...B (three dots) is the same as diffing from git merge-base A B to B, so it shows only what changed on the pull request's side since it branched. git diff A..B (two dots) compares the two tips directly, which also shows everything that landed on main since. For review you almost always want three dots. And --name-only prints just the paths, while --stat adds a count of changed lines per file, which is the fastest way to spot a 4,000 line lockfile change hiding behind a 20 line code change.
Do the work properly with the Safeguard CLI
The Safeguard CLI scans code, container images and SBOMs on your own machine, sends only the results to the platform, and includes an assistant that can fix what it finds. For review, three parts matter: safeguard review, which reviews changes for correctness and security; the scanners, which tell you what a dependency change brought in; and the assistant, which reads, explains and, with your approval, writes code and runs commands.
Install
On macOS and Linux:
curl -fsSL https://cli.safeguard.sh/install | bash
safeguard --version
On Windows, in PowerShell:
irm https://cli.safeguard.sh/install.ps1 | iex
It is a single static binary with no Node, Python or JVM needed. It runs on macOS, Linux and Windows, on x86_64 or arm64 (Windows is x86_64 only).
First session
Run safeguard with no arguments to open the interactive terminal. /login signs you in through the browser, and /scan . scans the current folder. From then on you can ask in plain language, such as "how many critical vulns do we have" or "what does this pull request change in the payment flow?". The assistant has tools for your local files and for your Safeguard data, and it picks whichever the question needs.
Start the CLI inside the checkout you are reviewing. The @ file picker attaches files from the folder you started in, so @src/routes/refunds.ts puts that exact file in front of the assistant. /resume picks up the last session in that folder, which is handy when a review spans two days.
Writing and fixing code
The assistant writes code, not only reports. If you own the branch, or the author asked you to push a fix, it can edit the files, run the tests and give you a commit message. Here is a real session recorded on 21 October 2026 on the sample payments-api project. It installs the CLI with the curl command (checksum verified), checks safeguard --version, opens the interactive terminal and asks "fix the lodash CVE in this repo". The assistant reads the finding, the files and the advisory, and asks before each command, which you answer with y or n. It edits package.json to lodash 4.17.21, runs npm install and npm test with approval, then prints a summary with a suggested commit message. It pushes nothing. The session ends with /permissions, /model and /scan ..
Click through it at your own pace, or open it full screen.
Using your Claude or ChatGPT plan
Use /model to see or switch the model for a session. To use the plan you already have, see the CLI docs for connecting a model. If you are moving over from another agent, safeguard import converts a Claude Code or Codex setup into Safeguard configuration, and safeguard other-agents reads Claude Code, Codex and OpenCode configuration too (it is on by default).
Approvals for reviewers
/permissions sets what runs without a prompt:
- Ask. Reads run; edits and commands ask first.
- Accept edits. Edits in this folder and read-only commands run; other commands ask.
- Plan. Read and plan only.
- Auto. Read-only commands and what the policy allows run; anything else asks. The default.
- Strict. Pre-approved actions only, for CI.
For review, start in Plan. You want the assistant reading and explaining, not changing anything while you form a view. Switch to Ask or Auto only when you decide to run tests or make a fix. There is also a --yolo flag that approves everything; it is for throwaway sandboxes only, never for a branch someone else wrote.
CI with safeguard exec
safeguard exec runs one assistant turn without prompting and prints the result, which suits CI. Its default permission mode is strict: nothing is asked, and anything not pre-approved by the policy file is denied. It refuses to run outside a git repository. The CI section below puts it to work on every pull request.
Step by step: review pull request 482
1. Check it out in its own worktree
Reviewing in a separate folder means you never have to stash your own work. With the GitHub CLI:
cd ~/code/payments-api
git fetch origin
gh pr checkout 482 --worktree ../review-482
cd ../review-482
The GitHub CLI docs describe --worktree as checking out "the pull request into a worktree at the given path". With plain git, check out the pull request's branch into a new worktree:
git fetch origin
git worktree add ../review-482 origin/feature/refund-limits
cd ../review-482
The git docs say a worktree shares everything with the main repository except per-worktree files such as HEAD and the index, so it is cheap to create and remove.
2. Read the shape of the change
git diff --stat origin/main...HEAD
git diff --name-only origin/main...HEAD
Or, without a local checkout, gh pr diff 482 --name-only. Sort what you see into three piles: code, dependency files (package.json, package-lock.json, go.mod, pom.xml, requirements.txt and friends) and everything else (CI config, Dockerfiles, generated files). Any change to CI config or a Dockerfile goes on your list of things to read line by line.
3. Run safeguard review against the target branch
safeguard review --base origin/main
safeguard review reviews changes for correctness and security. Without --base it looks at the working tree, which is what you want for your own uncommitted work. A checked-out pull request has no uncommitted changes, so for review you pass --base to diff against the target branch.
If main has moved on since the pull request branched, a two-tip comparison can drag in other people's changes. Compare the files the review talks about with the list from step 2. If they do not match, review against the merge base instead, which mirrors what three-dot diff shows:
safeguard review --base "$(git merge-base origin/main HEAD)"
Read the output as a list of questions for the author, not a verdict. Each point should name a file and a reason. Keep the ones you agree with for your review comment.
4. Check what the change pulled in
If step 2 showed any dependency file, scan. For a quick look that sends nothing anywhere:
safeguard findings sca --dir .
safeguard findings runs a scanner on this machine and prints a normalized list with severity, package and version, fixed version and remediation. No project is registered and nothing is uploaded, even when the CLI is signed in.
To know which findings are new, run the same command in a clean checkout of main and compare. The quickest way is a second worktree:
git worktree add ../main-baseline origin/main
safeguard findings sca --dir ../main-baseline --json > ../baseline.jsonl
safeguard findings sca --dir . --json > ../pr-482.jsonl
Then ask the assistant to compare the two files and list findings present only in the pull request. With --json, the command prints progress lines and then the result, so tell the assistant to use the final result line from each file.
When you want a record in the platform, with licence results too, run a full scan into its own folder:
safeguard scan --dir . --output output/pr-482
Results land as JSON files such as vuln.json and license.json under that folder. A new copyleft licence in a service you ship is a review comment, even if there is no vulnerability.
5. Question the change with the assistant in Plan mode
safeguard
Run /permissions and pick Plan. Then ask, attaching files with @ where it helps:
- "Summarise what this branch changes compared with origin/main, file by file."
- "In @src/routes/refunds.ts, where is the refund amount validated, and can a negative value reach the database?"
- "Which tests cover the new refund limit, and which paths have no test?"
- "The lockfile changed by 4,000 lines. Which direct dependency changes caused that?"
Plan mode is read and plan only, so nothing changes while you build a picture. If an answer surprises you, open the file yourself. The assistant is there to speed up reading, not to replace it.
6. Run the tests with your approval
Switch /permissions to Ask or Auto and ask the assistant to install dependencies and run the test suite. It asks before each command. Read the command before you press y. For a Node project with a committed lockfile, a clean install in a review checkout looks like this:
npm ci
npm test
The npm docs say npm ci requires an existing lockfile, exits with an error if the lockfile and package.json disagree, and never writes to either. That makes it a check in its own right: if npm ci fails, the pull request's lockfile is out of step with its manifest.
7. Fix it, if it is yours to fix
If you own the branch, or the author asked for help, ask the assistant for the fix: "add validation so refund amounts must be positive and no larger than the original charge, and add a test for both cases." It shows each edit and asks before each command. When it is done, it prints a summary and a suggested commit message. It does not push.
You can approve from somewhere else, too. A CLI session is live: it shows in the web app, the desktop app and the phone app, and other devices can send work to it. In this recorded Android session, the same conversations appear on the phone, "Work on my computer" picks a computer running the CLI and a folder, and the command waits for Allow once, Allow for turn or Deny on the phone. The answer shows the tests passed.
Click through it at your own pace, or open it full screen.
If a fix goes the wrong way, /rewind returns the files to an earlier checkpoint. From the shell, safeguard checkpoints list with --session and the session id shows every checkpoint, and safeguard checkpoints restore with --dry-run prints what would change as a diff before you commit to it. Files the assistant writes or edits are snapshotted before each change; anything a shell command writes, such as a lockfile from an install, is not.
8. Write the review and clean up
Ask the assistant: "Draft a review comment from what we found: the points from safeguard review I kept, the new dependency findings, and the missing tests. Short, specific, one bullet per issue, file and line where possible." Edit it into your own words. Then post it yourself, in the browser or with the GitHub CLI:
gh pr review 482 --request-changes --body-file review-482.md
gh pr review takes --approve, --comment or --request-changes, with --body or --body-file for the text. Finally, remove the worktrees:
cd ~/code/payments-api
git worktree remove ../review-482
git worktree remove ../main-baseline
The git docs note that remove only removes clean worktrees unless you pass --force, which protects any notes you forgot to save.
Reviewing pull requests that an AI agent wrote
More pull requests now come from coding agents. The routine above works unchanged, with three extra habits.
Read the stated scope first. Agents sometimes tidy things nobody asked about. Step 2's file list is where you catch it.
Treat every new dependency as a question. Ask the assistant why each one was added and whether the standard library or an existing dependency already covers it. Then check it with safeguard findings sca.
Check CI and build files with extra care. A changed workflow file, Dockerfile or install script runs with more access than application code.
Our longer post on reviewing AI-generated code before merge goes deeper, and checking coding agent changes with the Safeguard CLI covers the same checks before a pull request even exists.
Run the first pass in CI
Local review is where judgement happens. CI makes sure the basic checks run on every pull request, even the ones nobody looked at closely. A GitHub Actions job:
name: pr security review
on:
pull_request:
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Safeguard CLI
run: curl -fsSL https://cli.safeguard.sh/install | bash
- name: Dependency scan
env:
SAFEGUARD_API_KEY: ${{ secrets.SAFEGUARD_API_KEY }}
run: safeguard ci scan --local --wait --fail-on high
- name: Write the pull request diff
run: git diff origin/${{ github.base_ref }}...HEAD > pr.diff
- name: Assistant summary
run: |
safeguard exec --restricted \
"Read pr.diff. List correctness and security concerns, one per line, with file and reason."
What each part does:
fetch-depth: 0. The actions/checkout README says only a single commit is fetched by default. A three-dot diff needs the target branch's history, so fetch it all.safeguard ci scan --local --wait --fail-on high. With--localthe scan runs on the CI runner and only results are uploaded, never the source. It covers dependencies (SBOM and vulnerabilities); SAST runs only in platform mode.--fail-on highfails the step when the scan has a vulnerability at or above high. It authenticates with a secret key from Settings, Secret Keys, with thescans:triggerscope andscans:readfor--wait, stored asSAFEGUARD_API_KEY.github.base_ref. GitHub's contexts reference describes it as the target branch of the pull request, available only forpull_requestandpull_request_targetevents.safeguard exec --restricted. Runs one assistant turn with a read-only tool set: no writes, no shell, no network. Reading a diff needs nothing more. The default mode for exec is already strict;--restrictednarrows it further. Add--output-format jsonif another step will parse the answer.
If your team uses policies, swap --fail-on high for --fail-on-gate Release (a gate name, an id or all). The step then waits for the gate's policies to be evaluated against the scan and fails when the gate fails. Policies and gates are evaluated in the platform, not by the CLI. For authentication and the other exec flags, see running safeguard exec in CI.
Common mistakes and troubleshooting
Common mistakes
Diffing with two dots. origin/main..HEAD compares tips, so changes merged to main after the branch was cut show up as if the pull request made them. Use three dots, or review against the merge base.
Running safeguard review with no --base on a checked-out branch. It reviews the working tree, and a fresh checkout has nothing uncommitted.
Reviewing in your own working branch. Checking out someone else's branch on top of your half-done work leads to stashes you forget. Use a worktree.
Skipping the dependency scan because the code diff is small. The lockfile is often the biggest part of the change.
Running npm install instead of npm ci in a review checkout. npm install can rewrite the lockfile, which hides the very mismatch you were checking for.
Leaving the assistant in Auto while you read. Use Plan until you decide to act.
Pushing a fix to someone else's branch without asking. The assistant never pushes; keep it that way for branches you do not own.
Troubleshooting
safeguard review mentions files the pull request did not touch. Your base has moved on. Run git fetch origin, then review against git merge-base origin/main HEAD.
The CI diff step fails with an unknown revision. The checkout is shallow. Set fetch-depth: 0 on actions/checkout.
safeguard exec refuses to run. It refuses outside a git repository. Make sure the step runs inside the checkout, or pass -C with the checkout path.
npm ci fails in the review checkout. The lockfile and package.json disagree. That is a finding for the author, not something to fix by running npm install.
git worktree add refuses the branch. The git docs say it refuses when the branch is already checked out in another worktree. Remove that worktree, or add the new one with a detached checkout.
Anything about the CLI install looks off. safeguard doctor checks the environment, sign in, profile, policy and tools, prints what is wrong in order and changes nothing.
FAQ
Can I use my Claude or ChatGPT subscription for pull request review?
Yes. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. You can also connect ChatGPT to the Safeguard MCP server and ask about findings from the chat; see connecting ChatGPT to the Safeguard MCP server.
What is the difference between safeguard review and asking the assistant?
safeguard review is a single command that reviews the changes for correctness and security, which makes it a consistent first pass. The interactive assistant is for follow up: questions about specific files, test runs and fixes, each approved by you.
Does reviewing a pull request upload our source code?
safeguard findings uploads nothing at all. When the local runner runs platform scan jobs, your source code never leaves the machine; only SBOMs and findings are uploaded. In CI, safeguard ci scan --local uploads only the results.
Will the assistant push or comment on the pull request for me?
No. In the recorded session it prints a summary and a suggested commit message and pushes nothing. You post the review yourself, in the browser or with gh pr review.
Which permission mode should I use while reviewing?
Plan while you read, because it is read and plan only. Ask or Auto when you want tests run or a fix made. Never --yolo on someone else's branch.
Can I approve the assistant's commands from my phone?
Yes. The phone app shows the same conversations, "Work on my computer" sends work to a computer running the CLI, and each command waits for Allow once, Allow for turn or Deny.
Does this work outside GitHub?
The local steps use plain git, so they work with any host. safeguard ci scan supports Jenkins, GitHub Actions, GitLab CI, Bitbucket Pipelines, Azure Pipelines, CircleCI, or anything that can run a command. Only the gh commands are GitHub specific.
Can CI block a merge on our security policy?
Yes, through the platform. safeguard ci scan --wait --fail-on-gate with a gate name fails the step when the gate fails after its policies are evaluated. Then make that CI job a required check before merging.
Try it yourself
This walkthrough sets up the runner on your own machine: pick the platform, start it, approve it with its device code, then use the same CLI to scan from the terminal.
Click through it at your own pace, or open it full screen.
Get the CLI, the desktop app and the phone apps from safeguard.sh/download, and keep the CLI docs open for your first review. Start in the terminal, carry on at the desktop and approve from your phone, all against the same session.
Quick check
Why use three dots, origin/main...HEAD, when diffing a pull request?
Three dots diff from the merge base to HEAD, so you see only what the pull request changed. Two dots compare the two tips and also show everything merged to main since the branch was cut.
Why does safeguard review need a base on a freshly checked-out pull request?
Without a base it reviews the working tree, and a fresh checkout has no uncommitted changes. Setting the base to the target branch reviews what the pull request actually changed.
Which permission mode suits reading a pull request before you decide anything?
Plan. It is read and plan only, so nothing changes until you switch to Ask or Auto.
Sources
- Safeguard CLI docs
- Safeguard CLI interactive terminal docs
- Safeguard downloads
- git diff documentation
- git worktree documentation
- GitHub CLI: gh pr checkout
- GitHub CLI: gh pr diff
- GitHub CLI: gh pr review
- actions/checkout
- GitHub Actions contexts reference
- npm ci
Last reviewed: 21 October 2026.