chained-pr
Chained PRs for large changes — split oversized PRs into sequential, reviewable chunks under 300 lines. Stacked PRs or Feature Branch Chain. Trigger: When a PR exceeds 300 lines, or SDD forecasts budg
SKILL.mdskills/chained-pr/SKILL.md
GitHubSkill: chained-pr
Chained PRs. Large changes broken into reviewable chunks that protect reviewer cognitive load.
Activation Contract
Load this skill when:
- A planned PR may exceed 300 changed lines
- SDD forecasts
300-line budget risk: HighorChained PRs recommended: Yes - The user asks for chained/stacked PRs or review slices
Hard Rules
- Split PRs over 300 changed lines unless a maintainer explicitly accepts
size:exception - Keep each PR reviewable in ≤60 minutes
- One deliverable work unit per PR; keep tests/docs with the unit they verify
- State start, end, prior dependencies, follow-up work, and out-of-scope in every chained PR
- Every child PR must include a dependency diagram marking the current PR with
📍 - Do not mix chain strategies after the user chooses one
Decision Gates
| Condition | Action |
|---|---|
| PR ≤300 changed lines and focused | Keep single PR |
| PR >300, each slice can land independently | Use Stacked PRs to main |
| PR >300, feature must integrate before main | Use Feature Branch Chain with tracker |
| Generated/vendor/migration diff cannot split cleanly | Ask maintainer for size:exception |
SDD provides delivery_strategy |
Follow it before apply/PR creation |
Strategy A: Stacked PRs to Main
main ← PR1 (refactor base)
← PR2 (core logic, base = PR1)
← PR3 (integration, base = PR2)
- PR1 targets main, gets reviewed and merged
- PR2 targets main, but code based on PR1
- PR3 targets main, but code based on PR2
- Each merge updates main, next PR rebases
Strategy B: Feature Branch Chain (with Tracker)
main ←──── feature/auth (tracker PR, draft, no merge)
← feat/auth-validate (PR #1)
← feat/auth-middleware (PR #2, base = PR #1)
← feat/auth-integrate (PR #3, base = PR #2)
- Create tracker PR
feature/auth→ draft, targets main, never merged - PR #1 targets
feature/auth, reviewed and merged into tracker - PR #2 targets PR #1's branch, reviewed and merged
- PR #3 targets PR #2's branch, reviewed and merged
- When all children are in, merge tracker to main
Critical: child PRs must NEVER target main directly. If GitHub shows previous slices in a child diff, retarget/rebase until the diff is clean.
Execution Steps
- Estimate changed lines and identify independent work units
- Ask for chain strategy when none is cached and budget is exceeded
- Create branches/PRs using the chosen strategy only
- Add Chain Context to each PR body (see below)
- Verify each PR independently: CI, tests, docs, clean diff
- Keep tracker PR draft/no-merge until all children are reviewed
Chain Context (add to each PR body)
## PR Chain
This is PR **2 of 3** in the `{feature}` chain:
- 📍 **PR #2 — {this PR description}** (you are here)
- PR #1: {description} → {link}
- PR #3: {description} → {link}
| Item | Value |
|------|-------|
| Chain strategy | stacked-to-main / feature-branch-chain |
| Review budget | {additions} + {deletions} = {total} changed lines |
| Depends on | {PR #1 link} |
| Blocks | {PR #3 link} |
Output Contract
Return: chosen strategy, PR order, current PR boundary, dependency diagram, review budget, verification plan, and any size:exception rationale.
Anti-patterns
- ❌ Splitting by file type instead of work unit (models/views/controllers → weak split)
- ❌ Child PR diff includes parent's code (polluted diff → retarget/rebase)
- ❌ Mixing stacked-to-main and feature-branch in same chain
- ❌ Tracker PR merged before children are complete