Pull Request Writing skill for Codex

PR descriptions reviewers can approve fast. Codex reads the branch diff against the merge base, checks size before writing, and fills the repo's own PR template or a structured default covering why, behaviour changes, reading order, risk, rollback and testing. Test evidence is limited to commands it actually ran, screenshots are handled honestly since gh cannot upload images, and PRs open as drafts only after you confirm.

  • Engineering Workflow
  • $pull-request-writing
  • 140 lines
  • 2 files
  • ~1,450 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- pull-request-writing

Installs to ~/.agents/skills/pull-request-writing/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $pull-request-writing, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Writes pull request titles and descriptions reviewers can act on - the problem, the approach and rejected alternatives, risk and rollout, real test evidence, before/after screenshots and a guided reading order - and sizes or splits PRs so they can be reviewed in one sitting. Fills the repo's PR template and opens drafts with gh pr create --body-file after confirmation. Use when asked to open a PR, write or improve a PR description, summarise a branch for review, or when a diff is too large to review.

Use it when

  • A branch is ready and needs a PR title and description
  • An existing PR description is thin or out of date
  • A diff looks too large to review in one sitting

Use something else when

How to check the result

Each claim in the description maps to a hunk in the three-dot diff, each test result was run in the session, and gh pr view renders the body correctly.

The mistake it prevents

Listing changed files instead of changed behaviour, and claiming tests pass without having run them on the final commit.

~/.agents/skills/pull-request-writing/SKILL.md

--- name: pull-request-writing description: Writes pull request titles and descriptions reviewers can act on - the problem, the approach and rejected alternatives, risk and rollout, real test… license: MIT ---

A good PR lets a reviewer decide in the first screen whether the change is right, then verify it without asking questions: why it exists, what it does, what could break, and proof that it works. The diff shows how; the description owns why and how you know.

Gather before writing

git fetch origin                                   # needs network
git log --oneline origin/main..HEAD
git diff --stat origin/main...HEAD                 # three dots: changes since the merge base
git diff origin/main...HEAD -- . ':(exclude)*.lock' ':(exclude)package-lock.json' | head -400
ls .github/pull_request_template.md .github/PULL_REQUEST_TEMPLATE/ docs/pull_request_template.md 2>/dev/null

Also read AGENTS.md and CONTRIBUTING.md for required sections, labels, changelog entries or sign-off. If the repo has a PR template, fill every section of it; do not replace it with your own structure.

Find the linked issue or ticket. If the user has not given one, ask instead of guessing.

Size check first

Changed lines (excluding generated/lockfiles)Action
Under ~400One PR
400-1000One PR only if it is a single concern; add a reading order
Over 1000, or mixes refactor + feature + migrationPropose a split before writing

Common split lines: preparatory refactor, then behaviour change; schema migration, then code using it; mechanical rename (reviewed by skim), then logic (reviewed carefully). For dependent PRs, see stacked-pull-requests. Never split so that an intermediate PR leaves main broken.

Title

  • One line, about 72 characters max, says what changes in imperative form: Cap bulk discounts at a single tier. Follow Conventional Commits if the repo squash merges with PR titles (fix(cart): cap bulk discounts at a single tier).
  • No ticket number alone, no “Fixes stuff”, no branch name.

Description structure

Default template when the repo has none:

## Why
<The problem in user or system terms, with the issue link. One short paragraph.>

## What changed
- <Behavioural change 1>
- <Behavioural change 2>
- <Notable internal change, only if a reviewer needs to know>

## How to review
<Suggested reading order for anything over ~300 lines. Point at the one file that
matters most; mark mechanical parts as skimmable.>

## Risk and rollout
- Risk: <what could break, for whom; "low: covered by X" is fine when true>
- Rollout: <feature flag, migration order, config change, none>
- Rollback: <revert is safe | needs down-migration | flag off>

## Testing
- [x] `pytest -q` - 214 passed
- [x] New: `test_bulk_discount_single_tier` (fails on main, passes here)
- [x] Manual: placed a 100-unit order in local dev, total 880.00 (was 836.00)
- [ ] Not tested: <what and why>

## Screenshots
| Before | After |
|---|---|
| <image> | <image> |

Closes #812

Section rules

  • Why must survive the reviewer not opening the issue. Paste the key sentence.
  • What changed lists behaviour, not files. “Adds tier_for()” is noise unless the function is new public API.
  • Alternatives considered: add a line when a reviewer would plausibly ask “why not X?”.
  • Testing contains evidence you actually observed in this session: commands and results, not “tests pass” from memory. Unchecked boxes for things not done are honest and useful; fabricated checks are a serious breach of trust.
  • Screenshots for any visible UI change, before and after at the same viewport. gh cannot upload images; produce the files (for example with Playwright) and tell the user to drag them into the PR, or reference images already hosted in the repo.
  • Use Closes #n / Fixes #n only if merging should close the issue; otherwise Refs #n.
  • Call out anything requiring reviewer action: migrations to run, env vars to add, secrets to rotate, downstream teams to notify.

Opening the PR

Opening a PR publishes to a shared system, so confirm with the user first unless they already asked for it. Prefer a draft when tests are still running or the description has open questions.

git push -u origin HEAD                       # confirm first; needs network
gh pr create --draft --base main \
  --title "Cap bulk discounts at a single tier" \
  --body-file "$TMPDIR/pr-body.md"
gh pr edit <n> --body-file "$TMPDIR/pr-body.md"   # update later without losing formatting
gh pr ready <n>                                   # when it is reviewable

Write the body to a file; inline --body strings mangle backticks and newlines in the shell. Do not add reviewers, labels or assignees the user did not ask for unless AGENTS.md or CODEOWNERS automation expects them.

When Codex authored most of the change, say so plainly in the description if the team’s policy requires disclosure; agentic-pr-workflow covers that policy in depth.

Gotchas

  • Two-dot git diff main..HEAD includes changes on main since you branched; use three dots for “what this PR changes”.
  • Lockfile and snapshot churn hides real changes in the stat. Exclude them when summarising and mention them in one line.
  • A description written before the last round of commits goes stale. Regenerate the “What changed” list from the final diff before marking ready.
  • Never paste secrets, internal hostnames or customer data from logs into the PR body.

Verification

  • Every claim in “What changed” maps to something in the diff, and every significant hunk in the diff is covered by a claim.
  • Every command in “Testing” was run in this session and the result shown is real.
  • Template sections are all filled or marked N/A with a reason.
  • The title alone tells a release-notes reader what changed.
  • Rendered preview checked: gh pr view <n> shows the body as intended.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Pull Request Writing"
  short_description: "PR descriptions reviewers can approve fast"
  default_prompt: "$pull-request-writing Write the PR description for this branch and open it as a draft"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc