bdfinst

ship

Run the full spec-to-merge pipeline as one command: spec, plan, small-batch build, code review, and a PR with auto-merge — pausing at the existing human gates. Idempotent per issue — a re-invocation for work already shipped or in-flight resumes/monitors instead of re-running the pipeline. Use when the user says "ship this", "take this feature end to end", "implement this issue", "we need to build", or wants the spec->plan->build->PR flow without re-assembling it each time.

bdfinst 298 35 Updated 3w ago
GitHub

Install

npx skillscat add bdfinst/agentic-dev-team/ship

Install via the SkillsCat registry.

SKILL.md

Ship

Role: orchestrator. This command chains the existing pipeline skills end to end; it
does not implement, review, or merge anything itself — each phase is delegated to the
skill that owns it, and the existing human approval gates are preserved.

You have been invoked with the /ship command.

Orchestrator constraints

  1. Delegate every phase. Call the owning skill (/specs, /plan, /build,
    /code-review, /pr); do not re-implement their logic here.
  2. Honor the human gates. Do not advance past a gate without explicit approval —
    this command sequences phases, it does not remove their review points.
  3. Confirm the approach first. Before planning, screen the request against
    ${CLAUDE_PLUGIN_ROOT}/knowledge/decision-defaults.md and confirm any ambiguous high-reversal-cost axis
    (replace-vs-merge, format fidelity, migrate-vs-edit-stub, scope) in one batch.
  4. Be concise. Report each phase's outcome and the next gate, nothing more.
  5. Agent-dispatch capability is a pipeline-wide precondition, enforced by the delegated skills, not duplicated here (issue #1461). /plan (Step 5b), /build (Steps 3, 4, 6), and /code-review (Step 4) each independently confirm the Agent/Task tool is present before dispatching any review agent, and each hard-fails — STOP, no self-applied review, no gate file written — when it is missing. /ship does not re-check or restate that logic; if a delegated phase halts on missing dispatch capability, /ship reports that halt and stops with it (per constraint 2, "Honor the human gates") rather than working around it or advancing past the phase that failed.
  6. Idempotent per issue. Never re-run the pipeline for an issue that is
    already shipped or in-flight. The Step 1 resume guard decides this from
    durable tracker/PR state — not conversation memory — so a re-fired command
    string (e.g. a ScheduleWakeup/loop prompt that repeats) lands on
    resume/monitor, not a second spec→plan→build→PR pass.

Parse Arguments

Arguments: $ARGUMENTS

  • Positional: the feature description (required).
  • --skip-spec: Skip the spec phase (use when a spec already exists for this work).
  • --no-auto-merge: Pass through to /pr so the PR is not set to auto-merge.
  • --force-restart: Bypass the Step 1 resume guard and re-run the pipeline from
    the start even when prior artifacts exist. Use only for a deliberate rebuild —
    it accepts the risk of duplicate spec issues, sub-issues, and PRs.
  • --issues <comma-separated-list>: dispatch this run as a batch covering
    every listed issue number, producing one shared spec, one shared plan, and
    one PR that closes every member issue. Mutually exclusive with treating
    $ARGUMENTS's positional feature description as a single-issue identifier —
    when --issues is given, the feature description still describes the
    batch's overall work, but the resume guard and every downstream phase
    operate over the full issue-number set, not one issue. Each token must be
    a bare issue number (^[0-9]+$ after trimming); reject the whole
    invocation with a clear error naming the offending token otherwise — never
    coerce or best-effort parse. Issue numbers are passed to gh as separate
    argv elements, never interpolated into a shell string. When --issues was
    given, <issue-identifier> for every iteration-journal-gate call in this
    run is the batch's stable key: the sorted member issue numbers joined as
    issues-<n1>-<n2>-... (e.g. issues-101-102-103) — used identically
    across every phase of this run, never re-derived differently per phase.

Workflow-state transitions (#1166)

At the start of each phase below (2-6), append one state-transition event so
/run-report and friends can derive dwell time per phase — never skip this
even when a phase resumes/monitors rather than running fresh:

python3 "${CLAUDE_PLUGIN_ROOT}/hooks/lib/workflow_state.py" record \
  --workflow ship --prior-state <PRIOR> --new-state <NEW> --session "$CLAUDE_SESSION_ID"

Map phases to canonical states: Spec→SPEC, Plan→PLAN, Build→BUILD,
Review→REVIEW, PR→PR (an extra COMMIT transition is optional — most
commits happen inside /build). Omit --prior-state only for the very first
transition of a run. This is a model-authored, fail-open append (same
convention as .claude/metrics/review-value.jsonl) — never let it block a phase.

Iteration journal gate (#1168)

Before advancing from one phase (2-6) to the next, append a structured
decision entry and confirm the gate allows advancement — a hard block,
distinct from the advisory, plan-step-keyed progress-guardian gate:

python3 "${CLAUDE_PLUGIN_ROOT}/hooks/lib/iteration_journal_gate.py" record \
  --round-id "<issue-identifier>" \
  --attempted "<short note: which phase just ran>" \
  --outcome "<short note: passed|failed|blocked>" \
  --next-action "<short note: next phase or stop>" \
  --session "$CLAUDE_SESSION_ID"

python3 "${CLAUDE_PLUGIN_ROOT}/hooks/lib/iteration_journal_gate.py" check \
  --round-id "<issue-identifier>" \
  --session "$CLAUDE_SESSION_ID"

<issue-identifier> is the same identifier the Step 1a resume guard resolves
(explicit issue number/URL, or feature slug) — or, when --issues was given,
the batch key defined in Parse Arguments (issues-<n1>-<n2>-...). If check
exits non-zero, do not advance to the next phase — retry record before
continuing.

Steps

1. Approach contract

1a. Resume guard — run before anything else

/ship is idempotent per issue. Before screening the approach or invoking
/specs, check whether this work has already been shipped or is in-flight,
so a re-invocation resumes or monitors instead of duplicating the spec issue,
the sub-issues, and the PR. Skip this guard only when --force-restart was
given (a deliberate rebuild).

Resolve the issue set from $ARGUMENTS: the explicit issue number(s)
(--issues list, or one number/URL), else stop and ask — the guard keys off
tracker/PR state, never off conversation memory, so a re-fired command
string (a ScheduleWakeup/loop prompt) lands on the same verdict. Then run the
deterministic guard (issue numbers are separate argv elements, validated
^[0-9]+$; the script rejects anything else):

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/ship_resume_guard.py" --issues <n1[,n2,...]>

It probes PR state (Closes #N bodies and issue-<N> / issues-<n1>-<n2>-...
head branches, cross-repo heads never qualify as /ship's own), issue state,
and spec/plan artifacts, and prints a JSON verdict plus the signal that
fired. Report the signal so the decision is auditable, then act:

verdict action
shipped Report the merged PR / closed issues and stop. No phase re-runs.
monitor Report the PR and gh pr checks <pr>. If BEHIND main, rebase onto main and hand back to its checks; otherwise wait on the open gate — a re-check timer follows `knowledge/long-run-waiting.md`. Do not re-enter spec→plan→build.
resume Continue from the earliest incomplete phase against the existing artifacts (--skip-spec when the epic exists; build onto the existing branch). Before writing any artifact that would duplicate one, AskUserQuestion to confirm resume-vs-restart.
partial-batch Some --issues members closed, others open, no own batch PR: halt, report which members closed and how, and AskUserQuestion whether to re-form the batch from the still-open members or halt.
batch-blocked A foreign open PR covers a member: halt the whole batch (no partial subset ships), post one comment on every member issue naming the in-flight PR — only if an equivalent /ship halt comment does not already exist (check first) — and take no further action this round.
first-run Proceed to the approach screen.
probe-failed Do not assume first-run: report the error and AskUserQuestion.

For a batch, the stable key is issues-<n1>-<n2>-... (sorted), as defined in
Parse Arguments.

1b. Approach screen

Once the guard confirms a genuine first run (or --force-restart was given),
screen the request against ${CLAUDE_PLUGIN_ROOT}/knowledge/decision-defaults.md. Surface any ambiguous
axis to the user in a single batch and get the answers before proceeding. Stop here if
a genuinely blocking ambiguity remains.

2. Spec (unless --skip-spec)

Invoke /specs for the feature. /specs runs the Ambiguity Resolution Protocol
before finalizing acceptance criteria — any finding classified requires-stakeholder-input
is surfaced to the human as a required answer, not an optional confirmation.
When --issues was given, /specs is invoked once for the whole batch's
combined feature description — one shared spec covering every member issue.
If /specs' own Scope Split Protocol determines the members describe
genuinely unrelated features, that split is /specs' existing human gate —
surface it and stop, rather than overriding it to force one spec.

These unresolved items ARE the human gate. Do not auto-approve past them, even in
non-interactive mode. The only exception is --skip-spec (when a reviewed spec already
exists). A spec that passed its consistency gate with undocumented assumptions is not
an approved spec.

Present the completed spec (Intent, Architecture, Acceptance Criteria, and Ambiguity
Log) for human review. Human gate — wait for approval before planning.

3. Plan

Invoke /plan with the (approved) spec. The plan decomposes the feature into vertical
slices with Gherkin scenarios and states the chosen stance on any decision-defaults
axis. Human gate — wait for plan approval before building.
When --issues was given, /plan is likewise invoked once for the whole
batch — one shared plan covering every member issue, never one plan per issue.

4. Build

Invoke /build to execute the approved plan in small per-behavior batches (code-first),
with inline review checkpoints and verification evidence. Do not proceed until the build reports a green
suite.

5. Review

First check whether /build's checkpoints already reviewed this exact change:

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/ship_review_gate.py" --files <the branch's changed files>

{"skip": true} means every applicable lens has a ledger pass at each file's
current content — skip the pass and say so in the Step 7 report (list the
cleared lenses). Anything else (including any doubt: no ledger, edited since,
unhashable file) runs the pass as below. --force-restart never skips.

Invoke /code-review over the changes and let its fix loop converge. Surface any
findings that need human judgment.

This dispatch deliberately omits --internal: /ship is a top-level,
human-typed command, and this Review phase is its pipeline's human-facing
quality gate, so /code-review writing its usual .dev-team-reports/code-review.md
report here is intentional — see knowledge/report-output-location.md's
"Report exception: /ship" section, not an unfixed oversight.

6. PR

Invoke /pr (passing --no-auto-merge only if it was given to /ship). /pr runs
the pre-PR quality gate, opens the PR, and — by default — enables auto-merge so it
lands once checks pass. Human gate — the PR is the final review artifact.

When --issues was given, the resulting PR body must carry one Closes #<N>
line per member issue — not just one — so merging it closes every batch
member. /pr's existing closing-keyword-lint guidance
(python3 "${CLAUDE_PLUGIN_ROOT}/scripts/pr_close_keyword_lint.py", see
skills/pr/SKILL.md) needs no change to support this: it already lints each
Closes #<N> line independently, so a batch PR body simply carries more of
them. /ship confirms the created PR body actually carries one such line
per member before reporting success; if any is missing, state the gap
explicitly rather than silently reporting the batch as shipped.

7. Report

Report the PR URL, the quality-gate result, and whether auto-merge is armed.

Notes

  • /ship is sequencing only: every gate, fix loop, and evidence requirement comes from
    the underlying skills. If any phase stops at a gate, /ship stops with it.
  • For a plan-only pass, use /plan; for build-only, use /build. /ship is for the
    whole loop in one invocation.
  • Re-invoking /ship for an issue that is already shipped or in-flight is safe:
    the Step 1 resume guard (1a) reports/monitors instead of re-running. Pass
    --force-restart only when a deliberate rebuild is intended.