stacked-pr-splitter
Skill20 starsChanged 14 days agoMITView on GitHub
Analyze an oversized current pull request or branch diff and redesign it as a small, reviewable set of independent and/or stacked pull requests. Inspect Git history, diff statistics, tests, generated files, and CODEOWNERS; propose a dependency graph, branch and base plan, reviewer routing, tests, and exact coverage of the original change — applied locally or published only when explicitly requested, final behavior preserved, no unrelated refactors. Use when the user runs /stacked-pr-splitter, optionally with a PR number or branch — for a PR that is difficult to review, spans multiple features, modules, or teams, exceeds roughly 1,000 changed human-authored lines, has tangled dependencies, or needs CODEOWNERS-aware review boundaries ("split this PR", "break up this PR", "stack my PRs").
- Commits and pushes
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- a11y-page-auditSkill
- branch-comment-cleanupSkill
- branch-test-planSkill
- context7-mcpSkill
- env-example-syncSkill
- feature-based-architectureSkill
- great-readmeSkill
- harvest-reviewsSkill
- light-dark-modeSkill
- localizationSkill
- minimal-code-changesSkill
- prod-page-auditSkill
- quantum-design-tokensSkill
- reviewable-commitsSkill
- shell-aliases-socialSkill
- skill-best-practices-syncSkill
- skills-auditSkill
- skills-socialSkill
- team-reviewerSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
39 rules. About 0 are common, 31 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈31
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 26
Do not introduce cleanup, redesign, formatting churn, dependency upgrades, or unrelated refactors.
- Distinctive: line 28
Prefer independent PRs from the original base when changes can stand alone.
- Distinctive: line 31
Keep implementation and its direct tests together.
- Distinctive: line 36
Do not propose a PR above 2,000 reviewable changed lines.
- Very specific: line 40
Read and respect repository-local instructions such as AGENTS.md, CLAUDE.md, CONTRIBUTING.md, and relevant README files.
- Distinctive: line 51
Plan only: Use for requests such as "analyze", "suggest", "design the split", or ambiguous requests.
- Distinctive: line 53
Apply locally: Use only when the user asks to split, restructure, create branches, or rewrite the local PR.
- Distinctive: line 55
Publish: Use only when the user explicitly asks to push, open, create, or update remote PRs.
- Distinctive: line 58
Do not close, replace, force-push, or comment on the original PR unless explicitly requested.
- Distinctive: line 65
When a Git repository is available, run (from the repository root):
- Distinctive: line 80
Treat the original base as the stack trunk.
- Very specific: line 81
Never discard, reset, clean, or auto-stash uncommitted work.
- Very specific: line 89
Commit history between merge-base and source — script commits.
- Distinctive: line 102
Do not infer a semantic split from filenames, directories, commit messages, or ownership alone.
- Very specific: line 113
Do not invent an owner for unmatched files (matched: false).
- Distinctive: line 115
Prefer one primary owner group per PR when semantic boundaries permit.
- Distinctive: line 116
If one owner group's coherent change exceeds 1,000 reviewable lines, split it again by behavior, use case, endpoint, component, migration …
- Distinctive: line 118
If a cross-team change is atomic, keep it together and list every affected owner.
- Distinctive: line 126
Start with candidate independent vertical PRs.
- Distinctive: line 130
Use multiple independent PRs or multiple short stacks when possible.
- Distinctive: line 131
Keep stack depth as low as the dependency structure allows.
- Distinctive: line 132
Place a dependency in the same PR or a lower PR, never in a higher PR.
- Distinctive: line 135
Keep intermediate states deployable when the repository deploys every merge.
- Distinctive: line 146
Total lines: all numeric additions plus deletions.
- Distinctive: line 155
Do not split a coherent 300-line change merely to balance PR sizes.
- Distinctive: line 161
Before presenting or applying the split, copy this checklist and tick each item:
- Distinctive: line 184
Never delete or rewrite the original branch by default.
- Distinctive: line 185
Create each new branch from its declared trunk or parent branch.
- Distinctive: line 186
Prefer existing commits only when an entire commit belongs to one proposed PR.
- Distinctive: line 187
When commits are mixed, reconstruct the final change from the recorded source SHA using whole-file restoration for exclusive files and …
- Distinctive: line 190
Commit the final intended state for each PR.
- Distinctive: line 192
Run the narrowest relevant checks after each PR, then the repository's required checks when feasible.
- Distinctive: line 194
Verify each branch diff against its declared base and recalculate line counts and ownership.
- Distinctive: line 196
Create a disposable integration branch or worktree, apply all unique PR commits in topological order, and compare its final tree with the …
- Distinctive: line 199
Keep the safety branch and report all created branch names, commit SHAs, checks, and any deviations.
- Very specific: line 212
Prefer GitHub's native gh stack workflow for a linear stack when gh stack --help succeeds (script github_cli.stack_available).
- Very specific: line 215
Use ordinary branches and gh pr create as the portable fallback and for independent PR graphs.
- Very specific: line 221
Use the PR body structure from references/output-template.md, including purpose, dependency, review scope, ownership, size, tests, and …
- Very specific: line 225
Never force-push an existing shared branch without explicit permission.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Stacked PR Splitter
Turn one oversized change into the smallest sensible dependency graph of reviewable pull requests. Optimize for reviewer comprehension, ownership, independent verification, and safe merge order. Do not optimize for equal line counts.
Hard rules (never violate)
- Preserve the intended final behavior and complete final tree of the original PR.
- Do not introduce cleanup, redesign, formatting churn, dependency upgrades, or unrelated refactors.
- Prefer independent PRs from the original base when changes can stand alone.
- Stack a PR only when it has a real compile-time, runtime, schema, API, migration, or review dependency on a lower PR.
- Keep implementation and its direct tests together.
- Make every PR coherent, reviewable, and valid against its declared base.
- Target at most 1,000 reviewable changed lines per PR.
- Permit 1,001 to 2,000 reviewable changed lines only with a concrete cohesion or safety justification.
- Do not propose a PR above 2,000 reviewable changed lines. Mark the plan non-compliant if no safe split is found and explain the indivisible boundary.
- Report generated, vendored, snapshot, binary, and lockfile changes separately. Never use them to hide a large human-authored change.
- Read and respect repository-local instructions such as
AGENTS.md,CLAUDE.md,CONTRIBUTING.md, and relevant README files.
The budget exists because reviewer attention drops sharply past a few hundred lines: about 1,000 reviewable lines is the most one reviewer can assess carefully in one sitting, and beyond 2,000 a review degrades into a rubber stamp.
Phase 0 — Select the operating mode
Infer the mode from the request:
- Plan only: Use for requests such as "analyze", "suggest", "design the split", or ambiguous requests. Inspect without changing Git state.
- Apply locally: Use only when the user asks to split, restructure, create branches, or rewrite the local PR. Create local branches and commits, but do not push.
- Publish: Use only when the user explicitly asks to push, open, create, or update remote PRs. Prefer draft PRs unless the user requests ready-for-review PRs.
Do not close, replace, force-push, or comment on the original PR unless explicitly requested.
Phase 1 — Establish the source and base
- Work from the repository root.
- Resolve the source from the supplied PR, branch, or current
HEAD. - When a Git repository is available, run (from the repository root):
python3 <skill-directory>/scripts/analyze_pr.py --repo . --head HEAD --format jsonPass --base <ref> when the base cannot be inferred reliably. Take the values below and
in Phases 2, 3, and 5 from its JSON output instead of deriving them by hand.
- Take the original PR base from
base.ref. The script resolves it withgh pr viewwhen available, otherwise the configured remote default branch, then common base branches such asmainormaster;base.resolutionsays which applied. - Record the source branch, source commit SHA, base ref, merge-base SHA, and working-tree
status (
source.display_ref,source.sha,base.ref,base.merge_base_sha,working_tree). - Treat the original base as the stack trunk.
- Never discard, reset, clean, or auto-stash uncommitted work. If the tree is dirty
(
working_tree.dirty), continue in plan-only mode and state that local application is blocked.
Phase 2 — Inventory the change
Inspect all of the following before designing boundaries:
- Commit history between merge-base and source — script
commits. - Changed files, additions, deletions, renames, binaries, and directory distribution —
script
files(status,old_path,additions,deletions,binary) andarea_summary. - Relevant diffs, symbols, imports, interfaces, schemas, migrations, feature flags, and tests — read the diff itself.
- Generated files, lockfiles, snapshots, vendored files, and machine-produced artifacts —
script
files[].category. - The effective
CODEOWNERSfile from the original base branch — scriptcodeowners.path. - CI, branch protection, test, build, deployment, and migration constraints visible in the repository.
Do not infer a semantic split from filenames, directories, commit messages, or ownership alone. Read enough of the actual diff to understand behavior and dependencies.
Phase 3 — Map ownership correctly
- Take each path's owners from
files[].ownership(matched,owners,pattern) and per-owner totals fromownership_summary. The script locatesCODEOWNERSon the original base in this order:.github/CODEOWNERS,CODEOWNERS, thendocs/CODEOWNERS, and applies the last matching valid pattern for each path. - Preserve entries with multiple owners and entries that intentionally clear ownership
(
matchedwith emptyowners). - Do not invent an owner for unmatched files (
matched: false). Suggest a logical reviewer separately and label that suggestion as inferred. - Prefer one primary owner group per PR when semantic boundaries permit.
- If one owner group's coherent change exceeds 1,000 reviewable lines, split it again by behavior, use case, endpoint, component, migration phase, or another semantic boundary.
- If a cross-team change is atomic, keep it together and list every affected owner. Explain why splitting at the ownership boundary would create an invalid or misleading review.
Phase 4 — Design the dependency graph
Load references/splitting-rules.md and apply its priority order and special cases.
- Start with candidate independent vertical PRs.
- Extract shared prerequisites only when multiple PRs truly depend on them or when they form a meaningful PR of their own.
- Build a directed acyclic graph, not automatically one long chain.
- Use multiple independent PRs or multiple short stacks when possible.
- Keep stack depth as low as the dependency structure allows.
- Place a dependency in the same PR or a lower PR, never in a higher PR.
- Give every PR one clear purpose and one concise review narrative.
- Assign direct tests and validation to the PR that introduces the behavior.
- Keep intermediate states deployable when the repository deploys every merge. Use additive schema and compatibility phases when necessary.
Phase 5 — Enforce the size budget
Define line counts as follows:
- Reviewable lines: additions plus deletions in human-authored source, tests, configuration, migrations, and documentation.
- Auxiliary lines: additions plus deletions in generated files, snapshots, vendored files, and lockfiles.
- Total lines: all numeric additions plus deletions. Report binary files separately.
The script applies these definitions: per file reviewable and changed_lines, and
totals in summary (reviewable_lines, auxiliary_lines, total_numeric_lines,
binary_files). Sum changed_lines per proposed PR; count by hand only the hunks of
files split across PRs.
For every proposed PR, apply the budget from hard rules 7 to 9, and:
- Do not split a coherent 300-line change merely to balance PR sizes.
- Isolate a very large generated or lockfile diff when doing so improves review, but keep its source-of-truth change and regeneration instructions obvious.
Phase 6 — Verify the plan
Before presenting or applying the split, copy this checklist and tick each item:
- [ ] Every original changed path and semantic change is assigned.
- [ ] No semantic change is duplicated or omitted.
- [ ] Shared-file hunks are assigned to the correct PR.
- [ ] The dependency graph is acyclic.
- [ ] Every PR has the correct base branch.
- [ ] Every PR is understandable without reviewing higher PRs in the stack.
- [ ] Every PR can build and run its declared checks against its own base.
- [ ] CODEOWNERS and inferred reviewers are explicit.
- [ ] The union of all PRs reconstructs the original final tree.
- [ ] The plan contains no unrelated improvements.Fix any failure and recheck before Phase 7 or the report.
Phase 7 — Apply the split locally
Perform these steps only in Apply locally or Publish mode:
- Require a clean working tree.
- Record the original source SHA and create a uniquely named safety branch at that SHA. Never delete or rewrite the original branch by default.
- Create each new branch from its declared trunk or parent branch.
- Prefer existing commits only when an entire commit belongs to one proposed PR.
- When commits are mixed, reconstruct the final change from the recorded source SHA using whole-file restoration for exclusive files and hunk-level patches for files shared across PRs. Do not reimplement the feature from memory.
- Commit the final intended state for each PR. Do not create artificial "work in progress" evolution unless an intermediate compatibility layer is required.
- Run the narrowest relevant checks after each PR, then the repository's required checks when feasible.
- Verify each branch diff against its declared base and recalculate line counts and ownership.
- Create a disposable integration branch or worktree, apply all unique PR commits in topological order, and compare its final tree with the recorded original source SHA. Require an empty tree diff.
- Keep the safety branch and report all created branch names, commit SHAs, checks, and any deviations.
Abort local application without destructive cleanup if a conflict cannot be resolved confidently. Preserve all work and return the validated plan plus the exact blocking conflict.
Phase 8 — Publish the PRs
Perform these steps only in Publish mode:
- Confirm that the remote, authentication, and push permissions are available through the existing environment.
- Prefer GitHub's native
gh stackworkflow for a linear stack whengh stack --helpsucceeds (scriptgithub_cli.stack_available). Inspect the installed command help before relying on flags because the feature may evolve. - Use ordinary branches and
gh pr createas the portable fallback and for independent PR graphs. - Set the bottom PR base to the original trunk. Set each dependent PR base to its immediate parent branch.
- Publish as drafts by default so the complete graph, descriptions, and links can be checked before requesting reviews.
- Use the PR body structure from
references/output-template.md, including purpose, dependency, review scope, ownership, size, tests, and stack navigation. - Link every PR to the original oversized PR when one exists.
- For non-native stacks, explain the bottom-up merge and retarget/rebase sequence.
- Never force-push an existing shared branch without explicit permission. Use
--force-with-leaseonly when a requested stack operation requires it and the remote state has been checked.
Report
Load references/output-template.md and follow it. State assumptions and unresolved
risks without pretending certainty. Finish only when the result is one of these:
- A compliant, fully specified split plan.
- A locally created and equivalence-verified branch graph.
- A published set of linked draft or ready PRs with verified bases and checks.
- A clearly marked non-compliant plan that identifies the exact boundary preventing a safe sub-2,000-line split.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

