Skip to main content

PR Sentinel

CI PyPI version Python versions License: MIT

Free, self-hosted AI code review for pull requests and merge requests. Point it at a free provider like Groq, Gemini, or a local Ollama model and it reads your diff, flags real problems, and leaves comments directly on GitHub or GitLab. No subscription, no seat-based pricing, no vendor lock-in.

If your team has a budget for a paid model, PR Sentinel works with your own OpenAI or Anthropic key too. Nothing here requires it.

Why this exists

Automated PR review tools are useful, but the well known ones are paid products with per-seat pricing. That is a real cost for a solo developer, a student project, or a small open source repository, even when the actual review only needs a handful of API calls per pull request. PR Sentinel is the same idea built as a small, auditable, self-hosted tool: you choose the model, you hold the API key (or use none at all with a local model), and the entire pipeline runs inside your own GitHub Actions job.

What it does

  • Reads the diff for a pull request (or a local git diff) and reviews only the changed lines, using surrounding context to understand intent.
  • Works on both GitHub pull requests and GitLab merge requests.
  • Flags bugs, security issues, performance problems, missing error handling, and missing tests, not personal style nitpicks.
  • Posts a single summary comment on the pull request, plus inline comments on the specific lines with a problem, and updates that same comment on every push instead of piling up duplicates.
  • Requests changes automatically when a critical issue is found, so it can act as a real merge gate if you want one.
  • Also works as a pre-commit hook, reviewing staged changes before they are even pushed.
  • Suggests a pull request title and description from a diff with prsentinel summarize, if you would rather not write one by hand.
  • Reviews diff chunks concurrently, so larger pull requests finish faster.
  • Works from the command line too, so you can review a diff before you even open the pull request.
  • Exports findings as SARIF for the GitHub Security tab, or as plain JSON for your own tooling.
  • Caches results per diff chunk so re-running a workflow does not spend API quota reviewing the same lines twice.

Quickstart: GitHub Actions

Add this workflow at .github/workflows/pr-sentinel.yml:

name: PR Sentinel

on:
  pull_request:

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Lethe044/prsentinel@v1
        with:
          provider: groq
          api-key: ${{ secrets.GROQ_API_KEY }}

Get a free Groq API key at console.groq.com/keys, add it as a repository secret named GROQ_API_KEY, and every new pull request gets reviewed automatically.

Quickstart: GitLab CI

Add this to .gitlab-ci.yml:

prsentinel:
  image: python:3.12
  stage: test
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  script:
    - pip install prsentinel-cli
    - prsentinel review --post-to-gitlab --provider groq
  variables:
    GROQ_API_KEY: $GROQ_API_KEY

Add GROQ_API_KEY and a GITLAB_TOKEN (a project access token with the api scope) as masked CI/CD variables in your project settings, and every merge request gets a summary note plus inline comments on the changed lines.

Quickstart: pre-commit hook

PR Sentinel also works as a pre-commit hook, so you catch problems before they are even pushed. Add this to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/Lethe044/prsentinel
    rev: v1.1.0
    hooks:
      - id: prsentinel

This reviews your staged changes every time you run git commit, using whichever provider and API key you have configured locally.

Quickstart: command line

pip install prsentinel-cli

export GROQ_API_KEY=your-key-here
prsentinel review --base origin/main --head HEAD

This prints a table of findings straight to your terminal, before you even push. Combine it with a pre-push git hook if you want a check before code leaves your machine at all.

Choosing a provider

Provider Cost Setup
groq Free tier API key from console.groq.com/keys, set GROQ_API_KEY
gemini Free tier API key from aistudio.google.com/apikey, set GEMINI_API_KEY
ollama Free, fully local Run ollama serve and pull a model, no key needed
openai Paid, bring your own key Set OPENAI_API_KEY
anthropic Paid, bring your own key Set ANTHROPIC_API_KEY

Run prsentinel providers at any time to see this list along with the default model used for each one.

Configuration

Run prsentinel init to write a starter .prsentinel.yml in your repository root. Every field is optional and falls back to a sensible default if the file does not exist at all.

provider: groq
model:
severity_threshold: suggestion
fail_on: critical
max_files: 60
max_diff_lines_per_chunk: 350
ignore:
  - "*.lock"
  - "dist/**"
  - "node_modules/**"
  - "vendor/**"
custom_rules:
  - "Flag any hardcoded API keys or secrets"
  - "Require a docstring on every public function"
post_summary_comment: true
inline_comments: true
request_changes_on_critical: true
cache_enabled: true
max_workers: 4
show_footer: true

custom_rules is where PR Sentinel becomes specific to your project. Add plain English instructions and they get appended to every review prompt, alongside the general review.

fail_on controls the exit code (and therefore whether your CI check goes red). Set it to warning for a stricter gate, or suggestion for the strictest possible one.

max_workers controls how many diff chunks are reviewed at the same time. Raising it speeds up large pull requests, at the cost of hitting a free tier rate limit sooner.

