Skip to content
Back to skills

Open Pull Request

ASecurity

REQUIRED for all pull requests. Always use when opening PRs, creating merge requests, or executing gh pr create / glab mr create commands. Enforces conventional branch names and conventional-commit PR titles.

  • 3 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added October 23, 2026
ai-agentsgoshellbashgitapi

Works with

  • cursor
  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned November 11, 2026

npx -y skills add alkofu/ai-tpk --skill open-pull-request --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Open Pull Request?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Open Pull Request
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/alkofu-open-pull-request/badge)](https://www.skillsdirectory.com/skills/alkofu-open-pull-request)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: open-pull-request
description: REQUIRED for all pull requests. Always use when opening PRs, creating merge requests, or executing gh pr create / glab mr create commands. Enforces conventional branch names and conventional-commit PR titles.
TRIGGER: user asks to open/create a PR or MR, mentions pushing and opening a PR, references gh/glab commands, or discusses pull request workflow.
DO NOT SKIP: applies to all PR creation regardless of repository or context.
---

# Open Pull Request (Conventional Branch + Conventional Title)

This skill extends the usual workflow (inspect state → branch → commit or amend → confirm all tracked work is committed → push → open PR) so **branch names** follow [Conventional Branch](https://conventional-branch.github.io/) and **PR titles** follow the same rules as [Conventional Commits](https://www.conventionalcommits.org/)—aligned with the `commit-message-guide` skill for commits.

## IMPORTANT: When This Skill Applies

This skill is **mandatory** for:
- Any request to open, create, or draft a pull request or merge request
- Commands like `gh pr create`, `glab mr create`, or GitLab/GitHub UI PR creation
- Workflows involving "push and open PR" or "create PR from branch"
- Branch naming when the branch will be used for a PR

**Do not** create PRs through other means or skip this workflow.

## Non-Negotiable Requirements

Every PR must:
1. Use conventional branch naming (`<type>/<description>`)
2. Have a conventional commit title (`<type>(<scope>): <subject>`)
3. Be opened as `--draft` (unless explicitly requested otherwise)
4. Be assigned to `@me` (the user)
5. Have all changes committed before push

## Workflow

1. **Check existing PR status**: Before starting work, check if the current branch already has an open or merged PR associated with it.
   - **GitHub**: `gh pr list --head $(git branch --show-current)` to check for open PRs, and `gh pr list --head $(git branch --show-current) --state merged` for merged PRs.
   - **GitLab**: `glab mr list --source-branch $(git branch --show-current)` for open MRs, and `glab mr list --source-branch $(git branch --show-current) --state merged` for merged MRs.
   - **If a PR/MR exists** (open or merged): This branch has already been used. **Do not** add new commits to it. Instead:
     - Stash any uncommitted changes: `git stash`
     - Switch to the main branch: `git checkout main` (or `master`/`develop` as appropriate)
     - Fetch latest changes: `git pull origin main` (or appropriate remote/branch)
     - Proceed to step 2 to create a new branch for the new work
   - **If no PR/MR exists**: Continue to step 2.

2. **Inspect state**: `git status`, `git branch --show-current`, confirm remote and default branch.

3. **Branch** (if needed): If on `main`/`master`/`develop` or the user wants a new branch, create one using the naming rules below. If already on a correctly named branch (with no existing PR per step 1), keep it.

4. **Commit**: Stage changes, then record history using the **commit-message-guide** for message text. Prefer **few commits** on the branch—see **Commit history** below. Every change that belongs in the PR must end up **committed** on this branch; uncommitted work will not appear on the PR.

5. **Pre-push (required)**: Do **not** push to upstream until **every change Git already tracks** (and every new file that should be in the PR) is committed. Run `git status`; if you see unstaged changes, staged changes waiting for a commit, or deletions not yet committed, resolve via amend, fixup, or a new commit (per **Commit history**) until there is nothing left to commit for work that should ship. Untracked files stay out until you intentionally `git add` and commit them.

6. **Sync with main**: Fetch remote refs, guard against a dirty working tree, and rebase the branch onto the latest `refs/remotes/origin/main` before pushing. Run each command as a standalone Bash call — do not chain with `&&` or `;`. Pipes are permitted only for data transformation.

   **6a. Fetch remote refs**

   Run: `git fetch origin`

   This updates remote-tracking refs without modifying the working tree.

   **6b. Guard against a dirty working tree**

   Run: `git status --porcelain`

   If the output is non-empty, stop and tell the user: "Working tree is dirty. Commit or stash your changes before syncing." (At this point in the workflow, changes should already be committed per step 5 — this is a safety net.)

   **6c. Rebase onto `refs/remotes/origin/main`**

   `refs/remotes/origin/main` is used instead of the `origin/main` shorthand to avoid resolution ambiguity when a local branch named `main` exists.

   **6c.1** — Run: `git rebase refs/remotes/origin/main`

   - If the rebase exits with **zero** → proceed to step 7 (Push).
   - If the rebase exits **non-zero** → continue to 6c.2.

   **6c.2** — Apply the procedure in `claude/references/conflict-resolution-rebase.md`. In this
   skill's context, "incoming branch" is the PR's branch and "upstream" is `main`. The reference
   handles detection, resolution, and the `git rebase --continue` cycle including all abort and
   round-counter cases. After the procedure completes successfully (the reference reports the rebase
   is complete), proceed to **6d** (re-validate). If the procedure aborts at any point, propagate
   the abort and stop — do not proceed to 6d or push.

   **6d. Re-validate if conflicts were resolved**

   If any conflicts were resolved during sub-step 6c.2 (i.e., the rebase did not complete cleanly in 6c.1), re-run the `validate-before-pr` skill before proceeding to step 7 (Push). Conflict resolution can modify file contents in ways that introduce lint or formatting violations that the earlier validation already cleared.

   If `validate-before-pr` fails on re-run, stop — do not push or open a PR. Report the failures and request fixes.

7. **Push**: `git push -u origin <branch>` (or your remote/branch convention) to upstream. If you **amended or rebased** commits that were **already pushed**, use `git push --force-with-lease` instead of a plain push. The PR compares the default branch to this branch, so **all commits you pushed** are what the PR contains.

8. **Open PR (always draft, assign to the user)**:
   - **GitHub**: `gh pr create --draft --assignee @me --title "..." --body-file -` (body on stdin via heredoc)
     Use `@me` so the PR is **assigned to the person opening it** (the user’s GitHub account). Adjust only if the repo uses a different assignee rule.
   - **GitLab**: `glab mr create --draft --assignee @me` (or your login) with the same title/body rules; use the web UI only if you mirror draft + assignee there.

Never omit `--draft` unless the user explicitly asks for a ready-for-review PR.

## Commit history (keep the count small)

Prefer to **update existing commits** instead of stacking more, so the PR stays easy to review.

- **`git commit --amend`**: Use when the new work **belongs with the latest commit** (same intent, same type/scope, follow-up edits, typo fixes, small adjustments). Amend updates that commit in place; adjust the message if the title line no longer fits.
- **New commit**: Add only when the change is **logically separate** or has a **different scope** (`type`/`scope` in the subject) than any commit already on the branch—so history stays one commit per coherent slice of work, not one commit per save.
- **`git commit --fixup=<commit>`** (and later **`git rebase -i --autosquash <upstream>`**): Use to attach tweaks to an **earlier** commit on the branch without rewriting the message by hand—Git lines up fixups to squash into the right parent. Typical flow: make fixup commits, then rebase onto the branch base with autosquash so fixups fold in.

After rewriting history that was already on the remote, push with **`--force-with-lease`** so you do not overwrite others’ work blindly.

## PR title (must match Conventional Commits)

Use the **same format as** `commit-message-guide` **first line**:

```
<type>(<scope>): <subject>
```

- **Types**: `feat`, `fix`, `refactor`, `perf`, `style`, `test`, `docs`, `build`, `ci`, `chore`
- **Scope**: optional; module or area (`api`, `auth`, `ui`, …)
- **Subject**: imperative, lowercase after the colon, no trailing period, ~50 chars ideal (72 max)

**Default**: Set the PR title to the **subject line of the primary commit** on the branch (the one that best describes the whole change). With a lean history (amend/fixup), this is often a **single** commit; if several commits remain, pick one title that summarizes the branch without contradicting them, or tighten history first.

Examples:

- `feat(auth): add oauth callback handler`
- `fix(api): handle empty pagination cursor`
- `chore(deps): bump eslint to 9.x`

Avoid: vague titles (`Updates`, `Fix stuff`), past tense (`Added login`), or titles that only list filenames.

## Branch names (Conventional Branch)

Structure:

```
<type-prefix>/<description>
```

**Prefixes** (pick one synonym where alternatives exist and stay consistent with the repo):

| Purpose | Prefix |
|--------|--------|
| New functionality | `feat/` or `feature/` |
| Bug fix | `fix/` or `bugfix/` |
| Urgent production fix | `hotfix/` |
| Release prep | `release/` (e.g. `release/v1.2.0`) |
| Maintenance, deps, docs-only, tooling | `chore/` |

**Description segment** (after `/`):

- Lowercase `a-z`, digits `0-9`, **hyphens** `-` between words
- For release branches, **dots** are allowed in version segments (e.g. `release/v1.2.0`)
- No underscores, spaces, or consecutive/leading/trailing hyphens or dots
- Optional ticket id: `feat/jira-123-add-export`

**Mapping from commit type → branch prefix** (when creating a branch from intent):

| Commit / work type | Typical branch prefix |
|--------------------|-------------------------|
| `feat` | `feat/` or `feature/` |
| `fix` | `fix/` or `bugfix/` (use `hotfix/` if urgent) |
| `perf` | `feat/` or `fix/` depending on whether it reads as enhancement vs correction |
| `docs`, `build`, `ci`, `chore`, `style`, `test` | `chore/` |
| `refactor` | `chore/` unless the change is user-visible, then `feat/` |

Examples:

- `feat/user-profile-settings`
- `fix/null-guard-in-parser`
- `chore/update-playwright`
- `release/v2.0.0`

Optional **team prefix** (only if the repository already uses it): `username/feat/foo` or `team/fix/bar`. Do not invent a prefix unless the project standard requires it.

## PR description

Short Markdown that is quick to scan: a one- or two-sentence lead, then bullets. Use this shape:

```markdown
<1–2 sentences: the problem solved and why it matters>

## Changes
- <one line per logical change, imperative mood>

## Notes
- <risks, rollout steps, follow-ups, or manual verification still needed>

Closes #N
```

- **Lead**: impact-first — the problem and the user or system benefit. No heading above it.
- **Changes**: 3–5 bullets, one line each. Describe changes, not files; the file list is visible in the PR UI. Use backticks for code identifiers and paths.
- **Notes**: include only when there is something to say; never write an empty or "N/A" section.
- No other headings, no checklists, no tables, no emoji. A trivial PR may be the lead sentence alone.
- Omit noise: test pass claims, AI attribution, line counts.
- Pass the body with `--body-file -` and a heredoc rather than inline `--body "..."`, so newlines, backticks, and quotes survive shell quoting.

**Closing keywords:** If the task description, session context, or commit messages on this branch contain any GitHub issue-closing keyword (`Closes #N`, `Fixes #N`, `Resolves #N`, including the `Close`/`Closed`/`Fix`/`Fixed`/`Resolve`/`Resolved` variants), append the matching line(s) verbatim to the end of the PR body so GitHub auto-closes the linked issue(s) on merge. Do not invent a closing keyword; only propagate what the upstream context supplied. If the same `Closes #N` keyword appears in multiple sources, emit it only once in the PR body.

**Issue filing is opt-in:** The PR is opened unlinked by default. Never ask whether to file an issue. Only when the user's request explicitly asks for an issue to be opened (e.g. "open a PR and file an issue") does the executing agent file a brand-new issue and link it to this PR. This step runs **after workflow step 7 (Push) has succeeded and immediately before workflow step 8 (Open PR)**, so that an aborted earlier step (e.g., step 6's rebase) cannot orphan a freshly-filed issue.

- **Explicit request:** Page in and execute `claude/references/draft-issue-protocol.md` (the same invocation `/feature --file-issue` uses; the protocol requires no changes), then append the resulting `Closes #N` line (derived from the issue number the protocol returns) verbatim to the end of the PR body, exactly as an upstream-supplied closing keyword would have been appended. If an upstream closing keyword already exists, do not file another issue.
- **No explicit request:** Proceed unchanged — the PR is opened with no linked issue and no closing keyword beyond any upstream-supplied ones.
- **Mid-flow abort/cancel/decline fallback:** `draft-issue-protocol.md` was written for the top-level `/draft-issue` session, so two of its branches end the whole session — its gh-auth pre-flight ("### Pre-flight: gh auth status check") on a non-zero `gh auth status`, and its final confirmation ("### User confirmation before delegation") if the user rejects the drafted issue. When the protocol is invoked from `/open-pr`, those "end the session" branches are reinterpreted as "return control to `/open-pr` and open the PR with no linked issue and no closing keyword." This reinterpretation is caller-side only and does not alter `draft-issue-protocol.md`; no abort, cancel, decline, or gh-auth failure during the inline protocol may terminate the PR-opening flow.
- **Standing guardrail:** filing is limited to a brand-new issue; there is no path to look up, search, or enter an existing issue number.

## Examples (end-to-end)

After push, open with draft + assignee, e.g. `gh pr create --draft --assignee @me --title "feat(reports): add csv export for quarterly view" --body-file -` with the body in a heredoc.

**Feature**

- Branch: `feat/export-csv`
- Commit / PR title: `feat(reports): add csv export for quarterly view`

**Bugfix**

- Branch: `fix/chart-tooltip-position`
- Commit / PR title: `fix(ui): correct tooltip placement near viewport edge`

**Chore**

- Branch: `chore/bump-axios`
- Commit / PR title: `chore(deps): bump axios to 1.7.x`

## Pre-flight checklist

- [ ] **GitHub account and commit author**: Verified per the account probe in `claude/references/github-auth-probe.md` (extract `{owner}/{repo}`, probe with `gh api`, switch accounts if needed, verify commit author email)
- [ ] **Branch has no existing PR**: Verified that the current branch has no open or merged PR—if one exists, switched to main, fetched latest, and created a new branch
- [ ] **Before push**: all tracked changes (and intended new files) are **committed**—`git status` shows nothing that still needs committing for work going into the PR
- [ ] **Synced with main**: Fetched origin, rebased onto `refs/remotes/origin/main`; if conflicts were resolved, `validate-before-pr` was re-run and passed
- [ ] History is **compact**: prefer `--amend` / `--fixup` + autosquash; new commits only when scope or topic differs
- [ ] Branch matches `<prefix>/<description>` and Conventional Branch character rules
- [ ] PR title is a conventional commit subject line (and matches the main commit when single-commit)
- [ ] PR body follows the lead + `## Changes` (+ optional `## Notes`) shape and adds context, not a file inventory
- [ ] If the task description or commit history contains a closing keyword (`Closes #N` / `Fixes #N` / `Resolves #N` etc.), the PR body includes the matching line at the end (deduplicated if the same keyword appears in multiple sources)
- [ ] No issue-filing question was asked; an issue was filed only if the user explicitly requested one, in which case the resulting `Closes #N` was injected into the PR body, and if the inline protocol aborted/cancelled/failed the PR was opened unlinked
- [ ] PR is opened as a **draft** and **assigned to the user** (`@me` or equivalent)
- [ ] No AI/tool attribution in title or body

## After PR Creation

**1. Implementation review**
The PR is in draft state and not ready to merge. Ruinor code review runs as a mandatory next step; treat PR creation as the beginning of the review phase, not the end of the implementation phase.

**2. Acting on reviewer feedback**
When inline comments or change requests arrive:
- Read all feedback in full — inline comments, review body, and general comments — before making any changes
- Address all requested changes in focused commits; do not introduce unrelated refactors or cleanups alongside feedback responses
- Re-run `validate-before-pr` after implementing feedback, before requesting re-review
- Do not remove the draft flag or request re-review until all feedback has been addressed

## Relationship to other skills

- **Commits**: Follow **commit-message-guide** for message bodies and footers. It also documents **WIP** and **fixup!** subject lines—pair fixup commits with `git rebase -i --autosquash` to merge them into the target commit.
- **Sync with main**: Step 6 fetches remote refs and rebases the branch onto `refs/remotes/origin/main` with automated conflict resolution before pushing. The conflict-resolution algorithm is defined in `claude/references/conflict-resolution-rebase.md`; step 6c.2 delegates to that reference. The `/sync-pr` command performs the same rebase logic independently for post-PR-creation syncing. If conflicts were resolved during the rebase, `validate-before-pr` is re-run before proceeding to push.
- **MCP / automation**: Skills named like “open-pull-request” on catalogs (e.g. [MCP Market](https://mcpmarket.com/tools/skills/open-pull-request)) usually wrap the same steps; this document defines **naming** and **titles** so any tool or CLI you use stays consistent.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.