Teaching Claude and coding agents to stack PRs
GitHub now supports stacked pull requests natively, but coding agents in cloud sandboxes could not use them. Here is how we fixed that with agent instructions and a one-line environment change.
Big code changes are slow to review and easy to miss important changes, and the bigger they get the harder it can be to roll back mistakes.
The best practice is to break-down work into smaller chunks, but that has its own cost. If each piece has to merge before you start the next, a feature crawls through review one layer at a time. The better approach combines these two into stacked PRs: a chain of changes that build on top of each other where each layer can be read, tested and reverted on its own.

GitHub shipped stacked pull requests earlier this year. If you haven't tried them, the idea is simple. Instead of one large PR that targets main, you open an ordered sequence of small PRs, each one branched from and targeting the one below it. Reviewers get smaller, grouped changes and merging the top PR triggers a chain where the entire feature is merged as chunks in the right order.
This fits how complex features actually get built. A single feature might need a database change, a new API, some UI and updated support docs. As a stack: we would put the schema at the bottom, the code that uses it above, and the docs on top; each one small enough to review and have confidence in anything that requires a specific order. On a laptop it's pretty seamless: GitHub's gh stack extension creates the branches, opens each PR against the one below it and links the whole thing into a native stack.
However, it's not as easy for coding agents in cloud sandboxes to do the same.
Limitations with coding agents
Every Claude Code cloud session starts in a fresh sandbox with a standard set of tools, this is good security practice and prevents situations where "it works on my machine". These sandbox environments have the GitHub CLI installed, but gh stack isn't, and you can't add it from inside a session. The sandbox also blocks GitHub's GraphQL API, which the extension relies on. So Claude could create a branch off a parent and open a PR against it, but it had no way to link those PRs into a stack.

This isn't ideal: either a whole feature landed as a single PR that touched every layer of the app, or it arrived as a loose chain of PRs fragile to changes and prone to mistakes.
Teaching agents to use stacked PRs
Tooling gets the mechanics right, but it can't make the judgement calls. An agent still has to decide whether a piece of work deserves a stack at all, what goes in each layer, which order the layers merge in, and what state each one has to be in before it's safe to land. None of that is general knowledge. It depends on how the repo is put together and how it deploys, so it has to be written down where every session will read it.
The first step was to update our CLAUDE.md and AGENTS.md files, which Claude Code and other coding agents read at the start of every session, with a short section on stacking. It comes down to four things.
Stack by default. The work is split whenever it spans more than one layer (schema, packages, libraries, services, or UI), if it's ~400+ changes, or has a natural breakpoint of a feature rollout. If a PR outgrows that while it's being written, it gets split before review.
Each PR stands on its own.
Each one has to lint, type-check and build on its own head, and leave main deployable even if nothing above it ever merges. It's fine to land code that nothing calls yet. It's not fine to leave a half-built feature reachable, so anything partial sits behind a flag, an unlinked route or gate until the last PR removes it.
Follow dependencies. In our repo the order is nearly always the same:
- Database changes as migrations (with regenerated database types)
- Packages
- Libraries and services
- Apps and UI
- Flags and observability

The order matters: Supabase and Vercel deploy independently, with no guarantee about which goes first, so the only way to be sure the database is updated before the code that needs it is to put the migration at the bottom of the stack and merge it first. If it fails, the rest of the changes are paused.
Keep it shallow. Two to four PRs is the sweet spot. Beyond that, the retargeting and merging down costs more time than the smaller reviews save.
Recently we open-sourced StuntKit. First the switch to StuntKit's browser toolset, spelling and icon packages, then the agent skills that document them, and finally a release so our apps point to the new set of packages.
Giving the sandbox the same tools
Our first attempt worked around the sandbox rather than fixing it. Claude opened each PR against its parent branch, then linked the chain through GitHub's REST API for stacks, since GraphQL is blocked by security policies. That worked, but it meant a separate, agent-only way of doing something we already did ourselves with one command.
So we changed the sandbox environment instead; cloud sessions now run in a custom environment whose setup script installs the extension before the session starts. It's just one line:
gh extension install github/gh-stack
With that in place, agents can run the same commands we do:
gh stack init
gh stack add
gh stack submit
gh stack sync
gh stack merge
The first stacks exposed an oversight in our CI workflow which was configured to only run on pull requests targeting main, leaving PRs in the middle un-validated before they were merged. The simple fix was to re-target CI to run on all branches and setup branch protection rules that prevent merging if they fail.
The last piece was to update the PR template with a description that includes the whole stack as a numbered list of links, making it easy to understand at a glance what each PR contributes and how the stack is organised.
Stacked PR gotchas
A few things can go wrong that are unique to using stacked PRs.

Update branch protection rules.
Use hooks, CI, and branch protection rules to catch issues on each individual PR and prevent merging if the rules aren't met. Where this matters most is with database migrations, which use a unique timestamp to ensure the correct order is applied. If two stacks both have migrations a pre-push hook and a required CI step now reject any migration created before the most recent one on main. This catches potentially catastrophic conflicts where migrations become out of sync and skipped silently.
Merge from the bottom, one at a time, on green.
It's tempting to retarget a child straight at main to skip the queue, but that pulls the parent's unreviewed commits along with it. When feedback lands on a lower PR, the fix goes there and flows up.

Use hot-fix to jump the queue: If a patch is needed before a stack can be merged, use a fresh branch off main, merge it first, then continue the stack. Require human review for hot-fix changes.
Let gh stack keep the stack current.
When main moves on, or a lower layer changes after review, gh stack sync rebases every branch above it in order and pushes them. Agents can run this utility rather than rebasing branches one at a time by hand.
Key takeaways: doing this yourself
Your agents' work arrives in pieces you can actually review: each layer read in one sitting, tested on its own and reverted on its own if something breaks. Fewer surprises reach production, and the ones that do are easier to undo.
To set it up yourself:
- Install
gh-stackin the agent's environment. Addgh extension install github/gh-stackto the setup script of whatever cloud environment your agents run in, so every session starts with it. - Write a stacking section in your agent instructions.
In
CLAUDE.mdorAGENTS.md, say when to stack, what makes each PR safe to merge on its own, and the layer order your repo needs. Put the reason next to each rule: "one migration per PR" gets followed, but "one migration per PR, because an early stamp is skipped by every deploy" also gets followed in the cases you didn't anticipate. - Make CI run on every layer.
If your workflow only triggers on PRs targeting
main, everything above the bottom of a stack goes unchecked, and the agent learns the rule is optional. - Ask for a stack map in every PR description. A numbered list of the stack with the current PR marked saves reviewers from opening a diff that looks incomplete.
See it on your own site
Give an actor your URL. It opens a real browser, works through the site, and shows you every step it took.
Free to start, or watch a live demo.
Keep reading

4 minBuilding a Self-Healing Product Feedback Loop
Turn error signals and feedback into almost instant product improvements with triage and cloud coding agents.

4 minBuilding with Supabase
How we run a multi-tenant AI agent platform on Supabase: row level security for tenant isolation, OAuth and passkeys for humans and machines, pgvector for agent RAG, read replicas for global reads, and preview branches for every pull request.

7 minHow to Test Your Product for AI Agent Users
AI agents are already signing up for your product, checking out, and navigating flows. Most products break silently when the user isn't human. Here's how to find out where.