Run prsentinel validate-config at any time to check a .prsentinel.yml file for typos or invalid values without running a full review, useful as a quick sanity check in CI before the real review step runs.

Command line reference

prsentinel review           Review a diff and report findings
prsentinel summarize        Suggest a PR title and description from a diff
prsentinel init              Write a starter .prsentinel.yml
prsentinel validate-config   Check a .prsentinel.yml file for problems
prsentinel providers         List providers and setup instructions
prsentinel clear-cache       Delete the local review cache
prsentinel stats             Show how much is stored in the local cache

Useful flags on review:

--base, --head        Git refs to diff (defaults to origin/main...HEAD)
--staged              Review staged changes instead of a branch diff
--diff-file           Review a saved unified diff file instead of running git
--provider, --model   Override the provider or model from config
--output              terminal (default), json, sarif, or html
--output-file         Write json/sarif output to a file
--post-to-github      Post results as a review on the current GitHub Actions PR
--post-to-gitlab      Post results as notes on the current GitLab CI merge request
--dry-run             Compute the review but do not post anything, just print it
--fail-on             Override the fail_on threshold for this run
--no-cache            Skip the local response cache for this run

Suggesting a PR title and description

prsentinel summarize --base origin/main --head HEAD

Reads the same kind of diff as review, but instead of finding problems it proposes a conventional-commit style title, a short summary, and a few highlights. Handy when you are about to open a pull request and would rather not write the description from scratch.

Quickstart: Docker

If you would rather not install Python, a ready to use image is published on every release:

docker run --rm -v "$(pwd):/workspace" -e GROQ_API_KEY \
  ghcr.io/lethe044/prsentinel:latest review --base origin/main --head HEAD

Mount your repository at /workspace and pass whichever provider key you are using as an environment variable. This works the same way in any CI system that can run a Docker image, not just GitHub Actions or GitLab CI.

Silencing a specific finding

Sometimes a flagged line is genuinely fine for reasons the model cannot see. Silence it the same way you would silence a linter, with a comment near the line:

eval(trusted_internal_config)  # prsentinel-ignore-line
# prsentinel-ignore-next-line
eval(trusted_internal_config)

Add # prsentinel-ignore-file anywhere in a file to skip it entirely (for example, a generated file that should never be reviewed). This works with any comment syntax, since only the marker text itself is matched. Turn it off globally with enable_suppression_comments: false in .prsentinel.yml if you would rather not have this escape hatch at all.

Confidence and category severity floors

Every finding also carries a confidence level (low, medium, or high), based on how sure the model is. Set min_confidence: high in .prsentinel.yml if you only want the findings it is fairly certain about.

category_severity_floor forces a minimum severity for a category no matter what the model assigned, which is on by default for security findings (security: warning) so a model having an off day never quietly downgrades a real security issue to a suggestion.

How review comments look

PR Sentinel posts one summary comment with a small table of counts by severity, followed by a breakdown per file, and inline comments on the exact lines a finding refers to. If a critical issue is found and request_changes_on_critical is enabled, the review is submitted as "Request changes" instead of a plain comment, so it behaves like a real review a teammate would leave.

Limitations, on purpose

PR Sentinel reviews diffs, not your entire codebase, and it does not replace a human reviewer. Language models make mistakes, including missing real issues and occasionally flagging something that is not actually a problem. Treat its output the way you would treat a review from a thorough but fallible colleague: worth reading, not worth merging blindly on faith either way. custom_rules and the severity_threshold and fail_on settings let you tune how much weight to give it in your workflow.

Contributing

Bug reports, feature requests, and pull requests are welcome. See CONTRIBUTING.md for how to get set up locally, how the provider interface works, and what a good pull request looks like here.

License

MIT. See LICENSE.

Metadata

Release files for prsentinel-cli 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prsentinel-cli 1.2.0
File Size Uploaded Provenance
prsentinel_cli-1.2.0.tar.gz 42.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for prsentinel-cli 1.2.0
File Interpreter ABI Platform
prsentinel_cli-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 84.9 kB

Release files / prsentinel_cli-1.2.0.tar.gz

Download URL prsentinel_cli-1.2.0.tar.gz
Size 42.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ed16341a47b3ed67f2423a5ebfb0dff17c2f081c441938a93fa64fae87901ecd
BLAKE2b-256 checksum
How to use checksums
b038f50f388311c2c0694ce6a7e61846cb998e1fc30c89d6879108871ad21112
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / prsentinel_cli-1.2.0-py3-none-any.whl

Download URL prsentinel_cli-1.2.0-py3-none-any.whl
Size 42.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f7eef83465eb6039280a30226d4081b2b4f517f4bcf59dd1f6370c87d7787062
BLAKE2b-256 checksum
How to use checksums
4f1775ad931e73fd2cac13b277ac3df6225842dd4a5922a21556a4cedcf5d23d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Security for prsentinel-cli 1.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for prsentinel_cli-1.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page