pr-captain-merge
SkillDev toolsCaptain-only. Merge a PR safely, true merge commit (never squash, never rebase), branch protection respected, --principal-approved gate for --admin override. Prevents the "accidentally squashed via the wide GitHub UI button" failure mode that has burned the fleet.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the pr-captain-merge skill
What this skill tells your AI
The instructions your AI receives, as published by the-agency-ai/the-agency in .claude/skills/pr-captain-merge/SKILL.md and read by ahel’s review.
pr-captain-merge
Captain's safe wrapper for merging PRs on GitHub. Always a true merge commit (no squash, no rebase). Respects branch protection by default. --principal-approved is the only way to engage --admin override.
Name pattern: pr- prefix groups with the PR skill family (autocomplete /pr<tab> shows the full kit), captain- qualifier makes captain-only scope visible at a glance.
Why this exists
Raw gh pr merge is too easy to misuse:
- GitHub's UI nudges toward squash (the wide button)
- The
--squashflag is one keystroke away from--merge --adminbypasses branch protection silently- Without discipline, the captain shipped 4 squash merges in one day (pre-v2 incident)
pr-captain-merge is the gate — skill-level enforcement plus the underlying agency/tools/pr-merge tool that does the actual work.
Required reading
Before running, Read the files in required_reading: frontmatter. GIT-MERGE-NOT-REBASE.md explains why we never squash or rebase. SAFE-TOOLS.md covers the safe-tool family this skill composes.
Usage
/pr-captain-merge <pr-number>
/pr-captain-merge <pr-number> --principal-approved
/pr-captain-merge <pr-number> --delete-branch
/pr-captain-merge <pr-number> --dry-run
Preconditions
- Captain is on master in main checkout. Not in a worktree.
- PR number is known. Captain has verified PR is not in draft.
- CI has passed (or deploy-preview flake is understood and ignored).
- Principal has approved — either via GitHub review OR verbally in this conversation.
- For
--principal-approved: the principal's authorization is in THIS conversation. Do not infer from prior sessions.
If any precondition is missing, STOP. Ask the principal to resolve, or use the non-approved path and let branch protection block.
Flow / Steps
Step 1: Pre-flight
- Confirm the PR number (ask if missing).
- Confirm you're not on the PR's branch — captain merges from master or any non-PR branch.
- If you're going to use
--principal-approved, confirm the principal has authorized in THIS conversation. Don't infer from history. - Check for pending post-merge (C#372 Fix B). Run
./agency/tools/post-merge-state check. If exit 1, STOP — a prior PR was merged but its release hasn't been cut yet. Run/pr-captain-post-merge <pending-PR>first, then re-invoke this skill. New work cannot start while a prior PR is in pending state. Exit 0 → continue.
Step 2: Invoke the tool
./agency/tools/pr-merge <N>
Or with explicit principal approval (only when they verbally OK'd in-session):
./agency/tools/pr-merge <N> --principal-approved
Tool enforces:
--mergealways (never--squash, never--rebase)- Branch protection respected by default
--adminonly when--principal-approvedflag is present
Step 3: Handle the outcome
On success (exit 0): report merge URL + next-step recommendation (sync master via ./agency/tools/_sync-main-ref, or wait for /pr-captain-post-merge).
On branch-protection block (exit 3): tool prints the gate. Two resolutions:
- Ask principal to
gh pr review <N> --approvein GitHub UI, then re-run. - If principal authorized in this conversation but not GitHub UI, re-run with
--principal-approved.
On merge conflict (exit 1): resolve locally first:
gh pr checkout <N>
./agency/tools/git-safe merge-from-master --remote
# resolve conflicts
./agency/tools/git-safe add <files>
./agency/tools/git-captain merge-continue
./agency/tools/git-push <branch>
# then retry
/pr-captain-merge <N>
Step 4: Post-merge (handoff or chain)
After successful merge:
- Sync local master:
./agency/tools/_sync-main-ref - If release PR: run
/pr-captain-post-merge(or/pr-captain-post-mergeonce refactored) to create GitHub release + fleet notification. - Notify affected agents:
/dispatch create --type master-updated --to <agent> - Notify cross-repo collaborators:
/collaborateif relevant
Failure modes
- CI failing: do NOT merge. Address the failure; restart from
/pr-prepor captain's diagnosis. - Merge conflicts on agent's branch: sent back for agent to resolve. Captain doesn't resolve agent's conflicts.
- Principal-approved flag without in-conversation authorization: DO NOT PASS. Ask the principal explicitly; wait for their OK; then pass the flag. Captain attests to something real.
- Squash or rebase attempted: blocked by tool. No way in the skill to request.
What this does NOT do
- Does not write commits — merge happens server-side at GitHub.
- Does not delete the local branch — that's captain's next decision (or
/pr-captain-post-merge). - Does not auto-tag a release — explicit
gh release createafterward (or via/pr-captain-post-merge). - Does not push — merge is server-side; no local push.
- Does not squash, does not rebase — blocked by the underlying tool (
agency/tools/pr-merge).
Why never squash, never rebase
Both rewrite history. The-agency framework is built on visible, append-only history:
- Branch commits are individually meaningful (QGRs, fixes, version bumps)
- Merge commits create a permanent record of integration
git log --graphshows the actual flow- Bisecting works against real commits, not synthetic squash blobs
Cost: heavier git log output. Benefit: you can SEE what happened and WHY, which is essential when fleet agents and adopters all have to read the same history.
Captain-only — three-layer defense
Defense in depth against accidental invocation from the wrong context:
paths: [](intentionally empty) — no file-path auto-activation; universally discoverable for the captain but scoped out of worktree contexts.- Name contains
captain-— any reader sees scope in the skill listing. - Runtime precondition — underlying
agency/tools/pr-mergechecks caller context before engaging--admin.
(Historically disable-model-invocation: true was a fourth layer. That flag was removed 2026-04-20 because the captain session IS the principal's session — DMI was blocking the captain from invoking captain-* skills. See REFERENCE-SKILL-CONVENTIONS.md §1.)
Status
active — ships as of agency-skill-version 2 adoption 2026-04-19. Replaces v1 pr-merge skill.
Related
/pr-captain-land— the local-first landing flow; calls this as its Step 8 merge, on a_land-<branch>head/pr-prep— the QG-before-PR-create (agent-side)/pr-submit— agent hands branch to captain for landing/pr-captain-post-merge(TBD refactored to/pr-captain-post-merge) — release + fleet-notify after mergeagency/tools/pr-merge— the underlying safe-merge toolclaude/hookify/hookify.block-raw-gh-pr-merge.md— hookify rule that blocks baregh pr mergeagency/REFERENCE/REFERENCE-GIT-MERGE-NOT-REBASE.md— the discipline rationale- the-agency#296 — PR lifecycle ownership (the-agency direction)
- the-agency#298 — skill refactor recommendation (the methodology)
OFFENDERS WILL BE FED TO THE — CUTE — ATTACK KITTENS!
Signals
- GitHub stars
- 55
- Forks
- 8
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
pr-captain-merge- Source
- github.com/the-agency-ai/the-agency