This skill ends in a PR awaiting review with a QA comment. /commit-push-close closes the issue directly. GitHub closing keywords take effect on merge into the repository's default branch; other targets need the workspace's issue-completion workflow.
Issue commands show the GitHub default; a workspace-named tracker overrides them per Tracker in references/ship-policy.md.
Shared ship policy
Read references/ship-policy.md first — it holds every shared ship rule the steps below cite by bold section name, Read state through the Response footer. This SKILL.md only covers what is specific to opening a PR.
PR title and body
Title mirrors the commit subject.
Body:
Closes #<num>
## Summary
<one or two sentences — what changed and why>
## Where changed
<product location and meaningful repo-relative paths, with what changed in each>
## Decisions
- <only non-obvious choices; omit section if none>
## How to test
1. <step>
2. <step>
3. <expected result>
## Notes
- <follow-ups or known gaps; omit section if none>
How to test follows How-to-test rules, including setup, expected results and actual verification status. Also draft a separate PR comment using that policy's complete QA handoff template. Keep the body and comment consistent. Zero attribution: never add or leave co-author, AI, or tool attribution in commits, PRs, issues, or comments.
For a default-branch PR, Closes #N is mandatory near the top. Multiple issues each need a closing keyword. For a permitted non-default target, use an ordinary issue reference and explain when the workspace completes it; never promise automatic closure there.
Workflow
Emit Stage / Found / Next / Needs user at each phase transition — one line per field.
Read state — run Read state in the shared policy. Resolve the PR base from explicit user/workspace instructions, then an existing PR, then the detected default. Stop on conflicts or a prohibited production target; never default into a forbidden branch.
Resolve or create the issue — branch name → recent commits → conversation context. If none, use Inline issue creation for valid small ad hoc work. Create only after step 7 approval, then insert the actual number into the commit and PR issue reference.
Read issue labels — run gh issue view <num> --json state,labels,title,url and apply Label validation, including its taxonomy-absence fallback. Stop states route to /triage. Already CLOSED → stop and ask whether to reopen or target another issue; never open a PR against an issue that will remain closed. Inline creation includes its own read-back.
Branch handling — if the current branch is the detected default branch (main/master):
Stop before staging anything.
Propose issue/<issue-num>-<slug> (<slug>: short kebab-case from the issue title, ≤ 5 words). An inline-drafted issue has no number yet — propose issue/<slug>; the PR's Closes #<num> line does the linking, not the branch name.
Wait for the user to confirm the name (offer to edit). If the user is away, proceed with the proposed name — step 7's combined approval remains the hard gate.
git checkout -b <branch> — uncommitted changes follow the checkout.
Otherwise, continue on the current branch.
Draft the commit message from the issue title and diff, per Commit message format and Naming anchor.
Draft the PR and QA comment — title mirrors the commit subject. Follow How-to-test rules and run the applicable local pass/fail checks now. Quote the decisive result in both drafts and mark unperformed manual checks pending. A failure stops shipping; an unclear plan requires the missing information.
Before presenting drafts, run the Authorship policy scrub and, if env files/keys changed, the Env parity policy sync pass.
Show the user the drafts and wait for one combined approval. Do not stage, push, or call gh pr create before approval:
Inline-created issue: also include new-issue title/body and category/state labels. After approval, create the issue first, then commit/push/PR/comment in order.
This approval is a deliberate hard gate before any remote write. If the user is away, present the drafts and stop — never stage, push, or open a PR unapproved.
Pre-commit safety — apply every check in Pre-commit safety before staging.
Commit using the quoted-HEREDOC form in Commit message format.
Push the current branch:
Tracks a remote → git push.
No upstream → git push -u origin <branch>.
Verify the intended remote branch SHA as required by Read state. A rejected or mismatched push stops PR creation/edit and commenting.
Open or update the PR against the permitted base resolved in step 1. Test evidence must cover the committed content; rerun when content changed, not merely because timing output differs. A failed check stops publication. Save the final body to a file, then:
Check for an existing PR first with gh pr list --head <branch> --json number,baseRefName,headRefName. Update the matching PR using gh pr edit <num> --body-file <pr-body-file>.md; resolve ambiguous matches instead of guessing. Preserve unrelated human-authored body sections.
Read back with gh pr view <pr-num> --json title,body,baseRefName,headRefName,url. Verify title, issue reference, resolved base, current head and test plan. Correct mismatches and re-read.
Fill the QA comment with the actual SHA, branch and PR URL. Post using gh pr comment <pr-num> --body-file <qa-comment-file>.md, then read back with gh pr view <pr-num> --json comments and verify the body and URL. Apply the shared comment retry rule. A failed comment leaves the PR created but QA handoff incomplete; report and resume the missing step.
Report — <SHA> pushed to <branch>; PR #<pr-num> opened/updated against <base>; QA: <comment URL>. State the actual issue-completion behavior and any incomplete step. Append the Response footer. Stop before merge or direct issue closure.
Example
The matching commit message lives in Commit examples (issue #418). Optional sections (Decisions, Notes) are simply omitted when empty.
PR title: add idempotency keys to checkout flow
PR body:
Closes #418
## Summary
Checkout charges are now idempotent on `x-request-id`; replays return the original result instead of double-charging.
## Where changed
`POST /checkout`, implemented in `server/checkout/handler.ts`; replay tests in `server/checkout/handler.test.ts`.
## Decisions
- Stored keys in Redis (24h TTL) over Postgres — the read path is hot
- Reused existing `x-request-id` header instead of a new one
## How to test
Setup: run this branch locally with a test account and the repo's payment sandbox.
1. `pnpm test server/checkout/handler.test.ts` — passing tail quoted below:
Test Files 1 passed (1)
Tests 6 passed (6)
Duration 1.24s
2. Hit `POST /checkout` twice with the same `x-request-id` — second call returns the first response, no second Stripe charge
3. Hit twice with different IDs — two distinct charges as before
Manual API checks pending. Remove test orders afterward.
## Notes
- Stripe webhook path still unguarded — see follow-up #419
Completion criteria
Push landed — git status shows the branch up to date with its upstream
PR read back: title, permitted base, head, issue reference, and test plan match the final drafts
Separate QA comment posted and read back with actual SHA, changed locations/paths, setup, expected results and verification status; URL reported
When the test plan contains a pass/fail test or validation command, its passing output tail is quoted in the PR body
No co-author or AI/tool attribution text in the commit message, PR title/body, or issue content
Hooks ran (no --no-verify)
Report line printed and the Suggested next skills (optional) footer appended
1---2name: commit-push-pr3description: Ship one iteration of issue work as a pull request — commit with a structured message, push the branch, and open a PR whose `Closes4---56# commit-push-pr78This skill ends in a PR awaiting review with a QA comment. `/commit-push-close` closes the issue directly. GitHub closing keywords take effect on merge into the repository's default branch; other targets need the workspace's issue-completion workflow.910Issue commands show the GitHub default; a workspace-named tracker overrides them per **Tracker** in `references/ship-policy.md`.1112## Shared ship policy1314Read [`references/ship-policy.md`](references/ship-policy.md) first — it holds every shared ship rule the steps below cite by bold section name, **Read state** through the **Response footer**. This `SKILL.md` only covers what is specific to opening a PR.1516## PR title and body1718**Title** mirrors the commit subject.1920**Body**:2122```23Closes #<num>2425## Summary26<one or two sentences — what changed and why>2728## Where changed29<product location and meaningful repo-relative paths, with what changed in each>3031## Decisions32- <only non-obvious choices; omit section if none>3334## How to test351. <step>362. <step>373. <expected result>3839## Notes40- <follow-ups or known gaps; omit section if none>41```4243**How to test** follows **How-to-test rules**, including setup, expected results and actual verification status. Also draft a separate PR comment using that policy's complete **QA handoff** template. Keep the body and comment consistent. Zero attribution: never add or leave co-author, AI, or tool attribution in commits, PRs, issues, or comments.4445For a default-branch PR, `Closes #N` is mandatory near the top. Multiple issues each need a closing keyword. For a permitted non-default target, use an ordinary issue reference and explain when the workspace completes it; never promise automatic closure there.4647## Workflow4849Emit `Stage / Found / Next / Needs user` at each phase transition — one line per field.50511. **Read state** — run **Read state** in the shared policy. Resolve the PR base from explicit user/workspace instructions, then an existing PR, then the detected default. Stop on conflicts or a prohibited production target; never default into a forbidden branch.52532. **Resolve or create the issue** — branch name → recent commits → conversation context. If none, use **Inline issue creation** for valid small ad hoc work. Create only after step 7 approval, then insert the actual number into the commit and PR issue reference.54553. **Read issue labels** — run `gh issue view <num> --json state,labels,title,url` and apply **Label validation**, including its taxonomy-absence fallback. Stop states route to `/triage`. Already `CLOSED` → stop and ask whether to reopen or target another issue; never open a PR against an issue that will remain closed. Inline creation includes its own read-back.56574. **Branch handling** — if the current branch is the detected default branch (`main`/`master`):58 - Stop before staging anything.59 - Propose `issue/<issue-num>-<slug>` (`<slug>`: short kebab-case from the issue title, ≤ 5 words). An inline-drafted issue has no number yet — propose `issue/<slug>`; the PR's `Closes #<num>` line does the linking, not the branch name.60 - Wait for the user to confirm the name (offer to edit). If the user is away, proceed with the proposed name — step 7's combined approval remains the hard gate.61 - `git checkout -b <branch>` — uncommitted changes follow the checkout.62 Otherwise, continue on the current branch.63645. **Draft the commit message** from the issue title and diff, per **Commit message format** and **Naming anchor**.65666. **Draft the PR and QA comment** — title mirrors the commit subject. Follow **How-to-test rules** and run the applicable local pass/fail checks now. Quote the decisive result in both drafts and mark unperformed manual checks pending. A failure stops shipping; an unclear plan requires the missing information.6768 Before presenting drafts, run the **Authorship policy** scrub and, if env files/keys changed, the **Env parity policy** sync pass.69707. **Show the user the drafts** and wait for one combined approval. Do not stage, push, or call `gh pr create` before approval:71 - Existing issue: commit message + PR title/body + QA comment + target branch.72 - Inline-created issue: also include new-issue title/body and category/state labels. After approval, create the issue first, then commit/push/PR/comment in order.7374 This approval is a deliberate hard gate before any remote write. If the user is away, present the drafts and stop — never stage, push, or open a PR unapproved.75768. **Pre-commit safety** — apply every check in **Pre-commit safety** before staging.77789. **Commit** using the quoted-HEREDOC form in **Commit message format**.798010. **Push** the current branch:81 - Tracks a remote → `git push`.82 - No upstream → `git push -u origin <branch>`.83 - Verify the intended remote branch SHA as required by **Read state**. A rejected or mismatched push stops PR creation/edit and commenting.848511. **Open or update the PR** against the permitted base resolved in step 1. Test evidence must cover the committed content; rerun when content changed, not merely because timing output differs. A failed check stops publication. Save the final body to a file, then:86 ```bash87 gh pr create \88 --base "<resolved-base>" \89 --head "<current-branch>" \90 --title "<subject>" \91 --body-file <pr-body-file>.md92 ```93 - Check for an existing PR first with `gh pr list --head <branch> --json number,baseRefName,headRefName`. Update the matching PR using `gh pr edit <num> --body-file <pr-body-file>.md`; resolve ambiguous matches instead of guessing. Preserve unrelated human-authored body sections.94 - Read back with `gh pr view <pr-num> --json title,body,baseRefName,headRefName,url`. Verify title, issue reference, resolved base, current head and test plan. Correct mismatches and re-read.95 - Fill the QA comment with the actual SHA, branch and PR URL. Post using `gh pr comment <pr-num> --body-file <qa-comment-file>.md`, then read back with `gh pr view <pr-num> --json comments` and verify the body and URL. Apply the shared comment retry rule. A failed comment leaves the PR created but QA handoff incomplete; report and resume the missing step.969712. **Report** — `<SHA> pushed to <branch>; PR #<pr-num> opened/updated against <base>; QA: <comment URL>`. State the actual issue-completion behavior and any incomplete step. Append the **Response footer**. Stop before merge or direct issue closure.9899## Example100101The matching commit message lives in **Commit examples** (issue #418). Optional sections (**Decisions**, **Notes**) are simply omitted when empty.102103PR title: `add idempotency keys to checkout flow`104105PR body:106```107Closes #418108109## Summary110Checkout charges are now idempotent on `x-request-id`; replays return the original result instead of double-charging.111112## Where changed113`POST /checkout`, implemented in `server/checkout/handler.ts`; replay tests in `server/checkout/handler.test.ts`.114115## Decisions116- Stored keys in Redis (24h TTL) over Postgres — the read path is hot117- Reused existing `x-request-id` header instead of a new one118119## How to test120Setup: run this branch locally with a test account and the repo's payment sandbox.1211. `pnpm test server/checkout/handler.test.ts` — passing tail quoted below:122 Test Files 1 passed (1)123 Tests 6 passed (6)124 Duration 1.24s1252. Hit `POST /checkout` twice with the same `x-request-id` — second call returns the first response, no second Stripe charge1263. Hit twice with different IDs — two distinct charges as before127Manual API checks pending. Remove test orders afterward.128129## Notes130- Stripe webhook path still unguarded — see follow-up #419131```132133## Completion criteria134135- [ ] Push landed — `git status` shows the branch up to date with its upstream136- [ ] PR read back: title, permitted base, head, issue reference, and test plan match the final drafts137- [ ] Separate QA comment posted and read back with actual SHA, changed locations/paths, setup, expected results and verification status; URL reported138- [ ] When the test plan contains a pass/fail test or validation command, its passing output tail is quoted in the PR body139- [ ] No co-author or AI/tool attribution text in the commit message, PR title/body, or issue content140- [ ] Hooks ran (no `--no-verify`)141- [ ] Report line printed and the `Suggested next skills (optional)` footer appended
Run npx skillmds@latest add devarfeen/commit-push-pr in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Ship one iteration of issue work as a pull request — commit with a structured message, push the branch, and open a PR whose `Closes It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
devarfeen (@devarfeen) published this skill. Their other Agent Skills are listed on their SkillMD profile.