GitHub Action · source available · runs in your CI

Dependabot tells you a dependency changed. Patchery works out what that means for your code.

Dependabot and Renovate do one job well: notice the new version, open the bump. By design they never read your code — so when that bump turns the suite red, the pull request just sits there. Patchery starts exactly there. It reproduces the break, works the fix, re-runs your tests, and then grades its own evidence — publishing how far the proof actually goes, and refusing to ship a change it could not prove.

Keep Dependabot. This is the layer above it.

How it works

Four steps, and the last two are the product.

  1. 01

    Reproduce

    It pins your repository, applies the upgrade, and runs your test suite. If the failure is not real and repeatable, it stops here — there is nothing to fix.

  2. 02

    Fix

    An agent reads the failure and the changelog, and migrates the call sites. It works inside your checkout, with your tests as the only judge of whether it is done.

  3. 03

    Prove

    The patch ships with its evidence: the failing run before, the passing run after, the files it touched, and a read-only second agent's review. And it says how far that proof goes — a change nothing mechanical ever exercised opens as a draft marked Not verified, instead of borrowing a header it did not earn.

  4. 04

    Hand over

    Some breaks have no fix at the call site. A dependency that starts shipping as an ES module renames nothing — your code is fine and can no longer load it. Patchery reports which call sites are affected, why the obvious fix does not apply, and which decision would unblock it. Where the fix does not exist at the call site, that report is what is left — a fallback, not the thing Patchery is for.

The gate

Writing the fix is the easy part.

Any capable model can produce a patch that looks right. The question is what happens when it is wrong — and the answer most tools give is: it opens the pull request anyway. Patchery ends a run in one of seven states, and it would rather end in the second one than guess.

REFUSED and WRONG are not the same column.

An agent that declines to send what it cannot prove is doing the job. An agent that sends it anyway is the risk you were trying to remove. A report that merges the two is measuring some other product.

It cannot shrink the test that judges it.

Tests are counted while the code is still whole — before anything is broken, so nothing the agent does afterwards can move that baseline. They are counted again after its turn. If fewer tests pass than at the start, the change is reverted and the run ends REFUSED, however green it looks — nothing reaches a pull request, which is the point.

Where it runs

There is no Patchery server.

Patchery is not a service you send a repository to. It is a file in your project that runs on your own runners, with your own key, against your own checkout. We host nothing and store nothing, so there is no copy of your source anywhere to ask us for.

What does leave the runner is what a model has to read to do the work: the failing test output, the files the agent opens, and the diff it writes. That goes to the endpoint you set in anthropic-base-url and nowhere else — point it at your own deployment and nothing reaches a third party at all.

runs as
a GitHub Action
runs on
your CI runners
model key
yours, in your repo secrets
code we host
none
your code goes to
the model endpoint you configure, only
starts
when you press the button
licence
source available, BUSL-1.1 — free for public repos, subscription for private commercial ones
Evidence

Read the run, not the claim.

A pull request it opened

fix(deps): migrate fake-lib call sites

A breaking upgrade in Patchery's own repository, fixed end to end by the action. The pull request carries the test runs from either side of the fix and the second agent's review — which raised concerns, and says so at the top of the page.

turns
11
cost, at list price
$0.3236
model
glm-5.3-flash
test files changed
0 — enforced by CI
Open pull request #2
The benchmark

14 real breaks, 9 repositories, none of them ours.

Candidate upgrades are pulled from public projects, and each one is confirmed to actually turn that project's own suite red before Patchery is allowed near it. That list is in the repository, not in a slide.

Still no success ratio here, deliberately. The first batch ran while the rules for what counts as a failure of the product versus a failure of our harness were still being fixed — and a number produced under rules that changed mid-run is not a measurement. The full table goes here when a set has run under one set of rules: every case, including the ones it could not fix and what stopped it.

What is already measured is the shape of the problem: 11 of the 14 are packaging breaks, only 3 are changed signatures. "Did the suite break" is a trigger that selects for packaging — express v4 → v5 is one of the best-known breaking changes in the ecosystem, and across five repositories that depend on it, not one suite noticed.

ratio pending a clean full run
Install

One file, and nothing runs until you say so.

  1. Add your model key to the repository's secrets as ANTHROPIC_AUTH_TOKEN.
  2. Save this file as .github/workflows/patchery.yml.
  3. Start it from the Actions tab, and choose which package it works on.

No scheduler and no background scanning: it runs when you dispatch it. Scheduled runs are the next thing on the list.

Full setup guide

.github/workflows/patchery.yml
name: Patchery

on:
  workflow_dispatch:
    inputs:
      package:      { required: true }
      target-dir:   { default: "." }
      test-command: { default: "npm test" }

permissions:
  contents: write
  pull-requests: write

jobs:
  fix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - run: npm ci
        working-directory: ${{ inputs.target-dir }}

      - id: patchery
        uses: patchery-dev/Patchery@v0.2
        with:
          package:              ${{ inputs.package }}
          target-dir:           ${{ inputs.target-dir }}
          test-command:         ${{ inputs.test-command }}
          anthropic-auth-token: ${{ secrets.ANTHROPIC_AUTH_TOKEN }}

      - if: steps.patchery.outputs.changed == 'true'
        uses: peter-evans/create-pull-request@v7
        with:
          branch:    patchery/${{ inputs.package }}
          body-path: ${{ steps.patchery.outputs.pr-body-file }}
          add-paths: ${{ steps.patchery.outputs.files }}
Where it stands

Early, and specific about it.

True today

  • It works on JavaScript projects with a test command.
  • It has opened a real pull request, with the evidence attached.
  • A second agent reviews every patch without write access.
  • 14 real breaks in 9 repositories we do not own are confirmed and queued.
  • Every check is in the repository and readable, not described in a brochure.

Not yet

  • No scheduled runs — you dispatch it by hand, so today it only reacts to a red build.
  • A break your suite never sees is one Patchery never sees. We installed Express 5 into four projects that depend on it — cors, multer, express-session, formidable — and not one suite went red. Their tests never reach the paths that changed.
  • One ecosystem. Other languages are unproven, not supported.
  • No success ratio to quote until a full set runs under one set of rules.
  • Most of what it has met is packaging; changed signatures are the thinner half of the evidence.
  • No users to point at. There is nothing to sign up for.