# Pull request comments

Get one comment on every GitHub pull request listing each dependency with a known security advisory. A Deep feature, off until you turn it on.

Pull request comments tell your team, in the pull request itself, which dependency versions in the lockfile have a known security advisory, starting with the ones the change adds. This is a Deep feature, and it is off until you turn it on.

## What it does

When a pull request is opened, gets new commits or is reopened, Lockpick reads your lockfile at two points: the pull request's head, and the point where its branch left the base branch (the merge base). It checks the exact versions in both against known security advisories.

The check is deterministic. No code is run, and no AI reviews it.

Lockpick compares the two lists, so it can tell what the pull request adds or changes apart from what was already there. Problems that landed on your base branch after the branch was cut are not counted against it.

It reads every lockfile the repository has, or the ones you chose. Each lockfile is checked on its own, so a monorepo's Go modules and its JavaScript projects are all covered. A lockfile the pull request does not change is not downloaded again when Lockpick already read that exact file.

## Supported lockfiles

Only the exact versions a lockfile pins are read. Nothing is resolved, installed or run.

| Stack                     | Lockfile                                                                                                  | Advisories from |
| ------------------------- | --------------------------------------------------------------------------------------------------------- | --------------- |
| JavaScript and TypeScript | `pnpm-lock.yaml`, `package-lock.json`, `npm-shrinkwrap.json`, `yarn.lock` (classic and Berry), `bun.lock` | npm             |
| Python                    | `poetry.lock`, `uv.lock`, `Pipfile.lock`, `pdm.lock`, `requirements.txt` (only `==` pins)                 | PyPI            |
| PHP                       | `composer.lock`, including dev packages                                                                   | Packagist       |
| Ruby                      | `Gemfile.lock`, `gems.locked`                                                                             | RubyGems        |
| Go                        | `go.mod`, plus the Go toolchain it builds with                                                            | Go              |
| Java and Kotlin           | `gradle.lockfile`, `buildscript-gradle.lockfile`, `pom.xml`                                               | Maven           |
| Rust                      | `Cargo.lock`                                                                                              | crates.io       |
| .NET                      | `packages.lock.json`                                                                                      | NuGet           |
| Dart and Flutter          | `pubspec.lock`                                                                                            | Pub             |
| Elixir                    | `mix.lock`                                                                                                | Hex             |
| Swift                     | `Package.resolved`                                                                                        | Swift packages  |

Two files are recognised only to tell you how to make them checkable:

* **`bun.lockb`** is Bun's binary lockfile. Run `bun install --save-text-lockfile`, commit the `bun.lock` it writes and choose that.
* **A Gradle build without a lockfile** (`build.gradle` or `build.gradle.kts`) can't be checked. Turn on dependency locking (`dependencyLocking { lockAllConfigurations() }`), run `./gradlew dependencies --write-locks`, commit `gradle.lockfile` and choose it.

For these, and for any lockfile Lockpick could not read, the comment says it could not check, never that the pull request is clean.

## Turn it on

You need:

* a site with its GitHub repository connected, under **Settings**, then **Repository**;
* Deep or Master Key on the workspace;
* the manage right on the site.

Linking a repository turns **Pull request comments** on. There is one switch per site, under **Settings**, then **GitHub**. Turn it off there and it stays off, even if you link the same repository again; linking a different repository turns it on again. Without Deep or Master Key the switch shows "On, but paused" and nothing is posted.

When you link a repository, Lockpick checks every lockfile it finds, up to 20, and finds them again each time it reads the repository, so a project added later is covered. Lockfiles in `testdata` and `fixtures` folders are left out, and the languages GitHub counts in the repository decide which come first: for a mostly Go repository, its `go.mod` files. You can untick lockfiles or type a path such as `apps/web/pnpm-lock.yaml` instead; a list you choose is kept until you pick all lockfiles again.

## What the comment shows

Lockpick keeps one comment per pull request and edits it in place. It does not post a new comment for each push.

Every pull request gets the comment, whether or not it touches the lockfile. It lists every dependency version at the pull request's head that has a known advisory, direct and transitive. A line at the top counts them by severity, for example "81 vulnerable versions: 6 critical · 14 high · 30 medium". Rows are ordered **Known exploited** first, then critical, high, medium, low and **Not rated**, then by package name:

* **Added or changed by this pull request**: each row shows the package, the version (and the version it replaced, when the pull request changed it), the severity, a **Known exploited** badge when attackers are already using the problem, a link to the advisory, and the version that fixes it;
* **Still in the repository after this pull request**: vulnerable versions that were on the base branch and are still at the pull request's head. The 25 most severe across every lockfile are shown, grouped under each lockfile, with a link to the rest in Lockpick;
* for a Go repository, the Go version it builds with (the `toolchain` line in `go.mod`, or else the `go` line) counts too. Its standard library advisories are one row, **Go standard library**, with how many there are and the release that fixes them all. Lockpick only compares versions, so it says that reachability was not checked;
* a line saying how many advisories the pull request fixes, and a short list of the versions it fixed (package, the old version → the new one, or removed), the most severe first. The first 10 are shown, with a link to the rest.

When no version has a known advisory, the comment says so in one line, naming the lockfile and the commit it read.

When a later commit changes the picture, Lockpick edits the comment. A stale warning does not stay behind.

If Lockpick cannot read the lockfile, it says it could not check. This happens when the file is larger than 25 MB, is in another format, or is missing. For a missing lockfile it says where it looked (the base branch and the pull request's head), suggests the lockfile the repository's languages point to, and links to the setting. It never says the pull request is clean when it did not read the file.

Some advisories, such as many in the Go vulnerability database, carry no severity. Lockpick then uses the severity of a matching CVE or GitHub advisory it has; with none, the row says **Not rated** and is listed after the rated ones.

## Permissions

The Lockpick GitHub App reads **Contents** and **Metadata**. For this feature it also needs **Pull requests** with read and write access, so it can read the pull request and post the comment.

Lockpick uses short-lived tokens that are limited to the one repository. It does not merge, and it does not change your code.

### Existing installations

If you installed the Lockpick GitHub App before this feature, you must accept the new permission on GitHub. The owner of the installation gets an email, and GitHub shows a banner on the installation's settings page.

Until it is accepted, **Settings**, then **Repository** shows **Permission pending**, with a link to the installation. You can turn the switch on before then. It starts working when you accept.

## Allowance and limits

Pull request comments spend no scan allowance. They do not create a scan.

To keep things fair, Lockpick runs about 20 checks an hour for each pull request, and 600 an hour for each workspace. A check refused by a limit is dropped. The next push after the hour tries again, and it always reads the newest commit.

## Who it acts as

The Lockpick GitHub App posts the comment, but the switch runs on the access of the manager who turned it on.

* If that person loses access to the site, the feature turns itself off. Another manager can turn it on again.
* If the workspace loses Deep, the feature pauses, and comments stop. It resumes by itself when you upgrade.

## Turn it off

Turn off the switch, disconnect the repository, or choose another repository, and Lockpick stops. Comments already on GitHub stay there. Lockpick never deletes them.

If you uninstall the Lockpick GitHub App on GitHub, Lockpick loses all access to the repository.

## If two sites use the same repository

If two Lockpick sites connect the same repository, only one of them keeps the comment. The pull request still gets one comment, not two.

> **Careful**
>
> A comment lists known advisories for the exact versions in your lockfile. It
> is not a full security review. A pull request with no comment has not been
> proven safe.