Getting started

Review your last commit in two minutes

All you need is a Git repository with at least two commits. The first run needs no configuration, no Docker and no API key, and it never executes your code.

  1. Install the binary

    SwiftProof is a single executable. Git must be installed; nothing else is required for this guide. Copy the commands for your system, or download the archive and put swiftproof on your PATH yourself.

    VERSION=v0.3.0
    OS=$(uname -s | tr '[:upper:]' '[:lower:]')                 # linux or darwin
    ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')  # amd64 or arm64
    NAME=swiftproof-$VERSION-$OS-$ARCH
    curl -fsSLO https://github.com/gvinsot/SwiftProof/releases/download/$VERSION/$NAME.tar.gz
    tar -xzf $NAME.tar.gz
    sudo install $NAME/swiftproof /usr/local/bin/
    swiftproof version

    No sudo? Install to ~/.local/bin instead, provided it is on your PATH. On macOS, an archive downloaded with a browser is quarantined because it is not notarized; run xattr -d com.apple.quarantine swiftproof once. Downloads through curl are not affected.

    $v = "v0.3.0"
    $arch = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" }
    $name = "swiftproof-$v-windows-$arch"
    Invoke-WebRequest "https://github.com/gvinsot/SwiftProof/releases/download/$v/$name.zip" -OutFile "$name.zip"
    Expand-Archive "$name.zip" -DestinationPath . -Force
    $dir = "$env:LOCALAPPDATA\Programs\swiftproof"
    New-Item -ItemType Directory -Force $dir | Out-Null
    Copy-Item "$name\swiftproof.exe" $dir -Force
    # add it to your user PATH, now and for new terminals
    [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";$dir", "User")
    $env:Path += ";$dir"
    swiftproof version

    The last command prints the installed version, for example swiftproof v0.3.0. To check the archive against the published checksums, see Verify a download.

  2. Compare your last commit with the previous one

    Go to any Git repository and ask SwiftProof what changed between HEAD~1 and HEAD:

    $ cd path/to/your/repository
    $ swiftproof lint HEAD~1..HEAD
    5 files, +120/-5 lines; 21 risk signals; 0 reproduced issues.
    Focused review: 19 / 125 changed lines (a prioritization aid, not a correctness guarantee).
    Changed-line execution: not measured.
    Reports: /home/you/shop/.swiftproof

    lint is the static half of SwiftProof. It compares the two commits, collects risk signals and writes a report. It never executes repository code, never calls an AI provider and needs no .swiftproof.json: without one, the built-in defaults for the detected language apply.

    Only committed files are analyzed. Uncommitted edits and untracked files are ignored, so commit your work first, for example on a scratch branch. To keep reports out of git status without touching .gitignore, run echo .swiftproof/ >> .git/info/exclude.
  3. Read the report

    Open .swiftproof/CONFIDENCE_REPORT.md in your editor. Start with Suggested Human Review, a list of file and line ranges ranked by severity, each with the reason it was flagged:

    ## Suggested Human Review
    
    - **high** auth/auth.go:7–7 (new): Authentication or authorization function body changed
    - **high** payment/refund.go:21–21 (old): Configured sensitive path changed; No nearby test file changed; Possible input validation removed
    - **medium** catalog/format.go:9–9 (new): Exported Go declaration added
    …

    (new) points to a line in the candidate commit and (old) to a removed line in the base. Review Surface tells you how many changed lines those ranges cover. The same data, with commit IDs and signal evidence, is in confidence-report.json for scripts and CI.

    Signals are reasons to look, not confirmed bugs. The signal reference explains each one.

  4. Choose what to compare

    Any two revisions work. A few common choices:

    CommandCompares
    swiftproof lint HEAD~5..HEADYour last five commits taken together.
    swiftproof lint --base mainYour current branch against main, from their merge base, like a pull request. Use --base master if that is your default branch.
    swiftproof lint --base origin/main --head featureAnother branch against the remote default branch, without checking it out.
    swiftproof lint main..featureThe two exact commits, with no merge base (main...feature uses the merge base).
    swiftproof lint --base main --ciSame as above, but exits with code 2 when human review is required, for scripts and CI.
  5. Optional: run your checks in a sandbox

    review does everything lint does, then runs the repository's test, typecheck, build and coverage commands in disposable, network-less Docker containers. It needs Docker with Linux containers and a preloaded image containing your toolchain: SwiftProof never pulls images or installs dependencies itself. For a Go project with no third-party dependencies, the default image is enough:

    $ docker pull golang:1.26-bookworm
    $ swiftproof review HEAD~1..HEAD --reviewer=false
    Running test in isolated Docker sandbox...
    Running typecheck in isolated Docker sandbox...
    Running build in isolated Docker sandbox...
    Running coverage in isolated Docker sandbox...
    5 files, +120/-5 lines; 21 risk signals; 0 reproduced issues.
    Focused review: 19 / 125 changed lines (a prioritization aid, not a correctness guarantee).
    Changed-line execution: 44 executed, 0 not executed, 23 outside any instrumented block, 0 not measured, of 67 added Go lines.
    Reports: /home/you/shop/.swiftproof

    For Node.js and Python projects, stock images do not contain your dependencies: build an image that does, then point sandbox.image at it in a policy (next step). If Docker or the image is missing, SwiftProof stops with exit code 4 and never falls back to running code on your machine.

  6. Adopt it in your repository

    Generate a policy, review its commands and sandbox image, and commit it to your base branch. From then on, every comparison reads the policy from the base branch, never from the change under review.

    swiftproof init                                   # writes .swiftproof.json
    swiftproof review --base main --config .swiftproof.json   # try it before committing
    git add .swiftproof.json && git commit -m "Add SwiftProof review policy"
    
    # then, on every pull request or before handing work over
    swiftproof review --base main --ci

    Next steps: every flag, exit code and policy key is in the reference. To let an AI reviewer try to reproduce issues, configure a provider as described in AI reviewer. For GitHub Actions, see the CI integration guide.

If something goes wrong

MessageWhat to do
base: git rev-parse … Needed a single revisionA revision does not exist. The repository may have a single commit (so there is no HEAD~1), or its default branch is not main: pass --base master or an explicit range.
The report misses your latest editsThey are not committed yet. SwiftProof only analyzes commits; commit them, then run it again.
Exit code 2Not an error: with --ci, it means human review is required. See exit codes.
Exit code 4 during reviewDocker is not running or the sandbox image is not present locally. Pull it first, or use lint.
reviewer.model must be configured…--reviewer was requested without a model. Drop it, or configure a provider.