PatcheryGitHub ActionnpmMITearly

When a dependency breaks your code, Patchery fixes it and proves the fix.

Your project runs on other people’s code. When they change how it works, your app stops working. Patchery finds what broke, rewrites the lines that need rewriting, and checks the result against your own tests before it shows you anything — and throws its own work away if that check goes badly.

  • 1pull request it opened on its own
  • $0.1213what that run cost, end to end
  • 0users, customers, logos
  • MITevery line of it public

Read the pull request it opened Read the source

02 Why this is harder than it looks

Tell an AI to make the tests pass. It might just delete them. // 4 tests removed · suite green

This is not a hypothetical

Deleting the test is the cheapest way to satisfy the instruction, so it is the one an agent reaches for first. Failing that: soften the check, stub out the function, edit the very file that decides what working means. Every one of those makes a broken project look fixed.

Which means writing the fix was never the interesting problem. Everything that happens after it is. Patchery never reads the AI’s own account of what it did — it looks at the files themselves, throws the whole attempt away if anything off-limits moved, and re-runs your tests itself.

Why anyone needs it now

The libraries underneath modern software change faster than the teams using them can follow. Tools like Dependabot are good at telling you a newer version exists. They stop exactly where the work starts: the places in your code that used the old way.

That gap used to need a person. It stopped needing one somewhere in the last two years — but only if you can trust the result, which is the same problem again.

For scale, not for credit Recent breaking major releases, picked to show how ordinary this is. These are not packages Patchery has fixed. Two of them are: openai and @google/generative-ai — both migrated by hand, both linked below.
03 One run, five gates

In plain termsIt tries the fix, then spends four more steps trying to catch itself cheating.

It has to get
past itself first.

  1. 01Check it’s really brokenIf your tests already pass, stop here and charge nothing.
  2. 02Read the notes, fix the codeFind what changed, rewrite the lines that used the old way.
  3. 03Look at what changed on diskNot what the AI says it did — what the files say it did.
  4. 04Run your tests againMeasure it. Don’t ask it.
  5. 05Ask a human to approve itA change request you read and merge yourself. Never automatic.
step 01your test commandfailed
$ npm test

> toy-project@1.0.0 test
> node app.test.js

node_modules/fake-lib/index.js:3
    throw new TypeError("currency is required as of fake-lib@2.0.0");
    ^

TypeError: formatPrice(amount, currency): currency is required
    at formatPrice (node_modules/fake-lib/index.js:3:11)
    at renderCartTotal (app.js:4:20)
    at Object.<anonymous> (app.test.js:4:16)
This is the entry ticket. Patchery runs your own tests before it does anything else, and if they pass it stops — no AI, no cost, no pull request you didn’t ask for.
readingwhat the library changed
# fake-lib changelog

## 2.0.0 (breaking)

- Removed formatPrice(amount).
  Returned a plain number and rounded
  inconsistently across locales.

- Added formatPrice(amount, currency).
  Now requires an explicit currency
  code, e.g. "USD".

### Migration
  formatPrice(19.9)        // "19.90"
  formatPrice(19.9,"USD")  // "$19.90"
writingapp.jsone line
1  const { formatPrice } = require("fake-lib");
2
3  function renderCartTotal(amount) {
4    return `Total: ${formatPrice(amount)}`;
5  }
6
7  module.exports = { renderCartTotal };
The AI gets a fixed budget and a watchdog. Repeat the same move three times, or spend eight turns changing nothing, and the run is cut off — that watchdog exists because one confused run once spent 25 turns and 88 cents producing nothing at all.
step 03every file it touchedclean
changed on disk:
  app.js                       allowed

checked, and untouched:
  your tests                   off-limits
  package-lock.json            off-limits
  node_modules/                off-limits
  your CI configuration        off-limits

→ nothing off-limits moved. carry on.
This is the step the whole product is built around. If the AI touches even one file on that list, the entire attempt is deleted — the working fix along with it. Try to sneak one past it →
step 04your test command, againpassed
$ npm test

> toy-project@1.0.0 test
> node app.test.js

PASS: app.test.js
Same command, same machine, run from scratch a second time. Patchery never asks the AI whether it worked — it re-runs your tests and reads the answer itself.
Open patchery-dev/Patchery #2

fix(deps): migrate fake-lib call sites

a change request, waiting for a human

app.js
  function renderCartTotal(amount) {
−    return `Total: ${formatPrice(amount)}`;
+    return `Total: ${formatPrice(amount, "USD")}`;
  }
  • 1 file
  • +1 −1
  • 11 turns
  • $0.1213

Opened automatically. Never merged automatically.

04 The part that matters, in your hands

In plain termsSome files are off-limits, and touching one throws away the whole attempt — including a fix that worked.

Try to
break it.

The off-limits list is short: your tests, the file that pins your versions, your build settings, and the installed libraries themselves. Those are the four ways an AI could make a broken project look fixed, so none of them may move. Two more rules sit alongside them — nothing may be deleted, and nothing outside the folder you pointed it at may be touched at all.

The box below runs the real check — the same few lines that run inside Patchery’s source, copied character for character, not a demo of it. Give it any file path and see what it decides.

+

or try one of these

the check files the AI touched 0 files

    Nothing here yet. Add a file and the verdict appears below.

    verdict waiting

    Five rules on the off-limits list, in the order they run — installed libraries, test files, test folders, build settings, version-lock files — plus a ban on deletions and on anything outside the folder you pointed it at. All of it is covered by a test that runs on every change to Patchery itself: offline, in a second, with no AI and no key.

    05 Evidence, not adjectives

    In plain termsEverything below is a link you can open and check for yourself, right now.

    It has done this once,
    with nobody watching.

    no human involved patchery-dev/Patchery #2

    One line, in one file, in a real repository

    A library called fake-lib went from version 1 to version 2 and made an argument required that used to be optional. Patchery ran the tests (they failed), read what the library had changed, rewrote the one line that needed it, checked which files it had touched, ran the tests again (they passed), and opened this pull request. The first human to see it was the reviewer.

    • files changed1
    • lines+1 −1
    • testsfailedpassed
    • AI turns used11
    • total cost$0.1213
    Open it on GitHub

    And here is the same job done by hand, on two projects we don’t own. No AI was involved in either — they are here because doing this work manually is how we learned what the automated version has to survive.

    All three are still open. None has been merged. We will change this sentence the day that changes.

    06 If you want to run it

    In plain termsYou copy one file into your project, and nothing happens until you press a button.

    One file in,
    one workflow out.

    Patchery is not a service you sign up for. It is a file you put in your own project, running on your own machines, with your own key — which is also why there is nothing for us to charge you for yet.

    1. 01Put your AI key in the repository’s secrets, as ANTHROPIC_AUTH_TOKEN.
    2. 02Save the file on the right as .github/workflows/self-maintain.yml.
    3. 03Start it from the Actions tab. You choose which library it works on.

    No scheduler, no background scanning. Nothing runs unless you press the button — that is deliberate, and it is the next thing to change.

    Full setup guide
    yaml .github/workflows/self-maintain.yml
    name: self-maintain
    
    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: sma
            uses: patchery-dev/Patchery@v0
            with:
              package:              ${{ inputs.package }}
              target-dir:           ${{ inputs.target-dir }}
              test-command:         ${{ inputs.test-command }}
              anthropic-auth-token: ${{ secrets.ANTHROPIC_AUTH_TOKEN }}
    
          - if: steps.sma.outputs.changed == 'true'
            uses: peter-evans/create-pull-request@v7
            with:
              branch:    self-maintain/${{ inputs.package }}
              body-path: ${{ steps.sma.outputs.pr-body-file }}
              add-paths: ${{ steps.sma.outputs.files }}
    07 Where this actually is

    We’d rather you audit us
    than trust us.

    True today

    • Anyone can install it right now, and read every line of it. MIT licensed.
    • One pull request opened start to finish with no human in the loop.
    • The off-limits check is tested on every change, offline, with no AI.
    • Keys and passwords are stripped out before anything is written down.
    • Works on JavaScript projects. You decide what counts as a passing test.

    Not yet

    • Nothing hosted. It runs on your machines, not ours.
    • No revenue, no users, no logo wall. Nobody is paying for this.
    • No open-source pull request accepted yet — the two below are waiting.
    • One library at a time. It won’t untangle a chain of breakages.
    • Other languages are plausible, but nobody has proven it.
    Live, in your browser, right now

    So here is the page checking itself.

    Everything below is written as something that can fail. They run against the real files and the real GitHub API, not against a recording. If one of them ever turns red on this page, the page is wrong — and it will be the first to say so.

    patchery audit --self

      Every number on this page comes from a run you can open and read for yourself. And one thing worth saying plainly: the AI reads your code. Check what your model provider does with it before you point this at anything private. The full list of limits →