Skip to content

feat(stacking-prs)!: rename split-branch to stacking-prs and cover managing and landing stacks - #54

Merged
zpyoung merged 29 commits into
mainfrom
zpyoung/enhance-pr-stack
Oct 21, 2026
Merged

zpyoung merged 29 commits into
mainfrom
zpyoung/enhance-pr-stack

Conversation

@zpyoung

@zpyoung zpyoung commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Summary

split-branch only knew how to cut a big branch into layers. It's now stacking-prs and covers the whole life of a stack: splitting it, keeping it healthy while lower PRs get review fixes, and syncing it after each merge. The research behind it is in docs/quirk/explorations/2026-10-19-splitting-and-stacking-prs.md, and the specs are in docs/quirk/specs/2026-10-20-stacking-prs/.

  • SKILL.md is now a short router. It runs stack.sh to see where you are and sends you to references/split.md, references/manage.md, or references/land.md.
  • split.md keeps the old flow and adds off-ramps for plans deeper than 4 layers or diffs too small to split, a CI-filter preflight, native GitHub stack registration through gh stack link, a restack of the layers above a layer you split further, and a step that puts an existing PR back to draft once it isn't the bottom layer.
  • manage.md covers a review fix on a lower layer, a moved trunk, and a broken chain. The plan gets approved before anything is committed, backups are taken first, and the --update-refs rebase filters out the backup refs so they stay put.
  • land.md covers pre-merge checks and the post-merge sync, including a merged PR with several children and the fork case. The skill never merges anything itself.
  • scripts/stack.sh is new. It's read-only and prints the stack as JSON from GitHub (native stacks or the PR base chain), GitLab, or local ancestry, with warnings for forks, deep stacks, GitLab's retarget cap, CI filters that would skip layers, and layers checked out in other worktrees.
  • scripts/restack.sh is new. It replays one layer onto its new base after a merge: backup, rebase --no-update-refs --onto, verify, push with --force-with-lease --force-if-includes, then retarget the PR. Each failure has its own exit code.
  • The PR-size citations now point at LinearB 2026, Google, and Kudrjavets 2022, and the 0.5× test weight is described as a configurable default, since no study backs it.

Test Plan

  • python3 -m pytest -q -p no:cacheprovider passes on the branch tip. About 230 new tests across tests/test_stacking_prs_{skill,stack,restack,analyze}.py. stack.sh and restack.sh run against real temp repos with stubbed gh/glab.
  • Five adversarial review rounds with codex across correctness, spec compliance, and security/failure modes, plus a sixth that checked only the last fix. Every accepted finding was fixed with a test, and the sixth round found nothing.
  • I ran split, manage, and land as scenarios: a fresh agent followed only the skill docs against fixture repos and a stateful fake gh, and I checked each end state by hand. All three ended where they should.
  • Try /quirk:stacking-prs on a real two-layer stack on GitHub.

The full suite now takes 8 to 10 minutes. pytest-xdist with -n auto would help, but I didn't change the test config here.

Changelog

  • split-branch is renamed to stacking-prs and now covers splitting, managing, and landing stacked PRs. Invoke quirk:stacking-prs instead of quirk:split-branch. Size weighting can be tuned in .quirk/stacking-prs.json (per repo) or ~/.quirk/stacking-prs.json.

- Weight changed lines by file risk and review effort
- Add layered configuration, validation, and analyzer coverage
- Require goal confirmation and refresh stack headers after changes
- Document research on splitting and stacking PRs
Approved brainstorm design for reworking split-branch into a
full-lifecycle stacked-PR skill (split, manage, land).
… phase references

Renames the skill and its config file to stacking-prs, moves the split flow
to references/split.md, adds manage and land phases, fixes the size
citations, and adds trigger evals and a structure test.
…replay

stack.sh reads the stack from GitHub or GitLab, or from local ancestry, and
emits JSON with warnings. restack.sh replays one layer onto a new base with a
backup, a lease-protected push, and an optional retarget.
A branch sharing the bottom layer's name prefix (topic vs topic_extra) has
backups the old glob also matched, and a descending refname sort put them
first. The recovery now accepts only an exact YYYYMMDD_HHMMSS remainder.
Copilot AI balanced review requested due to automatic review settings October 20, 2026 20:38
@zpyoung zpyoung added the breaking Breaking change; release notes file it under BREAKING label Oct 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

- Bind forge operations to the configured remote and report incomplete listings
- Improve native, fork, merged-parent, and published-head detection
- Prevent unsafe rebases, pushes, retargets, and branch deletion
- Make diff analysis robust for unusual paths and encoding
- Expand regression coverage for stack and workflow edge cases
@zpyoung
zpyoung merged commit 38fbac7 into main Oct 21, 2026
2 checks passed
github-actions Bot added a commit that referenced this pull request Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking change; release notes file it under BREAKING

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants