Ship Issue
SkillDev toolsFully solve a small issue end-to-end — resolve, publish the PR, run two Copilot review rounds, address them, and merge when confident. Escalates to the user on anything uncertain.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Ship Issue skill
What this skill tells your AI
The instructions your AI receives, as published by gittower/git-flow-next in .claude/skills/ship-issue/SKILL.md and read by ahel’s review.
Take a small, well-scoped issue all the way to merged, autonomously. This
skill chains the existing pipeline — /resolve-issue to implement, publish,
then two rounds of GitHub Copilot code review, addressing each round, and
finally merging when the result is confidently correct.
It is the end-to-end counterpart to /resolve-issue (which stops at the
publish gate). Use it only for issues you are confident an AI can solve
unattended. The autonomy is real: it publishes, comments, and merges without
asking — except at the escalation points below, where it stops and asks
you.
Arguments
/ship-issue <issue-number> [--no-merge] [--rounds <n>]
<issue-number>— required, the spec issue to solve end-to-end.--no-merge— do everything through the review rounds, then stop and hand the merge decision to you (present the state and the merge command). Use when you want the final call.--rounds <n>— number of Copilot review rounds (default 2).0skips Copilot review entirely and goes straight to the merge gate.
When to use / not use
- Use for small, well-scoped spec issues — a contained bug fix, a single-command flag, a doc-plus-code change — where the spec is clear and the blast radius is small.
- Do not use for large or ambiguous work, anything touching merge/conflict
semantics broadly, or an issue without a spec. Run
/resolve-issueinteractively instead. If in doubt about size, run/resolve-issueand stay in the loop.
Autonomy & Escalation Contract
Proceed without asking through the happy path. Stop and ask the user the moment any of these holds — describe what happened, what you tried, and the options, then wait:
- Not a small/clear issue —
/resolve-issue's precondition fails (non-spec issue, or a parent with a Breakdown), or the spec turns out to be larger/more ambiguous than "small" once analyzed. - Resolve aborted —
/resolve-issuehits its 3-revision abort, orgo build ./.../go test ./...fails and a straightforward fix isn't obvious. - Copilot can't be attached — neither the REST nor the GraphQL request attaches the reviewer (see recipe below). Ask the user to add Copilot in the web UI, then continue.
- Copilot doesn't respond — no review within the poll timeout (~10 min).
- A review finding you can't confidently resolve — a must-fix that needs a design decision, contradicts the spec, or that your fix doesn't fully satisfy. Don't guess on correctness.
- Rounds didn't converge — after the final round you still have an unresolved must-fix, or each round keeps surfacing new must-fix issues.
- Base update conflicts — the branch fell behind
mainand the merge from base produces conflicts that aren't trivially and unambiguously resolvable, or resolving them breaks the build/tests. - CI red — required checks fail after fixes and the cause isn't a trivial, obvious fix.
- Anything unexpected — an API error, a force-push seemingly required, a merge that reports not-merged, or any state you don't understand. Default to asking, not improvising.
The bar for merging is: build + tests green, CI green, both review rounds addressed with no unresolved must-fix, base up to date, and no lingering doubt. If all of that holds, merge. If any of it wobbles, escalate.
Workflow
Step 1: Resolve the issue
Run the /resolve-issue workflow (read
.claude/skills/resolve-issue/SKILL.md) for issue #<n> in this context,
executing its Steps 1–9. It analyzes the spec, creates the feature branch in
its own worktree (../git-flow-next.worktrees/<n>-<slug>), plans test-first,
implements, runs local + Codex review, applies fixes, and writes
pr_summary.md.
Do not stop at its Publish Gate (Step 10) — in this autonomous flow you perform the publish yourself (Step 2). But honor every one of its abort conditions: if the precondition fails, the 3-revision abort fires, or build/tests fail, stop and ask the user (Escalation 1–2).
After it completes, capture the worktree path, branch name
(feature/<n>-<slug>), and the .ai/ folder — you need them for the rest
of the flow. Confirm you are in the worktree and the branch is checked out.
Step 2: Publish the PR
Verify the branch is truly ready before going public: go build ./... and
go test ./... are green, and pr_summary.md passes the /pr-summary
Validate Format checklist (the PR body is a GitHub-only artifact).
Push with an explicit refspec and set tracking explicitly — a worktree branch
mis-tracks with git push -u (it can target main):
git push origin feature/<n>-<slug>:refs/heads/feature/<n>-<slug>
git branch --set-upstream-to=origin/feature/<n>-<slug> feature/<n>-<slug>
gh pr create --title "<type(scope): Subject>" --body "$(cat <ai-folder>/pr_summary.md)"
<title> follows the PR-title format from /pr-summary / COMMIT_GUIDELINES.md
(type(scope): Subject, no issue number). Verify the posted body with
gh pr view <pr>; if it drifted, fix it via REST (see the note on PR-body
edits in the recipe section — gh pr edit --body fails on this repo). Record
the PR number.
Step 3: Copilot review rounds
Repeat for each round 1..rounds (default 2; skip this whole step if
--rounds 0):
- Request a Copilot review on the PR — see Requesting a Copilot review. For round ≥ 2, request only after the previous round's fixes are pushed.
- Poll for the new review (a Copilot review with
submitted_atnewer than this round's request). Timeout ~10 min → Escalation 4. - Address the round — see Addressing a round. Accepted fixes are implemented, committed, pushed, and each thread replied to and resolved. If a finding needs a decision you can't confidently make, Escalation 5.
After the final round, if an unresolved must-fix remains or rounds aren't converging, Escalation 6.
Step 4: Update from base
Before merging, make sure the branch isn't stale:
git fetch origin
git log --oneline origin/main ^HEAD # any base commits the branch lacks?
If the branch is behind main, bring it up to date by merging the base
(do not rebase a published branch):
git merge origin/main
- Clean merge → run
go build ./...&&go test ./..., then push. - Conflicts → resolve only if trivial and unambiguous, then verify
build + tests still pass and push. If the conflicts are non-trivial, or the
resolution breaks anything,
git merge --abortand Escalation 7.
Also confirm CI is green (gh pr checks <pr>); red required checks →
Escalation 8.
Step 5: Merge decision
If --no-merge was given: present the full state (commits, review outcomes,
CI status, base freshness) and the merge command, and stop — the call is
yours.
Otherwise apply the merge bar from the contract. If everything holds, merge:
gh pr merge <pr> --merge --delete-branch
gh pr merge emits a projectCards deprecation warning on this repo but
still succeeds — confirm merged: true / exit 0 and ignore the warning. If it
reports not-merged, Escalation 9.
Step 6: Close the parent report
Resolves #<spec> closes the spec issue automatically. GitHub does not
cascade that to the spec's parent, so a user report that the spec was written
for stays open unless you close it — shipped work then sits in the open-issue
list looking unstarted. See
ISSUE_GUIDELINES.md §Relation to User Reports.
Check whether the spec has a parent: the spec body usually opens with "Refs #", and the report may list the spec as a native sub-issue.
gh issue view <spec> --json body --jq '.body' | head -5 # look for "Refs #N"
If a parent exists and the spec fully completes it, comment what shipped — naming the spec, the PR and the merge commit — and close it:
gh issue comment <report> --body "$(cat <<'EOF'
Shipped. The spec for this was #<spec>, implemented in #<pr> and merged to `main` in <sha>.
<2-4 sentences on the user-visible behavior that now exists, written for the reporter rather than the implementer.>
Closing as completed by #<spec>.
EOF
)"
gh issue close <report>
Do not close the parent when the spec only partly completes it — several specs may hang off one report. In that case comment what shipped and leave it open. Repeat up the chain if the report itself has a parent.
Step 7: Clean up and report
After a successful merge, remove the worktree and local branch:
cd ../git-flow-next
git worktree remove ../git-flow-next.worktrees/<n>-<slug>
git branch -D feature/<n>-<slug> # if it still exists locally
git fetch --prune
Report: the merged PR URL, the issue it closed, any parent report closed (or why it was left open), a one-line-per-round summary of Copilot findings addressed, whether a base update was needed, and confirmation the branch/worktree were cleaned up.
Requesting a Copilot review
Requesting Copilot on this repo is finicky — several obvious methods silently no-op. Use this order:
Fast path — REST with the full bot login (confirmed reliable):
gh api repos/gittower/git-flow-next/pulls/<pr>/requested_reviewers \
-X POST -f "reviewers[]=copilot-pull-request-reviewer[bot]"
Success = the response's requested_reviewers contains Copilot. An empty
array (a 200/201 with no reviewer) is a silent no-op — fall through.
Fallback — GraphQL requestReviews with the reviewer bot id:
# PR node id:
gh api graphql -f query='query { repository(owner:"gittower",name:"git-flow-next"){ pullRequest(number:<pr>){ id } } }' --jq '.data.repository.pullRequest.id'
# Request — use the REVIEWER bot id BOT_kgDOCnlnWA (NOT the swe-agent BOT_kgDOC9w8XQ):
gh api graphql -f query='mutation($pr:ID!,$bot:ID!){ requestReviews(input:{pullRequestId:$pr, botIds:[$bot], union:true}){ pullRequest { reviewRequests(first:10){ nodes { requestedReviewer { __typename ... on Bot { login } } } } } } }' -f pr="<PR_NODE_ID>" -f bot="BOT_kgDOCnlnWA"
botIds (not userIds); the reviewer bot is BOT_kgDOCnlnWA. The
copilot-swe-agent id from suggestedActors (BOT_kgDOC9w8XQ) is the
coding bot — passing it here is a silent no-op. Success = reviewRequests
lists Copilot.
Human fallback — if neither attaches the reviewer, ask the user to add Copilot as a reviewer in the web UI (one click, reliable), then continue. Escalation 3.
Polling for completion:
gh api repos/gittower/git-flow-next/pulls/<pr>/reviews \
--jq '[.[] | select(.user.login=="copilot-pull-request-reviewer[bot]")] | last | {state, submitted_at}'
Copilot's review objects appear under user.login == "copilot-pull-request-reviewer[bot]" (inline comments show author Copilot).
It usually posts 1–3 min after the request. Poll periodically (e.g. via the
Monitor tool or repeated checks) until a review with a submitted_at newer
than this round's request appears; for round 2, that means a second review
newer than round 1. Timeout ~10 min → Escalation 4.
Addressing a round
Delegate to /address-review (read .claude/skills/address-review/SKILL.md)
for the PR. It fetches the round's comments, evaluates each against the
project's pragmatic philosophy (accept / dismiss / partial), implements
accepted fixes, commits, and prepares inline replies + thread resolutions.
/address-review has its own "Push and post?" gate. In this autonomous flow
you are the approver for that gate: proceed automatically when the accepted
changes are clear-cut and build + tests pass. But if evaluating a comment
requires a judgment call you're not confident in — a must-fix touching
correctness or the spec, or a dismissal you're unsure the user would agree
with — surface it to the user instead of auto-approving (Escalation 5). Never
auto-dismiss a must-fix to keep the flow moving.
After it runs, the round's fixes are committed, pushed, and its threads replied to and resolved.
PR-body edits
If you need to change the PR title/body, gh pr edit --body fails on this repo
(projectCards deprecation). Use REST:
gh api -X PATCH repos/gittower/git-flow-next/pulls/<pr> -f body="$(cat body.md)"
Notes
- This skill orchestrates existing skills —
/resolve-issue,/address-review— rather than reimplementing them. Keep it thin; when their behavior changes, this inherits it. - All public writes (PR body, review replies) still go through the posting checklist via the delegated skills.
- The autonomy is deliberately asymmetric: bias toward asking whenever correctness, scope, or an unexpected state is in play. A merged wrong change costs far more than a question.
--no-mergeand--rounds 0let you dial the autonomy down without leaving the pipeline — full auto is the default because that's the point.
Signals
- GitHub stars
- 439
- Forks
- 28
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
ship-issue- Source
- github.com/gittower/git-flow-next