Skip to content

fix: /ship Steps 7-8 not idempotent — re-run after partial failure corrupts VERSION and CHANGELOG #649

@LarHope

Description

@LarHope

Problem

/ship executes a multi-step sequence: version bump → changelog → commit → push → PR create. If Step 7 (git push) succeeds but Step 8 (gh pr create) fails (GitHub API outage, auth token expiry, rate limiting), re-running /ship corrupts state:

  • VERSION gets double-bumped (e.g., 0.13.5 → 0.13.6 on first run, then 0.13.6 → 0.13.7 on re-run)
  • CHANGELOG gets duplicate entries (same changes listed under two versions)
  • No way to safely resume from where it left off

The dangerous window is narrow (one step) but the blast radius is real — manual cleanup is required.

Why this matters

/land-and-deploy already handles partial failure well (Step 6 offers revert, Step 8 has full revert procedure with branch protection awareness). /ship doesn't apply the same rigor despite being the more frequently used skill.

Suggested fix

Make the critical section idempotent rather than building a rollback framework:

  1. Before push: check if branch is already pushed (git rev-parse @{u} or git ls-remote)
  2. Before PR create: check if a PR already exists for the branch (gh pr list --head <branch>)
  3. Before version bump: check if VERSION was already bumped in a prior run (compare against base branch)

This is ~10 lines of shell, not a new subsystem.

Reproduction

# 1. Run /ship on a feature branch
# 2. Simulate gh failure: revoke token or disconnect network after push
# 3. Re-run /ship
# 4. Observe: VERSION bumped again, CHANGELOG has duplicate section

Context

  • /land-and-deploy already handles this pattern (Steps 6, 7, 8 all have failure recovery)
  • Issue Claude cannot resume multi-step workflows across sessions #341 covers cross-session resume but not within-session partial failure
  • The agent IS the resume mechanism — but it can't safely resume if the steps aren't idempotent

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions