One pull request, or several? A third option
Every large feature forces a familiar choice: squash everything into one pull request that reviewers dread opening, or split it into a chain of pull requests you must manually sync and rebase. The first is hard to review; the second is hard to maintain.
Coding agents widen the gap. They generate whole implementations quickly—Gartner projects a 50% productivity gain across every SDLC stage by 2028—but they default to whatever structure you give them. Left alone, an agent will happily produce a single 1,700-line pull request containing a data model, API routes, client wiring, UI, and error states all at once.
Stacked pull requests offer a way out: break the feature into a dependency chain of small pull requests, each scoped to one concern and small enough to hold in a reviewer's head. GitHub's native stacked pull request support, including its gh stack CLI, makes that structure practical with agents in the loop.
| Stack Layer (L#)/Branch | What to ship | Depends on |
|---|---|---|
| L1 (feat/catalog-data) | A typed catalog with seed data, validation, and a data access module | main (stack base) |
| L2 (feat/search-api) | Validated /api/products/search endpoint | feat/catalog-data |
| L3 (feat/chat-grounding) | Chat calls the API and answers from real product data | feat/search-api |
| L4 (feat/grounded-ui) | Product citation cards + state | feat/chat-grounding |
Setting up a stack workflow
Set the stack base first, because CI checks and merge rules evaluate against it. Then identify the foundational unit of work and put it lowest in the stack, with dependent layers on top. For a shopping assistant gaining product search, that means four independent concerns: data, API, wiring, and UX. Each can be reviewed by a different owner—data by a data owner, UX by a UI owner.
From the terminal, install the extension and teach agents the workflow:
gh extension install github/gh-stack
Agents need to know how stacks work and how to create and manage them. The gh-stack skills command handles that:
gh skill install github/gh-stack
Or if you prefer:
npx skills add github/gh-stack
Custom agents then follow a strict scoping discipline, each with defined work streams:
| Layer/branch | Agent |
|---|---|
| L1 (feat/catalog-data) | Data modeler agent |
| L2 ( feat/search-api) | Backend agent |
| L3 ( feat/chat-grounding) | Frontend agent |
| L4 ( feat/grounded-ui) | Frontend agent |
Finally, confirm CI exists—checks will run for every layer of the stack, not just the top one.
Building the stack, layer by layer
Layer one: Data catalog foundation
Invoke the Data Modeler agent. It initializes a stack with gh init stack, sets the first branch feat/catalog-data with main as its base, then checks out, works, runs validation, and commits once checks pass. Reviewer's checkpoint for later: are the types correct? Is the data validated? Is the query helper safe?
Layer two: Product search API
The Backend agent adds the next layer feat/search-api on top of layer one—its base is feat/catalog-data—using gh stack add, importing the completed data access module. After validation and a manual API test, the layer commits. Reviewer's checkpoint: input validated? Response contract stable? Are error and empty states handled here or pushed downstream?
Layer three: Wire chat to the API
The Frontend agent adds feat/chat-grounding on top of layer two, branching off with both the data access module and validated API in place. It runs browser tests with Playwright after checking out. Reviewer's checkpoint: every answer traces back to a real API response? What happens when the API fails or returns nothing?
Layer four: Grounded UI and citations
Layers three and four remain distinct despite having the same author (the Frontend agent), deliberately—the UI owner should not need to check underlying data flow, and vice versa. The agent adds feat/grounded-ui on top of feat/chat-grounding, tests in the browser, and commits. Reviewer's checkpoint: every citation links to a real product? Loading, empty, and error states covered?
Submit and review
Once the four branches are ready locally, push them to remote with gh stack push and create linked pull requests with gh stack submit. On GitHub, each pull request displays a stack map—one-click navigation between layers in the stack.
Reviewers read the stack top-down for context: at the top you see the end goal ("we want product cards on the chat interface"). Then review bottom-up, because each layer's implementation only makes sense once the preceding layer is understood. No single 1,700-line diff sits in one review session—work distributes into small, self-contained targets.
Propagating a change through the stack
Inevitably, review requests a change at the bottom. Hand the feedback to the Data Modeler agent that owns the branch, let it apply, test, commit, and push. Then the question becomes: what does this mean for layers two, three, and four?
Because the bottom branch was pushed out of turn after review, GitHub flags the situation plainly: "Some branches in this stack have diverged and must be rebased," blocking the merge. The UI offers a one-click Rebase stack button—but be careful: a web-based rebase runs on GitHub's servers, which resets the committer to whoever clicked, leaves resulting commits unsigned, and quietly breaks branch protection expecting signed commits.
The safer terminal equivalent is gh stack rebase, which performs the same cascading rebase locally using your own Git configuration so you can resolve conflicts interactively, followed by gh stack push. Then gh stack sync fetches from origin, cascades a rebase of every branch above the changed one onto the new commit, pushes rebased branches, and syncs pull request state. The change ripples upward without anyone touching layers two through four by hand. All checks re-run and pass, and the stack map settles into a clean, mergeable line from main to feat/grounded-ui.



