Stack Maintenance

SkillDev tools

Maintains dependent GitHub PR stacks. Use for restacking, repairing PR bases, or coordinating stack merges and merge queues.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Stack Maintenance skill

What this skill tells your AI

The instructions your AI receives, as published by edmundmiller/dotfiles in skills/catalog/stack-maintenance/SKILL.md and read by ahel’s review.

Keep stacked GitHub pull requests boring: map the real stack, act from the bottom, verify after every remote action, and rewrite branches only with a lease.

Use this skill for PR chains, dependent branches, branch retargeting, merge queues, stale parent branches, and review/merge triage. Prefer existing stack tools (gh stack, gh pr stack, jj spr) when the repository has them; fall back to plain gh and git only after confirming the tool is unavailable or insufficient.

Rules From Prior Stacked PR Incidents

  • Trust fresh GitHub metadata, not memory. Fetch baseRefName, headRefName, mergeStateStatus, mergeable, reviewDecision, checks, and auto-merge state before acting.
  • For evidence, compare against the PR head from GitHub (headRefOid or origin/<headRefName> after fetch), not just a local branch; local branches can be stale.
  • Stacked PRs usually merge bottom-up. A child can become conflicted after its parent merges; expect to rebase or retarget it before merging.
  • mergeable and CLEAN mean mergeable into the current baseRefName, not necessarily into main. Report the base explicitly in triage.
  • Do not recommend gh pr merge for a PR whose base is another stack branch unless the intent is to merge into that parent branch; otherwise retarget or wait for the parent to land first.
  • gh pr merge --auto --squash can merge immediately for intermediate stack branches. Re-read the PR afterward; do not infer from command text.
  • Main may use a merge queue. If GitHub says the merge strategy is controlled by the queue, retry without an explicit strategy, then re-read state, mergedAt, and mergeCommit.
  • Do not approve a PR before reviewing its diff and running the relevant local check. "Clean" only means mergeable, not reviewed.
  • Use --delete-branch=false for stack branches unless the user explicitly asks to prune. Other PRs may still depend on them.
  • Use git push --force-with-lease, never plain force, after rebasing a PR branch.
  • Stop before rewriting someone else's branch unless ownership and permission are clear.

Map The Stack First

Start with the current checkout and remote state:

git status --short --branch
git fetch origin --prune

List open PRs with the fields that matter:

gh pr list --state open --limit 100 \
  --json number,title,author,baseRefName,headRefName,isDraft,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url

Classify PRs into four buckets:

  1. Merge candidates: non-draft, MERGEABLE, CLEAN, no failing checks, not CHANGES_REQUESTED.
  2. Review candidates: clean but unapproved; inspect before approving.
  3. Stack repair: wrong base, conflicted, stale parent, or child branch blocked by a parent merge.
  4. Leave alone: draft, changes requested, branch owned by someone else, or unclear intent.

For a focused PR, inspect the exact relationship:

gh pr view <n> --json number,title,author,baseRefName,headRefName,headRefOid,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url

Merge Or Queue Safely

Merge bottom-up. After each merge, re-read the next child because the base may have changed.

For intermediate stack branches:

gh pr merge <n> --auto --squash --delete-branch=false

For a main-branch PR with merge queue behavior:

gh pr merge <n> --auto --delete-branch=false

Verify immediately:

gh pr view <n> --json number,state,mergedAt,mergedBy,mergeCommit,mergeStateStatus,autoMergeRequest,url,title

If the command reports an error that implies a race, stale base, or already-merged PR, re-read the PR before retrying. GitHub may have completed the merge while the CLI reported a confusing GraphQL error.

Review Before Approval

For a clean but unapproved PR:

gh pr diff <n> --name-only
gh pr diff <n> --patch

Run the smallest relevant check in a clean checkout or temporary worktree. Approve only after the diff and check match the intended change:

gh pr review <n> --approve --body "Reviewed diff and validated with <command>."

Then merge or queue it using the rules above.

Repair A Conflicted Child

Prefer stack tooling when available:

gh stack view
gh stack sync
gh stack submit

If using plain Git, repair in a throwaway worktree:

pr=123
base_branch=parent-branch
head_branch=child-branch
git fetch origin "$base_branch" "$head_branch"
tmp=$(mktemp -d "/tmp/pr${pr}.XXXXXX")
git worktree add -B "fix-pr${pr}" "$tmp" "origin/$head_branch"
cd "$tmp"
git rebase "origin/$base_branch"

Resolve conflicts, choosing the final intended content rather than mechanically taking either side:

git status --short
git add <file>
git rebase --continue

Run the relevant check. Push back with a lease:

git push --force-with-lease origin "fix-pr${pr}:$head_branch"

Re-read the PR. Merge only when it returns to MERGEABLE and CLEAN.

Clean temporary worktrees after use:

git worktree remove --force "$tmp"

Retarget Wrong Bases

If the commits are correct but the PR targets the wrong parent:

gh pr edit <n> --base <correct-base-branch>
gh pr view <n> --json number,baseRefName,headRefName,mergeable,mergeStateStatus,url

If retargeting introduces conflicts, repair the branch against the new base before merging.

Done Criteria

  • Every acted-on PR has fresh gh pr view evidence after the action.
  • Merged PRs show state: MERGED, mergedAt, and a merge commit.
  • Queued PRs show auto-merge or merge-queue state expected by the repository.
  • Rewritten branches were pushed with --force-with-lease.
  • Local temporary worktrees are removed.
  • Final report lists merged, queued, repaired, and intentionally skipped PRs separately.

Signals

GitHub stars
80
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
stack-maintenance
Source
github.com/edmundmiller/dotfiles