| name | pr |
| description | Open a pull request for the current branch with a CONTEXT-MAXED body. A PR-writer subagent reads the branch commits + diff, the linked ticket(s), and the full builds/ trail (build reports, critiques, verdicts, decisions) to draft a rich PR description — Summary, linked ticket + acceptance checklist, Changes + Verification, Decisions/Risks/CI-gates. Context-aware about the branch: on a MIXED branch it offers to cherry-pick just the target ticket's commits onto a fresh branch (never rewriting the shared branch); on a clean branch it pushes as-is. One confirm → push → gh pr create (base branch from the project's § Tracker config — dev for finch — draft or ready), then requests an automated Copilot review and polls the background for both Copilot and the Codex connector (the latter gated on its 👀 reaction), relaying the findings when they land. A building block: it opens the PR and surfaces the review, never addresses feedback or merges. Triggers: "open a PR", "create a pull request", "PR this", "raise a PR", "ship this for review". |
| version | 1 |
| tier | lightweight |
| args | [<base branch override, default: CLAUDE.md § Tracker PR base — dev for finch>] [--dry-run] [-- <PR title / framing override>] |
Open a pull request for the current branch with a context-maxed description. A PR-writer subagent reads everything — the branch commits, the diff, the linked ticket(s), and the full builds/ trail (build reports, critiques, verdicts, and the "whys") — to draft a rich, trustworthy PR body. This allows a human reviewer to trust the work without having to re-derive it. This skill is sessionless and lightweight: it runs within the active session, scopes the range, drafts the body, gets one confirmation, pushes, runs gh pr create, and stops.
This is not /snapshot. The /snapshot skill creates per-checkpoint commits and a ticket comment. The /pr skill operates at the branch-level — it rolls those checkpoints up into the entire slice of work for review. They compose perfectly: many /snapshot checkpoints culminate in one /pr. This is a building block: it opens the PR, but it never merges it.
Trail location: The active session sets <trailDir> = <sessionDir>/builds/. The PR-writer subagent draws deep context from the session's builds/ trail and log.
Hard Repo Rules (Enforce Strictly):
- Target Branch: PRs target the configured base branch (CLAUDE.md § Tracker "PR base branch";
dev for finch), never main directly (gh pr create --base <base>). Resolve <base> in §1 (args override § Tracker; absent both, fall back to dev).
- CI Boundaries: Build and lint are CI's job. Do NOT run them here. Instead, flag special CI gates in the PR body (see §2).
- Attribution: All PR bodies must end with the trailer:
🤖 Generated with [Claude Code](https://claude.com/claude-code).
- Consent: Push and PR creation happen ONLY after explicit user confirmation.
Tracker Integration:
We use Linear via the linear-server MCP — the tracker + its tools are constant; only the issue-key prefix varies per project and comes from CLAUDE.md § Tracker (resolve it in §1, inject into the subagent prompt; keys are <PREFIX>-NNNN — FIN for finch). Use the get_issue tool to read the linked ticket's title and acceptance criteria. Load this on demand via ToolSearch linear. GitHub integration is handled via the gh CLI. If no tracker is found or linked, draft the PR from the commits/diff, explicitly note the absence of a ticket, and skip the acceptance checklist.
Preview / dry-run mode: If invoked with --dry-run (or the user asks to preview the body without pushing), run §1 and §2 normally, then STOP after the PR-writer writes <trailDir>/<slug>_PR.md — do NOT enter §3 (no confirm, no push, no gh pr create). Report the file path so a cautious user can hand-edit the body in their editor, then re-run /pr without --dry-run to push it.
/pr Protocol
1. Scope & Base Branch
Establish the base branch, the commit range, the branching strategy, and the linked ticket(s).
- Resolve the tracker config (do this first): Read CLAUDE.md's
## Tracker block (the orchestrator sees CLAUDE.md; the subagent does NOT — resolve here, inject in §2). Resolve the issue-key prefix (<PREFIX> uppercase for keys <PREFIX>-NNNN / its lowercase for branches <prefix>-NNNN-…) and the PR base branch (<base>). Finch: prefix FIN, base dev. Fallback — no ## Tracker block (unconfigured): keep today's behavior — detect a FIN-style key (uppercase-alpha prefix + -NNNN) from branch/commits/conversation, and default <base> to dev. Args override § Tracker for the base; the config is never a hard requirement.
- Base branch: The default is
<base> (from § Tracker → dev for finch), which can be overridden by arguments. Determine the current branch using git branch --show-current.
- Sync & Divergence Pre-check (CRITICAL): Before asking for confirmation, run
git fetch. Then, report if the branch is ahead/behind upstream using git status -sb or git rev-list --left-right --count @{u}...HEAD.
- If the branch is BEHIND, surface this immediately. A standard push (never
--force) will be rejected as non-fast-forward.
- Do NOT attempt to auto-resolve (no
git pull or git rebase — that is dangerous history mutation).
- Instead, force the user to either reconcile manually OR steer them to the cherry-pick/fresh-branch path (which sidesteps the divergence by pushing a clean new branch). Never proceed silently into a push that will fail.
- Show the range: Run
git log <base>..HEAD --oneline (to see the commits) and git diff <base>...HEAD --stat (to see the shape). Render both in the terminal so the user sees exactly what the PR will contain.
- Isolation Check (Do this FIRST): Check if the current checkout is already isolated. This usually makes cherry-picking unnecessary.
- If the CWD is a linked
git worktree (git rev-parse --git-common-dir ≠ , or CWD is a non-main entry in ), OR
2. Draft — Spawn the PR-Writer Subagent
Backgroundable & parallelizable. This sub-agent dispatch is a composable building block: it can run in the background (run_in_background: true) so the orchestrator keeps working while it runs, and when the work splits into independent chunks, several such sub-agents can be fanned out in parallel and reconciled.
Spawn one subagent (using a general-purpose or analyzer role) to assemble the richest, most honest PR body possible. This subagent is read-only: it reads and drafts, but it NEVER pushes, creates the PR, or touches git state.
Construct its prompt to be entirely self-contained. Use the following prompt structure:
SYSTEM PROMPT FOR PR-WRITER SUBAGENT:
You are an expert engineer selling this architectural change to a skeptical maintainer who has zero context on this session. Do NOT simply regurgitate the git diff. Your job is to explain the WHY, prove the change is safe, surface the roads not taken, and direct the reviewer's attention to the most complex or fragile parts. Read WIDELY and draft a rich, honest body. CRITICAL: You are read-only. Do NOT push, create the PR, cherry-pick, or change any git state.
-
Tracker config (resolved from CLAUDE.md § Tracker — the orchestrator fills these; you cannot read CLAUDE.md): Linear (linear-server MCP) · issue-key prefix <PREFIX> (keys <PREFIX>-NNNN, branches <prefix>-NNNN) · PR base <base>. Use this prefix for every linked-ticket reference; do NOT assume FIN.
-
The Change: Branch <branch> → base <base>. Commits: <git log <base>..HEAD --oneline output, or the cherry-pick set>. Shape: git diff <base>...HEAD --stat. Read the actual diff for the substantive files to understand the implementation.
-
Linked Ticket(s): <primary <PREFIX>-NNNN — title + acceptance from get_issue>; related: <others>. If there is NO linked ticket, explicitly state "No linked ticket — drafted from commits/diff" in the Linked-ticket section instead of leaving an empty Closes, and skip the acceptance checklist.
-
Max Context (READ THE FULL TRAIL): In <trailDir>, read THIS work's <slug>_*.md files (e.g., _SNAPSHOT.md — /snapshot feeds /pr — _BUILD.md, _CONTEXT_PACK.md, _CRITIQUE.md, _FIX.md, _EXPERIMENT.md, _TICKETS.md), plus LESSONS.md and the session log. These files contain the DECISIONS, critique findings, verification results, and risks — everything the diff cannot show.
- Note: In a long session,
builds/ holds unrelated slugs. Scope your reading to this work's <slug>, skimming others only if directly relevant.
Before dispatching — §CMD_LOG_SKILL_INVOCATION: log this dispatch to the session log (why + context-pack pointer + one-line re-tread) so a restarted session can re-tread it. Fire it as the last step before the Task/Agent handoff.
Dispatch this subagent to the background by default (run_in_background: true) so you keep working while it drafts; relay the results when it lands. Run it in the foreground only if you need the drafted body before your next step.
Preview / dry-run stop: If this run is a --dry-run / preview, STOP HERE. Report the written <trailDir>/<slug>_PR.md path (plus the proposed title + gate flags) and do not proceed to §3 — no confirm, no push, no gh pr create. The user can hand-edit the body, then re-run /pr without --dry-run to push.
3. Confirm, Push & Create (Single Confirm)
HARD RULE — NO HISTORY REWRITING / NO LIVE-TREE MUTATION.
/pr NEVER uses git rebase, git reset, git commit --amend, or git push --force. It NEVER uses git stash (forbidden). It NEVER uses git switch -c or checkouts to mutate the current/shared branch or the live working checkout. (The ONE exception — a git worktree-unavailable fallback on a verified-CLEAN tree — is spelled out in §3; it switch -cs a NEW branch off <base> and restores the original branch as its final step, never mutating the shared branch.)
The cherry-pick mechanism relies exclusively on git worktree. A focused pick builds a NEW branch off <base> in a separate throwaway worktree. This guarantees the user's original branch, checkout, and dirty working tree remain untouched.
- On ANY cherry-pick conflict: run
--abort, remove the worktree, STOP, and surface the error to the user. Never auto-resolve or use -X force.
- If a focused PR cannot be built cleanly, hand control back to the user. Do not force it.
- Relay the Plan: Present the following to the user: branch strategy (push-whole vs. cherry-pick
<k> commits onto <prefix>-<ticket>-<slug>), base branch, proposed title, draft-vs-ready status, ticket links (Closes primary + Relates others), detected CI gate flags, and the rendered PR body (or a digest + trail link if it is very long).
- Confirm (MANDATORY): Use
AskUserQuestion to get explicit permission. This action pushes code and opens an outward PR.
- Present the summary: Title · Base (
<base>) · Strategy · Draft|Ready · Closes/Relates · Gate Flags · Body.
- Offer options: Create PR / Edit one first / Cancel.
- If "Edit one first", ask what to change (title, strategy, draft/ready, body, links), loop back, and re-present the plan.
- Execute on "Create" (Strict Order):
- Append the Trailer: The subagent wrote the body to
<trailDir>/<slug>_PR.md. Append the string 🤖 Generated with [Claude Code](https://claude.com/claude-code) to the end of that FILE.
- SECURITY WARNING: Always create the PR using
--body-file <path>. NEVER pass the body inline via --body "...". The body contains backticks and $ characters. Passing it inline allows bash to perform command-substitution, which corrupts the body and creates a severe remote-code-execution vulnerability (e.g., a trail containing `rm -rf...` would execute).
- Path A: Whole-Branch (Clean branch, or user chose push-whole):
git push -u origin <the-branch-being-prd>
gh pr create --base <base> --title "<title>" --body-file <trailDir>/<slug>_PR.md [--draft]
(Note: --title must be a single, short, sanitized value).
- Path B: Cherry-Pick (Focused PR via
git worktree, NEVER git switch -c the live tree):
git worktree add -b <prefix>-<ticket>-<slug> <tmp-path> <base>
git -C <tmp-path> cherry-pick <target-commits-in-order>
git -C <tmp-path> push -u origin <prefix>-<ticket>-<slug>
gh create --base <base> -- <prefix>-<ticket>-<slug> --title --body-file <trailDir>/<slug>_PR.md [--draft]
git worktree remove <tmp-path>
4. Relay the Automated Reviews (on background-poll completion)
When the §3 poll re-wakes you (REVIEWS_SETTLED / REVIEWS_TIMEOUT, carrying copilot=/codex_review=/codex_ok= counts), fetch whatever landed (queries below), then disclose it through §CMD_ELICIT rather than dumping a flat list — automated reviewers are indiscriminate, so render each finding as a Decision Card (what's-at-stake · complexity · how-to-verify · advisory engagement, with a defeasible my lean) and lead with the triaged summary ("N worth addressing, M FYI") so the user sees which findings actually matter vs. noise. Label each card by reviewer (Copilot / Codex). /pr stays read-only — §CMD_ELICIT only discloses + classifies attention; the address/ignore choice (and any /scrutinize·/fix chain) is the caller's own, offered after the disclosure — it never addresses or merges.
- Copilot (
copilot=>0): summary body + inline findings (file:line — essence):
gh api "repos/<owner>/<repo>/pulls/<n>/reviews" --jq '.[]|select(.user.login=="copilot-pull-request-reviewer[bot]")|.body'
gh api "repos/<owner>/<repo>/pulls/<n>/comments" --jq '.[]|select(.user.login=="Copilot")|"\(.path):\(.line) — \(.body)"'
- Codex (
codex_review=>0): its review is a formal PR review (body starts ### 💡 Codex Review) + inline findings:
gh api "repos/<owner>/<repo>/pulls/<n>/reviews" --jq '.[]|select(.user.login=="chatgpt-codex-connector[bot]")|.body'
gh api "repos/<owner>/<repo>/pulls/<n>/comments" --jq '.[]|select(.user.login=="chatgpt-codex-connector[bot]")|"\(.path):\(.line) — \(.body)"'
- Codex clean pass (
codex_ok=>0 with codex_review=0): no written review — relay "Codex reviewed and approved (👍, no written findings)."
- Then stop — offer, don't auto-run:
/scrutinize to triage the findings or /fix to address them. Acting on either review is the user's call.
REVIEWS_TIMEOUT: relay whatever DID land (per the signal's counts) and note any reviewer that didn't appear in the window (slow, not enabled, or — for Codex — never engaged). The PR is open regardless; don't block on it.
Constraints (Summary)
- Automated reviews are requested/detected + polled, never acted on: after the PR opens,
/pr requests a Copilot review and polls in the background (re-woken via run_in_background) for BOTH Copilot (requested) and the Codex connector (opt-in — detected via its 👀 reaction on the PR, gated so /pr only waits when codex is actually engaged), then RELAYS both sets of findings — it never addresses or merges them. Each degrades to a no-op where that reviewer isn't enabled or gh/MCP is unavailable.
- Base from § Tracker (
dev for finch), never main directly: Resolve the PR base from CLAUDE.md § Tracker (defaulting to dev when absent). Overridable only by explicit arguments.
- No history rewriting / no live-tree mutation: No
rebase, reset, amend, push --force, stash, or switch -c on the live tree. The cherry-pick mechanism is git worktree — a focused pick builds a NEW branch off base in a throwaway worktree and never touches the source branch or the working checkout. Abort (--abort + worktree remove --force) on any cherry-pick conflict; never force-resolve. The worktree-unavailable fallback requires a clean tree and restores the original branch as its last step.
- Push is fast-forward-only: Fetch and check ahead/behind before confirming. Surface divergence; a plain push (never
--force) is rejected non-fast-forward if behind — let the user reconcile or take the clean fresh-branch path; never auto-pull/rebase.
- Context-aware branch choice is surfaced, never silent: Always offer push-whole vs. cherry-pick-the-target on mixed branches. Untagged/merge commits are shown as their own bucket and excluded from focused picks (merge commits force the whole-branch path); the user decides.
- One confirm before push + PR: Nothing pushes or opens a PR without the explicit confirm; push/PR happen only on "Create".
- Body via
--body-file, NEVER inline: The subagent writes the body to <trailDir>/<slug>_PR.md, the orchestrator appends the trailer to that file and creates with --body-file; --title stays a short sanitized single value. Inline --body "…" is forbidden (backtick/ shell-substitution risk).