Blog
Updated SheltieBy Krzysztof Grajek

Introducing Sheltie: merge agent pull requests in parallel

Sheltie is a GitHub App that computes what every pull request touches, lands independent ones together and resolves conflicts in escalating tiers. Open source, Apache-2.0, early 0.x.

The Sheltie dashboard with example data: time saved against a one-at-a-time merge queue, landings per day and agent spend
The Sheltie dashboard for a repository (example data).

Coding agents open more pull requests than a one-at-a-time merge queue can land. Sheltie is my answer to that: a parallel merge engine for agent-generated pull requests. It runs as a GitHub App next to your existing CI, lands independent pull requests together, and resolves conflicts before a person has to.

Updated 20 Oct 2026 with releases and results since launch.

The repository went up on 16 October. The first release, v0.1.0, followed on 17 October, and at the time of writing the latest is v0.6.0, from 20 October. It is early (0.x), and the README says so.

The problem

A one-at-a-time merge queue lands each pull request on top of the last, with a CI run in between, so every change waits for every one ahead of it, whether or not they touch the same code. With agents opening pull requests, that wait is where the time goes. Sheltie’s answer is to work out which pull requests are actually independent and land those together.

Footprints

For every pull request an adapter computes a footprint: the build targets it writes, and the targets it affects through their interfaces. Two pull requests conflict only when one writes what the other writes or affects. Everything else can land together.

Adapters exist for six build tools, each running on your CI runner and uploading the footprint:

Build tool Adapter Unit
Cargo sheltie-cargo module
Go sheltie-go package
JavaScript / TypeScript (npm, yarn, pnpm, Nx) sheltie-node workspace package
Python (uv, Poetry, setuptools) sheltie-python package
Maven sheltie-maven module
Gradle sheltie-gradle project

The Cargo adapter parses interfaces with syn. The others read declarations line by line, without a compiler. That is pessimistic on purpose: an adapter can see an interface change where there is none, never the reverse. Bazel, sbt and Mill are planned.

How a pull request lands

  1. An agent opens a pull request; GitHub notifies Sheltie.
  2. The adapter for your build tool runs on your CI runner and uploads the footprint.
  3. The scheduler lands independent pull requests in parallel. Conflicting ones are built speculatively together or sent to the merge engine.
  4. The committer checks that nothing that landed meanwhile touches the change, then fast-forwards the default branch. It never force-pushes.
  5. Sweeps watch the default branch; a red commit is bisected and reverted automatically.

Builds, tests and agent jobs run on your runners with your API keys. The control plane only does set arithmetic and talks to GitHub.

Conflicts, in escalating tiers

When two pull requests do touch the same code, Sheltie tries progressively stronger resolutions on your runner, and verifies every result with your CI before it lands:

  1. Structural merge, by syntax tree with mergiraf, so two edits to the same file stop being a conflict.
  2. Regenerate lockfiles and other derived files instead of hand-merging them.
  3. Declared rules: set-like files are unioned and numbered migrations renumbered, as you declare in .sheltie/merge.toml.
  4. Replay: Claude Code re-derives the change from the pull request itself, whoever wrote it, checked against the tests it adds and the reviewed diff.

Since v0.6.0, replay finds its acceptance tests automatically: tests the pull request adds or changes that pass with the change and fail without it. The replayed result must pass them.

Before work starts, Sheltie also keeps agents off overlapping issues. It predicts which code an issue will touch and lets only one agent at a time work on issues that overlap; agents ask over MCP.

The demo

softberries/sheltie-demo-cargo-shop is a small Cargo workspace where a script opens a batch of agent-style pull requests: mostly independent, some editing the same files, one breaking another only when combined. Two batches ran on 17 October against demo.sheltie.dev in merge mode with the merge engine on. Measured by Sheltie, against a one-at-a-time merge queue simulated from the same ready times and the median CI time on main (1 min 50 s):

Sheltie One at a time
Pull requests landed 17 17
Median time from ready to landed 18 s 7 min 7 s
Longest wait 6 min 37 s 14 min 5 s
Total waiting 23 min 2 h 8 min

12 landed footprint-proven with no extra CI run; 5 were verified in a combined build. The merge engine resolved 3 by declared merge rules, and 2 that broke only when combined with an earlier change were re-derived from their intent by Claude Code, for about $0.04 together. One more went back to its author because the merge workflow was not installed yet in the first batch.

That is one small demo repository, built to exercise the scenarios its README lists: independent changes, feature flags, migrations and a semantic conflict.

A Sheltie report for a pull request that landed after an agent re-derived it on the new head, with its acceptance tests and footprint The Sheltie check on a pull request it replayed and landed, on the demo repository.

On real repositories

A demo built for the tool proves little on its own, so I also measured what Sheltie would have done on 23 popular open-source repositories over 90 days, against what each project does today. The report covers both sides. Where projects use a merge queue, Sheltie would cut waiting substantially. On projects without a merge queue, the study could not show that Sheltie prevents a red main, and there Sheltie would add CI rather than save it. It also lists where Sheltie’s footprints may have missed a real interaction. These are simulations, not production runs; the scripts and data are in the repository.

Try it

Start in shadow mode, where Sheltie only reports what it would do and how often it would have been wrong, before letting it merge.

To self-host you need a host with Docker and a public HTTPS name, and a browser to register the GitHub App:

git clone https://github.com/softberries/sheltie && cd sheltie
scripts/register-github-app.py --url https://sheltie.example.com   # writes .env and the App key
docker compose up -d --build
curl -s localhost:8080/healthz                                       # {"status":"ok"}

Then put a TLS reverse proxy in front of port 8080, install the App on your repositories, and add the footprint workflow. The Self-hosting guide also covers Kubernetes with Helm.

Sheltie is licensed under Apache-2.0.