feature-pr-description
Skill2 starsChanged 39 days agoMITView on GitHub
Write the body of a feature or fix PR from the branch's real diff, following the repo's PR contract.
- Commits and pushes
In this repository16 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- codebase-researchSkill
- context-transferSkill
- how-it-worksSkill
- human-voice-writingSkill
- i18n-translateSkill
- impact-checkSkill
- memory-reviewSkill
- orchestrateSkill
- promotion-pr-descriptionSkill
- pr-review-triageSkill
- qa-testerSkill
- release-notesSkill
- thorough-diff-reviewSkill
- walkthroughSkill
- writeups-cleanupSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 6 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 40
Use the three-dot form for the diff so the base's own commits stay out of it.
- Distinctive: line 44
When a PR already exists and the branch gained commits since its body was written, the description covers the whole branch again, never …
- Distinctive: line 49
Commit subjects are what you intended.
- Distinctive: line 72
When the branch adds or renames translation keys, name them, and check every locale that consumes them.
- Very specific: line 85
Every other block is fixed text: a heading with content under it, a table, a checklist, a footer after a --- rule.
- Very specific: line 93
Write the body to changes/<date>-<branch>/pr.md in the uncommitted drafts location from Repo facts: <date> is today as YYYY-MM-DD, <branch> …
- Distinctive: line 106
Do not open or edit a PR as part of writing the description.
- Distinctive: line 115
Use only the allowed PR title types from Repo facts.
- Very specific: line 146
If local.md exists next to this file, read it.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Feature PR description
Repo facts
This skill needs the facts below. Look each one up in the repo's CLAUDE.md (or AGENTS.md) and
the files it imports or points to (of a repo-facts file, only this skill's section:
sed -n '/^## feature-pr-description$/,/^## /p' <file>), then in local.md next to this file. If neither has it, ask
the user once, then suggest the one line to add to CLAUDE.md so the next run finds it.
| Fact | Example |
| PR description contract (a doc the description must follow, if any) | docs/pr-description.md |
| Branch flow and the default base branch for a feature PR | feature → release-<semver> → staging → main; a feature targets the open release-<semver> branch |
| Paths whose change widens a PR's blast radius (for example middleware, auth, shared UI) | src/lib/, src/middleware.ts, CI config, lint and test config, package.json |
| Where uncommitted drafts go | a gitignored writeups/ folder in the main checkout |
| Allowed PR title types | feat, fix, refactor, chore, docs, ci, with release reserved for promotion merges |
| Release index command, if any | scripts/release-index.sh |
The contract doc, when the repo has one, owns the shape, the section rules, the tone and the list of things that must not appear. This skill is the workflow around it: how to gather the material the contract asks for, and where the result goes. If the two ever disagree, the doc wins.
1. Establish the range
A description covers a branch, not a working tree.
git log --oneline <base>..HEAD # base is the PR's target branch
git diff --stat <base>...HEAD
gh pr view <N> --json title,body,baseRefName,headRefName # when a PR already existsUse the three-dot form for the diff so the base's own commits stay out of it. If no PR exists yet, target the base the branch flow from Repo facts names for a feature PR. Ask rather than assume when the branch name does not make it obvious.
When a PR already exists and the branch gained commits since its body was written, the description covers the whole branch again, never only the new commits. Propose the title with it every time.
2. Read the diff, not the commit messages
Commit subjects are what you intended; the diff is what shipped. Every claim in the description has to come from one of:
- a hunk you read,
- a test that pins the behaviour,
- a command you ran and whose output you saw.
The contract's highest-value section is where you deviated from the obvious approach, and that is never in a commit subject. Look for it deliberately: a shared primitive you touched, a wire payload you changed, a route you renamed, a default you flipped, a second design you rejected. If a commit was a follow-up fixing an earlier commit on the same branch, describe the end state, never the detour.
3. Find the blast radius yourself
Anything under the blast-radius paths from Repo facts reaches past the feature. Name the other consumers and say why they stay inert. Search the source folder for every use of what changed, excluding the files the branch already touches:
grep -rn "<ChangedComponent" <source-folder> | grep -v "$(git diff --name-only <base>...HEAD | tr '\n' '|')"When the branch adds or renames translation keys, name them, and check every locale that consumes them. A reviewer who discovers a shared change you did not mention reads the rest of the document with less trust.
4. Carry the repo's PR template
gh pr create --body-file never applies the repo's pull request template, so whatever the template
holds reaches the PR only if the body carries it. Look for the template in GitHub's places:
.github/pull_request_template.md, pull_request_template.md, docs/pull_request_template.md
(any case), or one file under a PULL_REQUEST_TEMPLATE/ folder there when it fits this PR.
- Guidance in the template (HTML comments, italic placeholder lines, "describe your change here") is an instruction: follow it, then replace it with the text it asks for.
- Every other block is fixed text: a heading with content under it, a table, a checklist, a
footer after a
---rule. Copy it verbatim, in the template's order and position.
A footer such as a list of review commands goes at the end of the body, exactly as the template has it, even when the contract doc never mentions it.
5. Write it to a file
Write the body to changes/<date>-<branch>/pr.md in the uncommitted drafts location from Repo
facts: <date> is today as YYYY-MM-DD, <branch> the branch name with / written as -. When
the branch already has a folder under changes/ (a QA run or a walkthrough made it), write into
that one instead. Resolve the location from the main checkout, never from a worktree: a
gitignored folder inside a worktree is deleted along with the worktree. For a writeups/ folder in
the main checkout, this resolves to the right folder from the main checkout and from any worktree
alike:
WRITEUPS="$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")/writeups"
PR_BODY="$WRITEUPS/changes/<date>-<branch>/pr.md"Do not open or edit a PR as part of writing the description. Pushing a branch, creating a PR, and editing a PR body are visible actions that need the user's explicit go-ahead each time. When they give it:
gh pr create --base <base> --head <branch> --title "<type>: <subject>" --body-file "$PR_BODY"
gh pr edit <N> --body-file "$PR_BODY"Use only the allowed PR title types from Repo facts.
6. Check it against the contract before handing it over
Diff the body against the template: every fixed block from step 4 is there, word for word.
Walk the contract's "Do not include" list and delete anything that crept in: a verification or testing section, a locales section, a recap of what a backend now sends, a commit list, a file-by-file tour, a screenshot gallery, a restatement of the ticket.
Then check that the title and body describe this repo's change only: no other repo by name, no
machine path, no private infrastructure. That context goes in the uncommitted drafts. Anything
another repo needs goes to the maintainer as a private brief, briefs/<date>-<topic>.md in the
drafts location, never into the PR.
Then check the headings. Each one has to be a claim a reviewer could disagree with. Contract
changes, Improvements, Testing and Other are labels, not claims: rewrite them into the
sentence the section actually argues, or fold the section into a neighbour.
Last, read the opening two paragraphs alone. A reader who stops there should know what merged and why it was needed. If they only learn that "several improvements" landed, the description has not started yet.
Related
promotion-pr-description: release branch → staging and staging → main PRs, built from the release noterelease-notes: the release record a release branch carries, and the release index command from Repo facts that regenerates its indexthorough-diff-review: review the diff before describing it
If local.md exists next to this file, read it; where it disagrees with this file, it wins.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

