Create/update PRs with Conventional Commits title, issue linking & guard rails. Triggers: "create PR" | "open PR" | "submit PR" | "update PR" | "/R-pr --draft" | "open a pull request" | "make a PR" | "open pull request" | "submit a pull request" | "create a draft PR" | "raise a PR".
Scanned 9/23/2026
Install to Claude Code
npx -y skills add Roxabi/roxabi-plugins --skill pr --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Pr?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/roxabi-roxabi-plugins-roxabi-plugins)More formats (shields.io, HTML) on the badges page.
---
name: R-pr
argument-hint: '[--draft | --base <branch>]'
description: Create/update PRs with Conventional Commits title, issue linking & guard rails. Triggers: "create PR" | "open PR" | "submit PR" | "update PR" | "/R-pr --draft" | "open a pull request" | "make a PR" | "open pull request" | "submit a pull request" | "create a draft PR" | "raise a PR".
version: 0.4.7
allowed-tools: Bash, Read, Grep, ToolSearch
---
# Pull Request
## Success
I := PR created ∧ pushed ∧ rebased on base
V := `gh pr view {N}` ∧ `git log origin/${BASE}..HEAD` non-empty
Let:
β := `staging` (∃ origin/staging) ∨ `main`
Β := current branch
N := issue# (first number after `/` in Β)
**Stack:** Read `.dev/stack.yml` first — every `{field}` placeholder below resolves from it. ¬∃ → output: "`.dev/stack.yml` not found — run `/R-env-setup` to generate it." and stop.
Β → PR: Conventional Commits title, issue linking, guard rails.
**Flow: single continuous pipeline. ¬stop between steps. Stop only on: REFUSE, explicit Cancel, or Step 6 completion.**
## Pipeline
| Step | ID | Required | Verifies via | Notes |
|------|----|----------|---------------|-------|
| 1 | gather-state | ✓ | state JSON emitted | — |
| 2 | guard-rails | ✓ | ¬REFUSE | — |
| 3 | generate | ✓ | title + body ready | — |
| 4 | create | ✓ | `gh pr create` success | — |
| 5 | rebase | ✓ | `git push` success | — |
| 6 | watch | — | — | inform only |
## Pre-flight
Success: PR created ∧ pushed ∧ rebased on base
Evidence: `gh pr view {N}` returns valid PR
Steps: gather-state → guard-rails → generate → create → rebase
¬clear → STOP + ask: "Which branch are you PR-ing from?"
## Step 1 — Gather State
```bash
bash ${CLAUDE_SKILL_DIR}/gather-state.sh
```
Emits: `branch`, `base`, commit log, diff stat, existing PR, issue number, lifecycle artifacts (analysis, spec), test file count, `falsify_required`, `oracle_ok`, `oracle_reason`, `priced_ok`.
`oracle_ok` / `priced_ok` come from `run-falsify.sh --verify` on `artifacts/reviews/{N}-falsify.json` + spec SC priced scan (`parse-falsify.sh` / `pf_emit_gates`) — markdown alone is ¬the oracle (ADR-019). Missing JSON when τ≠S → `oracle_ok=false` (fail-closed).
## Step 2 — Guard Rails
| Check | Condition | Action |
|-------|-----------|--------|
| Protected branch | Β ∈ {staging, main, master} | **REFUSE.** Create feature branch first. Stop. |
| No commits | `git log origin/${β}..HEAD` empty | **REFUSE.** Nothing to PR. Stop. |
| PR exists | gh pr list → result | → present choice **Update** (`gh pr edit`) \| **Cancel** |
| Branch not pushed | `git ls-remote --heads origin $BRANCH` empty | `git push -u origin $BRANCH` |
| Quality gates | `{commands.lint} && {commands.typecheck}` | Warn on failure, ¬block. Note in PR body if proceeding. |
| Falsify incomplete (τ≠S) | `falsify_required=true` ∧ `oracle_ok=false` | **REFUSE.** Re-run `/R-dev-implement` Step 6b (`run-falsify` → persist `artifacts/reviews/{N}-falsify.json`). Stop. |
| Priced quantity missing (τ≠S) | `priced_ok=false` | **REFUSE.** Re-run `/R-spec` to add `priced`/`not`/`oracles` blocks on fail-closed SCs. Stop. |
(Note: "behind base" is no longer a guard rail — Step 5 rebases post-create automatically. τ=S: skip both rails — `falsify_required=false`.)
## Step 3 — Generate Content
**3a. Commits + diff:**
```bash
git log origin/${BASE}..HEAD --format="%h %s%n%b"
git diff origin/${BASE}...HEAD --stat
```
**3b. Lifecycle artifacts:** already emitted by Step 1 (`issue`, `analysis`, `spec`, `issue_data`, `test_files`, `falsify_*`, `priced_ok`).
N detection: first number after `/` in Β (e.g. `feat/42-slug` → `#42`). ¬found → ask user "Which issue number does this PR close, if any?"
**3c. Title:** `<type>(<scope>): <desc>` (≤70 chars). Type from primary commit purpose. Scope from files: `web | api | ui | config` ∨ omit if cross-cutting.
**3d. Body:** template below.
## Step 4 — Create + Update Issue
Show generated title + body → create immediately (¬ask how). `--draft` → draft.
Failure ∨ explicit edit request → present choice **Edit title/body** | **Cancel**
```bash
gh pr create --title "<title>" --body "<body>" --base ${BASE} [--draft]
# --base <branch> if flag specified (overrides BASE)
```
Display PR URL.
Updating existing PR → `gh pr edit <number> --title "<title>" --body "<body>"`.
## Step 5 — Rebase on Base (post-create)
After PR creation, rebase Β on latest β → force-push with lease → PR updates with current base.
```bash
git fetch origin ${BASE}
BEHIND=$(git rev-list HEAD..origin/${BASE} --count)
```
`BEHIND == 0` → skip rebase, skip push. Log: "Already up to date with origin/${BASE}."
`BEHIND > 0`:
```bash
git rebase origin/${BASE}
# On conflict: → present choice **Resolve manually then re-run /R-pr** | **Abort rebase** (`git rebase --abort`)
git push --force-with-lease origin ${BRANCH}
```
**Safety:** only `--force-with-lease` (not `--force`) — refuses push if remote moved unexpectedly. Only on the feature branch (Β ∉ {staging, main, master} is already enforced in Step 2).
**Why post-create:** ensures the PR reflects the latest base from the moment it lands, so reviewers see a minimal diff and CI runs against current base. Staging can move between branch creation and PR create — this step closes that gap.
## Step 6 — Watch CI
Inform: "CI is running on the PR — use `/R-ci-watch` to monitor it live."
Merge path = gate-driven: `reviewed` label + auto-merge (`gh pr merge --auto --merge`). ¬manual `gh pr merge` while any check is IN_PROGRESS/QUEUED — the gate decides, not the operator.
## PR Body Template
```markdown
## Summary
- {what changed and why}
- {secondary change if applicable}
## Lifecycle
| Phase | Artifact | Status |
|-------|----------|--------|
| Intent | #{N}: {title} | {state} |
| Analysis | [{filename}](artifacts/analyses/{filename}) | Present/Absent |
| Spec | [{filename}](artifacts/specs/{filename}) | Present/Absent |
| Implementation | {N} commits on `{branch}` | Complete |
| Verification | Lint {✅/❌} Typecheck {✅/❌} Tests {✅/❌} ({N} new) | Passed/Failed |
## Test Plan
- [ ] {how to verify}
- [ ] {edge case}
## SC → Test Matrix
Insert persisted `artifacts/reviews/{N}-falsify.md` (optional render of JSON) — do not invent rows. (Step 2 already refused unless `oracle_ok=true`.) Tier S: omit this section entirely — see the Lifecycle note below.
## Falsification Evidence
Insert persisted `artifacts/reviews/{N}-falsify.md` (optional JSON render) — do not invent rows.
Fixes #{N}
---
Generated with [Roxabi dev-core](https://github.com/Roxabi/roxabi-plugins) via `/R-pr`
```
Lifecycle notes: S-tier → Intent + Implementation + Verification only. ¬issue → omit Lifecycle + Closes. S-tier → also omit SC → Test Matrix and Falsification Evidence sections.
## Options
| Flag | Description |
|------|-------------|
| (none) | Target auto-detected base branch |
| `--draft` | Create as draft |
| `--base <branch>` | Override base branch |
## Edge Cases
| Scenario | Behavior |
|----------|----------|
| Β ∈ {staging, main, master} | REFUSE: "Create a feature branch first" |
| ¬commits ahead | REFUSE: "Nothing to create a PR for" |
| PR already exists | Offer `gh pr edit` to update |
| ¬N in branch | → ask user link issue or skip |
| Multiple commit types | Use primary type only |
| Lint/typecheck fail | Warn + present choice: **Proceed anyway** \| **Fix first** |
| τ≠S ∧ (`oracle_ok=false` ∨ `priced_ok=false`) | REFUSE — falsify → `/R-dev-implement` Step 6b (`run-falsify`); priced → `/R-spec` |
## Safety Rules
1. ¬PR from `staging`, `main`, `master`
2. ¬`git push --force` — only `--force-with-lease`, and only during Step 5 rebase on feature branches
3. Always show PR content before creation
4. → present choice for all decisions (proceed despite warnings, edit)
5. Always display PR URL after creation
6. Rebase conflicts → abort + defer to user — ¬auto-resolve
7. ¬manual `gh pr merge` while any check is IN_PROGRESS/QUEUED — manual merge mid-CI cancels in-flight runs (`concurrency.cancel-in-progress`) and skips gates. Nominal path: `reviewed` label → auto-merge (`--merge`) on green.
8. τ≠S: ¬create PR while `oracle_ok=false` or `priced_ok=false` — markdown / `falsify_ok` is ¬the oracle. Re-run `/R-dev-implement` Step 6b (`run-falsify`) or `/R-spec` (priced blocks).
## Chain Position
- **Phase:** Build
- **Predecessor:** `/R-dev-implement` (worktree with commits) · or `/R-ship` commit step
- **Successor:** `/R-ci-watch` (via `/R-dev`) · or `/R-dev-review` (via `/R-ship`)
- **Class:** adv (continuous flow, no gate)
## Task Integration
- `/R-dev` owns the dev-pipeline task lifecycle externally
- This skill does NOT update its own dev-pipeline task
- Sub-tasks created: none
## Exit
- **Success via `/R-dev`:** PR created + rebased + pushed → return control silently. ¬write summary. ¬ask user. ¬announce `/R-ci-watch`. `/R-dev` re-scans and advances.
- **Success standalone:** print PR URL + `Next: /R-ci-watch --pr {PR#}`. Stop.
- **Failure (REFUSE, rebase conflict, gh error):** return error. `/R-dev` presents Retry | Skip | Abort.
$ARGUMENTS
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!