Skip to content
Back to skills

Pr

ASecurity

Create a pull request after self-review, verify, and test pass. Handles branch push, PR creation, plan archiving, and hand-off. Invoke automatically after /cross-review completes (or is skipped), when self-review, verify, and test reports all exist with passing verdicts.

  • 6 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
ai-agentsexpressgit

Works with

  • claude code
  • cursor
  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add yoshpy-dev/ralph --skill pr --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pr?

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

Security grade badge for Pr
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yoshpy-dev-ralph/badge)](https://www.skillsdirectory.com/skills/yoshpy-dev-ralph)

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: pr
description: Create a pull request after self-review, verify, and test pass. Handles branch push, PR creation, plan archiving, and hand-off. Invoke automatically after /cross-review completes (or is skipped), when self-review, verify, and test reports all exist with passing verdicts.
---
Create a PR to hand off completed work for human review and merge.

## Pre-checks

Before creating a PR, confirm ALL of the following:

1. A self-review report exists in `docs/reports/` with no CRITICAL findings.
2. A verify report exists in `docs/reports/` with pass or partial-pass verdict.
3. A test report exists in `docs/reports/` with pass verdict. **If tests failed, do NOT create the PR.**
4. Raw evidence is saved in `docs/evidence/`.
5. Branch name passes `./scripts/branch-name.sh validate "$(git branch --show-current)"`.
6. You are NOT on main or master.
7. `gh` CLI is available (if not, provide manual commands instead).
8. If `.harness/state/standard-pipeline/active-plan.json` exists, it includes `worktree_path`, `branch`, and `worktree_state_id` for post-PR cleanup.

If any pre-check fails, stop and explain what is missing.

## Steps

1. **Resolve pinned plan identity** (standard flow):
   Read `.harness/state/standard-pipeline/active-plan.json` to obtain the exact plan path and task worktree metadata persisted by `/implement`. Use this path for archival in Step 8 instead of rescanning `docs/plans/active/`. If the file is absent (e.g. legacy session), fall back to the single file under `docs/plans/active/` or ask the user which plan to archive.
2. Check for uncommitted changes with `git status --porcelain`.
   - **If uncommitted changes exist**: Stage with `git add` (prefer specific files over `-A`) and create a conventional commit: `<type>: <description>`. If a GitHub issue is linked, append `Refs #<number>` to the commit body.
   - **If working tree is clean** (intermediate commits already exist): Skip staging and committing — proceed directly to push.
3. **Scan the branch history for secrets, right before pushing**: run `./scripts/secret-scan-branch.sh --strict`. It scans the same range CI scans (merge-base with the base branch to `HEAD`) using the `.gitallowed` committed at `HEAD`, so run it after the last commit. Exit 0 means the range was actually scanned and is clean (the script prints `scanned <a>..<b> against <ref>: clean`): continue. Exit 1 (findings): do NOT push. History is scanned, so deleting the line in a new commit does not clear it: either rewrite the unpushed commits, or add a narrow `.gitallowed` regex (written so that the line itself does not match a scanner pattern), commit it, and re-run. Exit 3 covers three different problems: "could not scan" (no base ref, no merge-base, scanner missing, a rule in `.git/info/attributes`, which CI does not read, or the base changed `.gitattributes` and the merge's attributes cannot be computed the way CI's are: a local merge driver, an old git, or merge-tree failing), "nothing to scan" (HEAD is the base branch, or there are no commits between the base and HEAD), and the scanner itself failing to read the range (printed as `scanner failed with exit 3`; for example a git error) — in a `/pr` flow "nothing to scan" means something is off (wrong base, a base ref that moved), not that the branch is clean. In every case: do NOT push; fix the cause (for example `git fetch origin <base>`, confirm the base is actually what this branch merges into, move `.git/info/attributes` rules into `.gitattributes`, or merge or rebase the base into the branch so HEAD carries its `.gitattributes`) and re-run.
4. Push the branch: `git push -u origin HEAD`.
5. Create a ready-for-review PR with `gh pr create` using [template.md](template.md) for the body structure. **PR title and body must be written in Japanese.** The PR title must start with the current branch type prefix from `./scripts/branch-name.sh title-prefix "$(git branch --show-current)"` (for example, `feat/...` -> `feat: ...`). Do not pass `--draft` unless the operator explicitly requests a draft.
   - Do not identify an assistant tool as PR provenance in the title or body. Avoid markers like `[codex] ...`, `[claude] ...`, `[cursor] ...`, `chore(codex): ...`, `chore(claude): ...`, `chore(cursor): ...`, `Generated by Codex`, `Generated by Claude`, `Generated by Cursor`, `Created by ...`, `Co-authored-by: ...`, or similar labels. Mention Codex, Claude, Cursor, or another tool only when the change itself is about that tool's behavior or configuration, not as the PR author or creator.
   - **Linked issue handling**: If the PR fully completes a linked GitHub issue (from branch name `<type>/<issue>/<slug>` or the plan's `Related issue:` field), include `Closes #<number>` in the PR body so GitHub auto-closes the issue on merge. For partial work or related follow-up that should keep the issue open, use `Refs #<number>` instead. For multiple issues, repeat the keyword for each issue, such as `Closes #123, closes #456`. The closing keyword must appear in normal PR body text, not inside HTML comments, code blocks, or block quotes.
   a. **Overview image** (before the create call): the body's `## 全体図` section shows the overview figure of the plan's visual review page, or one line in Japanese saying why it does not (for example `全体図は省略: gh 2.96.0 に --attach がない`). The image is optional; none of the cases below blocks the PR.
      - Page: the path in the plan's `## Visual review` section, normally `.harness/state/plan-visual/<slug>.html` (`<slug>` is the plan file name without its `YYYY-MM-DD-` prefix and `.md`). If that section says `None (<reason>)` or the page does not exist, skip the image and give that as the reason.
      - gh: if `gh pr create --help` does not list `--attach` (gh 2.99.0 and later have it), skip the image; the reason names the version that `gh --version` prints.
      - Match the figure to the diff: compare the page's overview figure (and its file-map figure, if any) with `git diff --name-only <ref>...HEAD`, where `<ref>` is the base ref Step 3 printed (`against <ref>`). Ignore pipeline artifacts (`docs/reports/`, `docs/evidence/`, `docs/insights/`, the plan). If the implementation added, dropped, or renamed parts the overview shows, edit the page so the overview shows what was built, and add or rename only what the diff shows.
      - Shoot: `./scripts/plan-visual.sh shot .harness/state/plan-visual/<slug>.html .harness/state/plan-visual/<slug>-overview.png --fragment overview --width 1150 --height <fit> --scale 2`, where `<fit>` is about the overview `viewBox` height + 160. Read the PNG and fix the page until it is clean, the same self-check as `/plan` step 10.c. Exit 2 (no Chrome / Chromium found) or any other failure: skip the image and give the reason. If you cannot read images, attach the PNG unchecked and say so in the section.
   b. **Attach it**: write the body to a file outside the tracked tree (for example `.harness/state/pr-body.md`) and pass it with `--body-file`. Put `![<alt>](.harness/state/plan-visual/<slug>-overview.png)` in the `## 全体図` section, outside any code span or HTML comment, and add `--attach '.harness/state/plan-visual/<slug>-overview.png#<alt>'` to the create call. Use the exact same path string in both and run gh from the worktree root, so gh rewrites that reference to the uploaded URL instead of appending a second copy.
   c. **If the create call exits non-zero**: keep its stdout and exit code, and find out whether the PR exists: a PR URL on stdout, else an open PR from this branch of the repository you pushed to (Step 4's `origin`) into the intended base. gh can create the PR and still exit non-zero (an upload that failed partway, or an update after creation that failed).
      - Look it up with `gh pr list --head "$(git branch --show-current)" --base <base> --state open --json url,headRepositoryOwner --jq '.[] | select((.headRepositoryOwner.login // "" | ascii_downcase) == ("<owner>" | ascii_downcase)) | .url'`. Empty output means no such PR.
      - `<base>` is the branch name: the `<ref>` from Step 3 without its `origin/` prefix. `<owner>` is the owner part of origin's URL: `git remote get-url origin | sed -E 's#/+$##; s#.*[:/]([^/]+)/[^/]+$#\1#'` (works for `https://`, `ssh://`, and `git@<host>:` URLs, with or without a trailing `/`, including SSH host aliases that `gh` cannot resolve). `gh pr list --jq` takes no `--arg`, so write the owner into the expression in place of `<owner>`, keeping the double quotes.
      - `--head` matches the branch name only, so the owner check keeps a fork's PR with the same branch name out. The check ignores case, because GitHub owner names are case-insensitive, and a PR whose head owner is null never matches. Do not use `gh pr view` here: with no open PR it can return an earlier merged or closed PR of the same branch name. A closed or merged PR, or one from another owner's branch, counts as "No PR". An open PR from this branch into another base also gives empty output here; the second lookup under "No PR" finds it.
      - PR exists: run `gh pr edit <url> --body-file <body>` with the same `--attach` argument as in 5.b, once. If that also exits non-zero, replace the image line with a one-line reason and run `gh pr edit <url> --body-file <body>` without `--attach`.
      - No PR: before re-creating, look again for an open PR from this branch, into any base this time.
        - Look it up with `gh pr list --head "$(git branch --show-current)" --state open --json url,baseRefName,headRepositoryOwner --jq '.[] | select((.headRepositoryOwner.login // "" | ascii_downcase) == ("<owner>" | ascii_downcase)) | "\(.baseRefName) \(.url)"'`.
        - If it prints anything, an open PR from this branch into another base exists: do not create a PR; stop and report the base and URL it printed.
        - Only when it prints nothing, replace the image line with a one-line reason and re-run `gh pr create` without `--attach`.
        - If gh refuses because a PR for this branch already exists, stop and report it.
        - If the re-run fails for any other reason, the cause is not the image: stop and report it.
      - Never create a second PR for the same branch. Then continue with Step 6.
6. After PR creation, run `./scripts/ensure-pr-title-prefix.sh <pr-url-or-current-branch>` and `./scripts/ensure-pr-ready.sh <pr-url-or-current-branch>`. If either fails, stop and do NOT report the PR as complete.
7. For large diffs (>500 changed lines), create a walkthrough in `docs/reports/walkthrough-<date>-<slug>.md`.
8. Archive the plan using the path resolved in Step 1: `./scripts/archive-plan.sh <absolute-plan-path>`. This moves the plan file, so it needs its own commit and push: `git add` the move (when the script also prints `Updated N reference(s) in docs/tech-debt/README.md`, it has rewritten that file's `docs/plans/active/` links to the plan, so `git add docs/tech-debt/README.md` too and keep the rewrite in the same commit), create a conventional commit, run `./scripts/secret-scan-branch.sh --strict` again against this new `HEAD` (same rules as Step 3), and `git push origin HEAD` before treating the archive as durable.
9. **Clear standard-pipeline state** (on successful PR creation):
   `rm -f .harness/state/standard-pipeline/active-plan.json .harness/state/standard-pipeline/cycle-count.json`.
   If PR creation fails, leave the state files in place so the user can resume.
10. **Cleanup task worktree and local branch** (standard flow only):
    - Only run cleanup after the PR URL exists, title/ready checks pass, and the branch has been pushed to `origin`.
    - Resolve `worktree_state_id` from the Step-1 `active-plan.json`.
    - Run `./scripts/ralph-worktree.sh cleanup --id <worktree_state_id> --force-branch`.
    - `--force-branch` is allowed here because the remote PR branch is already the durable hand-off. Do not delete the remote branch while the PR is open.
    - If cleanup fails, leave the git-common-dir state file in place and report the exact recovery command (`./scripts/ralph-worktree.sh gc` or `cleanup --id <id>`) instead of hiding the failure.

## Completion gate

Do NOT present the PR as complete unless ALL of the following are true:

- [ ] `./scripts/secret-scan-branch.sh --strict` exited 0 before every push (the PR push and any later push, such as the plan-archive commit)
- [ ] PR created and URL displayed to the user
- [ ] The PR body's `## 全体図` section shows the overview image, or a one-line reason why it does not
- [ ] `./scripts/ensure-pr-title-prefix.sh <pr-url-or-current-branch>` passed
- [ ] `./scripts/ensure-pr-ready.sh <pr-url-or-current-branch>` passed
- [ ] Plan archived from `docs/plans/active/` to `docs/plans/archive/`
- [ ] For large diffs: walkthrough report exists
- [ ] Commit follows conventional commit format
- [ ] `.harness/state/standard-pipeline/` state files removed on success
- [ ] Standard-flow task worktree and local branch removed, or cleanup failure reported with state preserved

## CLI execution modes

This skill runs under both Claude Code and Codex. The execution mode follows
the conventions in AGENTS.md and `.codex/AGENTS.override.md`.

| Aspect | Claude Code | Codex |
|--------|-------------|-------|
| Skill invocation | `/skill-name` slash command | `$skill-name` mention or the `/skills` menu (avoid the `/skill-name` form — it collides with built-ins) |
| Skill body path | `.claude/skills/<name>/SKILL.md` | `.agents/skills/<name>/SKILL.md` |
| Subagent mechanism | `Task(subagent_type=...)` when a policy delegates | `.codex/agents/` custom agents when a policy delegates |
| Structured prompts | `AskUserQuestion` | Numbered options printed to stdout, awaiting a digit reply |
| Artifacts | `docs/reports/`, `docs/plans/`, `docs/specs/` (shared) | Same (CLI-agnostic) |

The drift check (`./scripts/check-skill-sync.sh`) cross-checks both bodies and
invocation metadata — editing only one side will fail CI.

Files in this skill

  • SKILL.md13.7 KB
  • template.md1.8 KB

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.

Comments

Loading comments…

Newsletter

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