pr-captain-merge

SkillDev tools

Captain-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.

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 --squash flag is one keystroke away from --merge
  • --admin bypasses 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

  1. Confirm the PR number (ask if missing).
  2. Confirm you're not on the PR's branch — captain merges from master or any non-PR branch.
  3. If you're going to use --principal-approved, confirm the principal has authorized in THIS conversation. Don't infer from history.
  4. 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:

  • --merge always (never --squash, never --rebase)
  • Branch protection respected by default
  • --admin only when --principal-approved flag 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> --approve in 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-merge once refactored) to create GitHub release + fleet notification.
  • Notify affected agents: /dispatch create --type master-updated --to <agent>
  • Notify cross-repo collaborators: /collaborate if relevant

Failure modes

  • CI failing: do NOT merge. Address the failure; restart from /pr-prep or 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 create afterward (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 --graph shows 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:

  1. paths: [] (intentionally empty) — no file-path auto-activation; universally discoverable for the captain but scoped out of worktree contexts.
  2. Name contains captain- — any reader sees scope in the skill listing.
  3. Runtime precondition — underlying agency/tools/pr-merge checks 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 merge
  • agency/tools/pr-merge — the underlying safe-merge tool
  • claude/hookify/hookify.block-raw-gh-pr-merge.md — hookify rule that blocks bare gh pr merge
  • agency/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