Skip to content
Back to skills

Ship

ASecurity

Commit, push, create PR(s), and auto-finalize — full automation pipeline. Handles uncommitted changes and recently created PRs.

  • 3 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 19, 2026
ai-agentsrustgobashcode-reviewgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add dryvist/claude-code-plugins --skill ship --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ship?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ship
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dryvist-ship/badge)](https://www.skillsdirectory.com/skills/dryvist-ship)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ship
description: >-
  Commit, push, create PR(s), and auto-finalize — full automation pipeline.
  Handles uncommitted changes and recently created PRs.
allowed-tools: Bash(git *), Bash(gh *), Bash(pre-commit *), Bash(npm run lint*), Bash(make lint*), Agent, Read, Grep, Glob, Skill
---

# Ship

**Single command to commit, push, create PR(s), and auto-finalize everything.**
Handles commit, push, PR creation, and `/finalize-pr` in one pipeline.

> ⛔ **NOT RESUMABLE — run from Step 0 on every `/ship` invocation.**
> Do not refer to "the PR I just finalized" or "already verified" from
> any earlier message in this session — those are stale snapshots.
> The world changes between invocations: CodeQL completes async, required
> reviewers post async, Renovate force-pushes, branch protection
> re-evaluates. Re-run everything from Step 0.

## Rate Limit Awareness

This skill orchestrates many downstream API calls via `/finalize-pr`,
which itself invokes `/resolve-codeql`, `/resolve-pr-threads`, `/simplify`,
and metadata updates. To avoid API rate limit errors:

- **Process PRs sequentially** — never dispatch parallel subagents for multiple PRs
- **Allow `/finalize-pr` to manage its own internal concurrency** — it can
  run its fixes in parallel since they're scoped to a single PR
- **Pause after PR creation** — `sleep 2` after `gh pr create` to let GitHub index

## Step 0: Verify Working Directory

Before anything else, confirm the working directory is valid:

```bash
git rev-parse --git-dir 2>/dev/null
```

**If this fails** (exits non-zero or the current directory doesn't exist), stop immediately
and report: "Working directory is not a git repository. This usually means the worktree was
cleaned up after a PR merge. Start a new session and create a worktree using `/superpowers:using-git-worktrees` to continue working."

Do NOT attempt to recover, cd elsewhere, or fall through to Step 1.

## Step 1: Detect Scope

Identify all PRs that need finalization.

### 1.1 Check for Uncommitted Changes

```bash
git status --porcelain
```

**If changes exist** (staged or unstaged), execute inline:

0. **Claim check** (session-coordination rule): before creating a new PR,
   search for a competing claim — an open PR (draft or ready) from another
   session covering the same issue or files:

   ```bash
   gh pr list --state open --json number,title,isDraft,headRefName,body
   ```

   If one exists, do NOT create a duplicate: stop, report the competing PR,
   and offer consolidation (comment with your session id; earliest claim
   wins). Otherwise continue.
1. Create branch if on the default branch (see /gh-cli-patterns Canonical
   Default-Branch Detection): `git checkout -b {type}/{sid8}-{description}`
   (derive from changes; `{sid8}` = session id per session-coordination)
2. Stage changes: `git add <relevant files>` (no `-A` — be selective)
3. Commit with conventional commit message: `git commit -m "type: description"`
4. **Simplify**: Invoke /simplify on all changes in the commit. If /simplify produces
   changes, stage them and amend the commit (`git commit --amend --no-edit`) — keep
   clean history for the first push.
5. **Validate locally**: Run project linters/tests if available (check for `pre-commit run --all-files`,
   `npm run lint`, `make lint`, etc.). If failures are found, fix them and amend the commit.
   Skip this step if no lint command is discoverable.
6. Push: `git push -u origin HEAD`
7. Create PR: `gh pr create --fill` (or with title/body derived from commit).
   Include the session id (`<runtime>-<host>-<8hex>`) in the PR body.
8. **Pacing**: Run `sleep 2` after `gh pr create` to allow GitHub to index the PR
9. Capture PR number from output (look for `pull/NUMBER` pattern)
10. Add it to the PR list

**If no changes**: Skip to 1.2.

### 1.2 Scan for Recently Created/Mentioned PRs

Check conversation context for PR numbers that were recently created or mentioned.
Also check the current branch:

```bash
gh pr view --json number --jq '.number' 2>/dev/null || true
```

Add any found PRs to the list.

### 1.3 Deduplicate

Remove duplicate PR numbers from the combined list (Step 1.1 + Step 1.2).

**If list is empty**: Report "Nothing to ship — no uncommitted changes and no open PRs
on this branch." and stop.

## Step 1.5: Build Context Brief

Before dispatching any finalization agents, construct a **context brief** that will
be included in every subagent prompt. This is critical — without it, subagents
resolving PR review threads will blindly follow reviewer suggestions instead of
making informed decisions about whether feedback is correct.

The context brief must include:

1. **What was built and why** — summarize the changes and their purpose from
   the conversation history (the user's original request, the problem being solved)
2. **Key decisions made** — any architectural choices, trade-offs, or deliberate
   patterns chosen during implementation (e.g., "chose X over Y because Z")
3. **Intentional patterns** — things that might look wrong but are correct
   (e.g., "the empty catch block is intentional because the caller handles errors")
4. **Scope boundaries** — what is explicitly out of scope for this change

Format as a concise block (aim for 10-20 lines):

```text
## Context for PR #<PR_NUMBER>
**Purpose**: [1-2 sentence summary of what and why]
**Key decisions**:
- [decision 1 and rationale]
- [decision 2 and rationale]
**Intentional patterns**:
- [pattern that reviewers might question]
**Out of scope**: [what this PR deliberately does not address]
```

This brief is passed verbatim to each `/finalize-pr` subagent in Step 2.

## Step 2: Finalize PRs

### Single PR (1 PR in list)

Invoke `/finalize-pr <PR_NUMBER>` directly via the Skill tool — no subagent needed.
The context brief from Step 1.5 is already in session context and will be available
when `/finalize-pr` invokes `/resolve-pr-threads`.

> [!IMPORTANT]
> If the repo uses Git Flow (default branch is `develop`), once the feature PR is
> merged into `develop` and validated, you must promote `develop` to `main` using
> `/promote-release`. Add a reminder to the active session checklist to perform
> this merge before completing the session.

### Multiple PRs (2+ PRs in list)

Process PRs **sequentially** — invoke `/finalize-pr` for each PR one at a time
via the Skill tool. Wait for each to complete before starting the next. This
prevents API rate limit errors from overlapping finalization cascades.

For each PR in the list:

1. Invoke `/finalize-pr <PR_NUMBER>` via the Skill tool
2. Record the result (ready / blocked / needs-human)
3. Proceed to the next PR

### What `/finalize-pr` handles

- CodeQL violation resolution
- Review thread resolution (via `/resolve-pr-threads` → `superpowers:receiving-code-review`)
- Merge conflict resolution
- CI failure fixes
- Code simplification (via `/simplify`)
- PR metadata updates

**Do NOT run `/resolve-pr-threads` separately** — `/finalize-pr` already invokes it
internally. Running both causes race conditions on GraphQL mutations and git pushes.

### Human-review gate

**Requesting a human — `main`-targeted PRs only.** When a PR targeting `main` needs
a human before merge — you are not confident enough, or merging would cut a release
you are not authorized to trigger — apply the label and report it instead of
merging. This is the sanctioned way to ask for a human:

```bash
gh pr edit <PR_NUMBER> --add-label "human:review"
```

Never apply it to a `develop`-targeted PR: merges into `develop` are always
AI-initiated, so there is nothing to request there.

**Never merging a labelled PR — unconditional.** `/ship` never merges a PR carrying
`human:review`, whatever its base branch, without an explicit same-session user
instruction to merge THAT PR. The scoping above governs where you may *apply* the
label, not whether to honor one already present: a label on a `develop` PR means a
human put it there deliberately, and this gate fails closed. See pr-standards
(github-workflows) → Human-Review Gate.

## Step 3: Aggregate Results

Wait for all `/finalize-pr` agents to complete.

**Before printing any PR as "Ready to merge": re-verify live state.**

Subagent self-reports from Step 2 are snapshots — not current truth. For each PR
that Step 2 reported as ready, run both gates from /gh-cli-patterns
against `<PR_NUMBER>`:

- **Gate 1**: Canonical PR-readiness gate (`mergeStateStatus` MUST be `CLEAN` or `HAS_HOOKS`)
- **Gate 2**: Canonical code-scanning alert count (must be `0` — NOT included in `statusCheckRollup`)

Abort conditions: `state` ≠ `OPEN`, `mergeable` ≠ `MERGEABLE`,
`mergeStateStatus` ≠ `CLEAN`/`HAS_HOOKS`, `isDraft` = `true`,
any `reviewThreads.isResolved` = `false`,
`reviewThreads.pageInfo.hasNextPage` = `true` (>100 threads — paginate manually),
`reviewDecision` = `CHANGES_REQUESTED`/`REVIEW_REQUIRED`,
`statusCheckRollup.state` ≠ `SUCCESS`, or CodeQL count > 0.

If any abort condition hits: re-invoke `/finalize-pr <PR_NUMBER>`, wait for completion,
then re-run both gates. Only list a PR as "Ready to merge" after both gates pass.

### Post validation evidence (agent-validated)

After both gates pass for a PR, record the evidence (commit status +
`validated:*` label mirror) so a later session can trust the change
without re-verifying (refs dryvist/ai-assistant-instructions#749). The
commit status is machine truth, bound to the exact head SHA; the label is
only a human-visible mirror and goes stale on new commits. Exact commands:
[references/validation-evidence.md](references/validation-evidence.md).

Then emit the **Canonical PR Status Summary** as defined in /gh-cli-patterns, titled
`Ship Summary`. Affected repos = current repo. Fetch each PR's full URL via:

```bash
gh pr view <PR_NUMBER> --json url --jq '.url'
```

Section 1 lists the PRs targeted by this `/ship` invocation. Section 2 lists all open
PRs in the current repo (including unrelated ones).

## Examples

```text
# Ship uncommitted changes (commit + PR + finalize)
/ship

# Ship when PR already exists on current branch
/ship

# Multi-PR: uncommitted changes create new PR, existing PR also finalized
/ship
```

## Related Skills

- finalize-pr (github-workflows) — invoked by ship to drive each PR to mergeable state
- merge-pr (github-workflows) — merge a PR after ship reports it ready
- resolve-pr-threads (github-workflows) — invoked internally via finalize-pr to resolve review threads
- gh-cli-patterns (github-workflows) — canonical gh CLI command shapes, placeholder convention, PR gate, code-scanning query
- pr-standards (github-workflows) — the Human-Review Gate policy: when to apply `human:review` and the absolute no-merge-without-instruction rule
- git-flow-next (git-workflows) — Dedicated git-flow-next guide, worktree setup, and promotion steps

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…