| name | ship-pr |
| description | Run completed local work through PR delivery: audit changes, verify locally, commit, push, open PR, monitor CI, handle review comments, and finish green. After exact approval (`I approve merging PR #<N>`), merge the PR and clean up its source branch. Use `fix-ci` for failing PR checks. |
ship-pr
This is the PR lifecycle orchestrator.
It should:
- audit and commit any uncommitted changes
- push and create a PR
- monitor CI and fix failures
- wait for review comments
- address every feedback comment
- ensure CI passes at the end
Defaults
- Default base branch is the repository's default branch (usually
main).
- Default PR title and body are auto-generated from the branch name, commit history, and the work that was done.
- Default comment wait time is 15 minutes from PR creation.
- If explicit PR title, body, or base branch instructions are provided, use those instead of auto-generating.
Inputs
Accept any combination of:
- explicit PR title
- explicit PR body or description instructions
- explicit base branch
- explicit comment wait time (default 15 minutes)
- whether to skip the comment wait period
Required behavior
Delegate to:
audit-and-fix-uncommitted-changes for pre-commit quality gates
repair-checks for pre-push local verification when the current session has not already observed the repo-defined local lane passing after the latest changes
fix-ci for CI failure diagnosis and repair
address-pr-comments for review comment handling
Continuation rule
Sub-skill returns are intermediate, not terminal. After every delegation (audit-and-fix-uncommitted-changes, repair-checks, fix-ci, address-pr-comments), continue to the next numbered step in the same turn — the sub-skill's closing summary is not ship-pr's closeout. The most common failure is stopping after audit-and-fix-uncommitted-changes returns, before staging and commit happen.
The loop exits only at end of Phase 8, a listed human checkpoint, or a mirrored sub-skill checkpoint (e.g., fix-ci halting without pushing — Phase 3 step 3c, Phase 6 step 1c).
Global constraints
- Do not create a PR if the current branch is the default branch and there is nothing to ship.
- CI is not the first debugger: run the repo's local check lane before the initial push/PR, and use CI only to confirm parity after local verification.
- Do not let ship-pr push CI-fix commits unless
fix-ci found a local reproducer and observed it pass after the fix, or fix-ci hit a human checkpoint without pushing.
- Pre-push local verification must use the repo-documented CI-equivalent lane when one exists; do not silently downgrade to a fast lane.
- Do not skip CI checks.
- PR feedback handling must pass the
address-pr-comments definition of done before this skill completes.
- The skill must end with CI passing.
- Do not force-push unless explicitly instructed.
Human checkpoints
- Required: ask when the current branch is the default branch and there are no changes to ship (no uncommitted changes, no commits ahead of the remote, and no non-default branch to PR).
- If the working tree has no uncommitted changes but the current branch is not the default branch, proceed — the user is asking for a PR of the branch's commits.
- Required: ask when PR creation fails due to an existing PR or branch conflict.
- Required: ask when CI failures persist after 3 fix-ci iterations.
- When a checkpoint involves a genuine tradeoff between substantive alternatives, present at least two options with brief pros and cons, state which you recommend and why, and let the human decide.
- Stay autonomous during normal commit, push, PR creation, CI monitoring, and comment handling.
Orchestration loop
Phase 1: Prepare and push (Committer)
- Determine the current branch and the repository's default branch.
- Run
git status --porcelain to check for uncommitted changes.
- If uncommitted changes exist and the current branch is the default branch:
a. Create a new branch with a descriptive name derived from the changes (e.g.,
feat/add-widget-support or fix/null-pointer-in-parser).
b. Switch to the new branch before continuing.
- If uncommitted changes exist:
a. Use the
audit-and-fix-uncommitted-changes skill to stabilize the working tree.
b. Stage all changes: git add -A
c. Craft a commit message that describes the work done.
d. Commit the changes.
- If no uncommitted changes exist and the current branch is not the default branch, proceed — the branch's existing commits are the content to ship.
- If no uncommitted changes exist and the current branch is the default branch, trigger a human checkpoint — there is nothing to ship.
- Run or delegate to
repair-checks for the repo-defined local check lane unless the current session already observed that lane passing after the latest branch changes.
- If local verification changes files:
a. Use
audit-and-fix-uncommitted-changes to stabilize those changes.
b. Stage all changes: git add -A
c. Commit the local-check fixes.
d. Re-run the repo-defined local check lane.
- Push the branch to the remote.
Phase 2: Create the PR (PR creator)
- Check if a PR already exists for the current branch using
gh pr view.
- If no PR exists:
a. Auto-generate the PR title from the branch name and commit history, unless explicit title was provided.
b. Auto-generate the PR body summarizing what was done, unless explicit body was provided.
c. Create the PR:
gh pr create --title "<title>" --body "<body>" --base <base-branch>
- If a PR already exists, use that PR.
- Record the PR number/URL and the current time as
start_time.
Phase 3: Wait for CI and fix failures (CI monitor)
- Poll CI status using
gh pr checks <pr-number>.
- Wait for all CI checks to complete.
- If any CI check failed:
a. Use the
fix-ci skill, passing the PR number.
b. The fix-ci skill handles the internal loop of diagnose, fix, audit, commit, push, re-check.
c. Confirm fix-ci satisfied its local-reproducer definition of done; if it stopped at a human checkpoint, stop here too.
- CI must be passing before proceeding.
Phase 4: Wait for review comments (Timer)
The review-comment wait timer starts at PR creation (start_time from Phase 2). Time spent waiting for CI in Phase 3 counts toward this timer.
- Calculate elapsed time since
start_time.
- If less than 15 minutes (or the configured wait time) have elapsed, wait for the remaining time.
- If the wait time has already elapsed (e.g., CI took longer than the wait period), proceed immediately.
Phase 5: Address PR comments (Comment handler)
- Use the
address-pr-comments skill, passing the PR number.
- If it reports no feedback comments, proceed.
- If it addressed comments, continue with CI verification before closing.
Phase 6: Final CI verification (CI monitor)
- If changes were pushed in Phase 5:
a. Wait for CI to complete.
b. If CI fails, use the
fix-ci skill again.
c. Confirm fix-ci satisfied its local-reproducer definition of done; if it stopped at a human checkpoint, stop here too.
d. Repeat until CI passes.
- Confirm CI is green.
Phase 7: Audit comment coverage (Comment auditor)
Independently verify that address-pr-comments reached its definition of done.
Do not trust the sub-skill output alone — re-fetch the PR state and validate.
- Re-fetch PR comments, review comments, and review bodies.
- Verify the
address-pr-comments definition of done against the fetched PR state.
- If any feedback comment fails that definition, run
address-pr-comments again with the flagged comments, then repeat this audit.
- Only proceed when every feedback comment passes the
address-pr-comments definition of done.
Phase 8: Close the run (Reporter)
- Confirm:
- CI is passing
- every comment has a reply that passes the Phase 7 audit
- all changes are committed and pushed
- Summarize the PR lifecycle outcome.
- Tell the user the exact phrase required to authorize merge (Phase 9). For example:
Reply "I approve merging PR #<N>" to merge this PR and delete the source branch.
Phase 9: Merge — only on explicit human authorization
This phase does not run automatically. After Phase 8 the skill stops and waits.
Authorization trigger. The agent may merge the PR only when the user replies with the exact phrase I approve merging PR #<N> (case-insensitive), where <N> is the exact PR number for this run. No other wording — "approved", "looks good", "merge it", "ship it", a thumbs-up, etc. — counts as authorization. If the user uses a similar but non-matching phrase, ask them to issue the exact phrase rather than inferring intent. If the PR number in the user's message does not match the PR for this run, refuse the merge and tell the user which PR number the skill is operating on. Authorization is single-use and scoped to the PR number it names.
Merge steps (after authorization):
- Re-verify the PR is mergeable and CI is still green:
gh pr view <N> --json mergeable,mergeStateStatus,state.
- Determine the merge method without guessing:
a. Run
gh repo view --json mergeCommitAllowed,rebaseMergeAllowed,squashMergeAllowed,viewerDefaultMergeMethod.
b. If exactly one method is allowed, run gh pr merge <N> with that explicit flag (--merge, --rebase, or --squash).
c. If multiple methods are allowed and viewerDefaultMergeMethod names one of them, run gh pr merge <N> with the matching explicit flag.
d. If multiple methods are allowed and no explicit default method is available, stop and ask the user to choose one of the allowed methods. Do not infer a method from branch names, commit history, or personal preference.
- Do not pass
--admin. Do not bypass branch protections. If the merge fails, surface the error and stop. Do not retry destructively.
Post-merge cleanup (after a successful merge):
- Fetch PR head metadata:
gh pr view <N> --json baseRefName,headRefName,headRepository,headRepositoryOwner,isCrossRepository,state.
- Switch to the base branch and update it:
git checkout <base> && git pull.
- Delete the local branch:
git branch -d <branch>. If -d refuses, re-confirm the PR is merged via gh pr view <N> --json state before considering -D; never force-delete an unmerged branch.
- Delete the remote branch only after mapping the PR head repository to a local git remote. Use
git remote -v to find the remote whose fetch or push URL matches headRepository; if no remote maps unambiguously, stop and report the unmapped head repository instead of deleting from origin by assumption.
- Delete the mapped remote branch:
git push <remote> --delete <headRefName>. If git ls-remote --heads <remote> <headRefName> shows it is already gone (e.g., GitHub auto-deleted it), skip this step.
- Verify the branch is gone:
- Local:
git branch --list <branch> returns no output.
- Remote:
git ls-remote --heads <remote> <headRefName> returns no output.
Never delete the repository's default branch under any circumstances, regardless of what the user says.
Guardrails
- Do not skip the audit-and-fix step before committing.
- Do not end with CI failing.
- Do not force-push or rewrite history unless explicitly instructed.
- Do not create duplicate PRs.
- Do not merge the PR unless the user issues the exact authorization phrase
I approve merging PR #<N> with a number that matches this run's PR.
- Never delete the repository's default branch.
Definition of done
- A PR exists for the current branch and
gh pr checks shows every required CI check passing on the final pushed commit.
- The repo-defined local check lane passed before the first push/PR, and CI-fix commits were not pushed without a local reproducer and passing post-fix local verification.
address-pr-comments reached its definition of done, and Phase 7 independently verified that result by re-fetching the PR state.
- The skill did not force-push, did not create a duplicate PR, and did not end with CI failing.
- The skill ends after Phase 8 with the PR open and green unless the user issues the exact authorization phrase
I approve merging PR #<N>; in that case the PR is merged with an explicit, unambiguous GitHub merge method and the source branch is deleted both locally and remotely.
Final handoff
After the run:
- Echo the PR URL.
- Summarize: what was committed, local verification run before push, CI status, comments addressed.
- For any CI fixes, summarize the
fix-ci local-reproducer evidence.
- State whether all comments passed the Phase 7 audit or if any require further human attention.
- If any comments were re-addressed during the audit, list them and explain what was corrected.
- State the exact phrase required to authorize merge:
I approve merging PR #<N> with this PR's number. If the user has not issued it, do not merge.
- If a merge was performed, report the merge outcome and confirm both local and remote branch deletion succeeded.