-
Notifications
You must be signed in to change notification settings - Fork 8.7k
fix: /ship Steps 7-8 not idempotent — re-run after partial failure corrupts VERSION and CHANGELOG #649
Copy link
Copy link
Open
Description
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:
- Before push: check if branch is already pushed (
git rev-parse @{u}orgit ls-remote) - Before PR create: check if a PR already exists for the branch (
gh pr list --head <branch>) - 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 sectionContext
/land-and-deployalready 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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels