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.