Receber por email
← Voltar para o catálogo

ship

This skill should be used when preparing a feature for production deployment. Enforces the lifecycle checklist: commit artifacts, update docs, capture learnings, create PR. Version bumping happens in CI.

14estrelas
Atualizado há 2 meses

Ver no GitHub ↗ Licença: NOASSERTION

Como adicionar

/plugin marketplace add jikig-ai/soleur

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/ship-jikig-ai/svg)](https://www.skillteca.com.br/skills/ship-jikig-ai)

Skills relacionadas

Ver todas de DevOps e Infra →

Alerta por categoria

Receba novas skills de DevOps e Infra toda segunda

1 email curto, só com as skills novas de DevOps e Infra. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

ship Skill

<!-- ship-merge-deploy-protocol:start -->

Merge → deploy protocol (load-bearing — especially Grok Build)

You own merge through production verification — never ask the operator to monitor.

  1. Phase 7: poll PR merge to MERGED (auto-merge queue, BEHIND sync, required-check failure exit).
  2. After merge: poll release/deploy workflows on the merge commit to completed + success.
  3. Step 3.8: invoke /postmerge <PR-number> (Grok) or soleur:postmerge (Claude) before Step 4 cleanup.
  4. FORBIDDEN: Ending the session at merge, at a red release run you did not investigate, or with "want me to watch CI?"
  5. Harness polling: plugins/soleur/lib/harness.ts → pollInstructions() — Claude uses Monitor tool; Grok uses AwaitShell (pattern for MERGED, BEHIND detected, auto-sync.*pushed, postmerge verification complete) or blocking Shell with block_until_ms.
  6. BEHIND stop-and-sync: When mergeStateStatus is BEHIND, stop CI-only polling and resync before continuing. Grok/ad-hoc polls: bash plugins/soleur/scripts/sync-pr-behind.sh <PR> from the feature worktree. Canonical spec: plugins/soleur/lib/pr-merge-poll.ts.

See workflow-fidelity.ts (SHIP_MERGE_DEPLOY_SENTINEL, POST_MERGE_VERIFICATION_SKILLS) and wg-after-a-pr-merges-to-main-verify-all. <!-- ship-merge-deploy-protocol:end -->

Purpose: Enforce the full feature lifecycle before creating a PR, preventing missed steps like forgotten /compound runs and uncommitted artifacts. Version bumping is handled by CI at merge time via semver labels.

CRITICAL: No command substitution. Never use $() in Bash commands. When a step says "get value X, then use it in command Y", run them as two separate Bash tool calls -- first get the value, then use it literally in the next call. This avoids Claude Code's security prompt for command substitution.

Headless Mode Detection

If $ARGUMENTS contains --headless, set HEADLESS_MODE=true. Strip --headless from $ARGUMENTS before processing remaining args.

When HEADLESS_MODE=true:

  • Phase 2: auto-invoke skill: soleur:compound --headless (forward flag, no user prompt)
  • Phase 4: if test files are missing, continue without writing (CI gate catches this)
  • Phase 6: auto-accept generated PR title/body without user confirmation
  • Phase 7: if CI is flaky or unrelated check fails, abort pipeline (do not ask whether to proceed)
  • All failure conditions: abort with clear error message, do not prompt

Phase 0: Context Detection

Detect the current environment:

# Determine current branch and worktree
git rev-parse --abbrev-ref HEAD
git worktree list
pwd

Branch safety check (defense-in-depth): If the branch from the command above is main or master, abort immediately with: "Error: ship cannot run on main/master. Checkout a feature branch first." This is defense-in-depth alongside PreToolUse hooks -- it fires even if hooks are unavailable (e.g., in CI).

Trailer-parse verification gate (defense-in-depth for [hr-always-read-a-file-before-editing-it]). For every commit on this branch since origin/main, parse any Key: value-shaped lines in the body and confirm git interpret-trailers recognises each as a trailer. The modal failure is a blank line between an Allowlist-Widened-By:/Reviewed-by:/Signed-off-by: line and Co-Authored-By:, which silently demotes the upstream trailer into body prose and breaks downstream consumers parsing via git log --format='%(trailers:key=NAME,valueonly)':

# Scan the WHOLE body, but only for KNOWN trailer keys.
#
# Two wrong ways to scope this, both tried:
#   * Any `^Word: ` anywhere — flags ordinary prose ("Suites: 18/18",
#     "Note: …", "Runbook: …"), so the gate fails on almost every
#     well-written commit message. A gate that cannot pass gets routinely
#     ignored, which is worse than no gate: it trains the reader to walk
#     past red. Measured on PR #6727: 6 hits, all prose, while every
#     intended trailer parsed fine.
#   * Final paragraph only — VACUOUS for the exact class this gate exists
#     to catch. The modal failure is a blank line BEFORE `Co-Authored-By:`,
#     which leaves the orphaned trailer in the second-to-last paragraph
#     while the final paragraph stays a clean parseable block. Verified
#     vacuous against a synthetic demotion.
#
# The real signal is neither position nor shape: it is whether the key is
# one a downstream consumer actually reads. Prose keys are not. Extend this
# list when a new machine-read trailer is introduced.
KNOWN_TRAILER_KEYS='Co-Authored-By|Signed-off-by|Allowlist-Widened-By|Reviewed-by|Reviewed-By-Soleur|Reviewed-Coverage|Acked-by|Tested-by|Cc'
RC=0
for sha in $(git rev-list origin/main..HEAD); do
  BODY=$(git log -1 --format=%B "$sha")
  declare -a CANDIDATES=()
  while IFS= read -r line; do
    [[ "$line" =~ ^(${KNOWN_TRAILER_KEYS}):[[:space:]] ]] && CANDIDATES+=("${BASH_REMATCH[1]}")
  done <<< "$BODY"
  for key in "${CANDIDATES[@]}"; do
    val=$(git log -1 --format="%(trailers:key=${key},valueonly)" "$sha")
    if [[ -z "$val" ]]; then
      echo "[FAIL] ${sha:0:8}: '${key}:' is in the body but does not parse as a trailer." >&2
      echo "       Fix: git rebase -i, reword the commit to make the final paragraph a contiguous Key: value block." >&2
      RC=1
    fi
  done
done
exit $RC

If the gate fails, do NOT proceed — reword the offending commit(s) via git rebase -i (or git commit --amend if the failing commit is HEAD AND has not been pushed) so the final paragraph is a pure contiguous Key: value block. See knowledge-base/project/learnings/2026-05-16-git-trailer-parser-requires-contiguous-key-value-block.md and PR #4106.

Load project conventions:

if [[ -f "CLAUDE.md" ]]; then
  cat CLAUDE.md
fi

Identify the base branch (main/master) for comparison:

git remote show origin | grep 'HEAD branch'

Phase 1: Validate Artifact Trail

Check that feature artifacts exist and are committed. Look for files related to the current feature branch name:

Get the current branch name:

git rev-parse --abbrev-ref HEAD

Extract the feature name from the result by stripping the feat-, feature/, fix-, or fix/ prefix. Then search for related artifacts using the Glob and Bash tools:

  • Brainstorms: glob knowledge-base/project/brainstorms/FEATURE
  • Specs: check knowledge-base/project/specs/feat-FEATURE/spec.md
  • Plans: glob knowledge-base/project/plans/FEATURE
  • Uncommitted files: git status --porcelain knowledge-base/

If artifacts exist but are not committed: Stage and commit them.

If no artifacts exist: Note this in the checklist but do not block. Not all features go through the full brainstorm/plan cycle.

Phase 1.5: Review Evidence Gate

Check for evidence that /review ran on the current branch. This is defense-in-depth -- /one-shot already enforces review ordering, but direct /ship invocations bypass it.

Step 1: Check for review artifacts (legacy).

Search for todo files tagged as code-review findings that this branch introduced — refresh origin/main first, since the scoping is only as accurate as the cached ref:

if ! git fetch origin main >/dev/null 2>&1; then
  echo "origin/main is stale — Signals 1-2 are unreliable; use Signal 3 only" >&2
else
  git log origin/main..HEAD -G'code-review' --name-only --format= -- todos/ 2>/dev/null \
    | sort -u | while read -r f; do
        git show "HEAD:$f" 2>/dev/null | grep -q "code-review" && echo "$f"
      done | head -1
fi

This was a repo-global grep -rl "code-review" todos/, which made the signal structurally unfailable (#6724): todos/ is a tracked directory on main, so a single long-lived review todo anywhere in it satisfied Step 1 for every branch forever — including branches where review never ran.

Three details are load-bearing, each closing a narrower version of the same vacuity (all

Compartilhar X LinkedIn