PR Description Management
Overview
This skill creates and updates GitHub PR descriptions for the yb-voyager project.
Descriptions summarize the entire PR diff as a whole — not individual commits.
Core rule: the shortest, most pragmatic description that completely explains the change
A PR description is skimmed in under a minute. Optimize for that, always.
Completeness is the floor, not the goal. The description has to cover everything a
reviewer needs to judge the change. Shortness is how it gets there — cut words,
never facts.
- Match the length to the PR — see "Length budget" below. Spend the budget on
distinct facts, never on longer sentences.
- Short answers stay one line. The callhome and on-disk questions, and the
user-facing section when nothing applies, are one line each no matter how large
the PR is. Testing is 1-3 lines.
- Simple language. Plain words, active voice, present tense. Write "fixes a
crash when a table has no primary key", not "addresses a suboptimal behavioral
characteristic in the primary-key-less code path".
- One idea per sentence. Aim for about 20 words. Don't chain facts together
with commas, semicolons, or "and". Split them instead — a bullet that needs a
semicolon is two bullets. Two plain sentences beat one clause-stacked one.
- No filler. Drop "this PR", "in order to", "it is worth noting that",
"comprehensive", "robust", "leverage", "various", "as mentioned above".
- No diff narration. The reviewer can see the file list. Don't walk through
files, functions, or commits.
- Examples only when they earn their place. One short snippet — a command, a
config line, a before/after — when it is genuinely clearer than a sentence.
At most one per PR, at most ~5 lines. Otherwise skip it.
Length budget
| PR size |
"Describe the changes" |
Whole description |
| Small — one fix, 1-3 files |
2-3 bullets, or 2-3 sentences |
~100 words |
| Typical — one feature or fix, a handful of files |
3-5 bullets |
~200 words |
| Large — new feature, refactor, or several subsystems |
one-sentence lede + one bullet per reviewable piece (usually 6-10) |
~350 words |
Big PRs get more lines, not longer lines. For a large PR:
- Open with one sentence saying what the PR delivers as a whole.
- Then one bullet per independently reviewable piece, one line each. A 15-file
PR earns 8 bullets; it never earns 8 paragraphs.
- Group the bullets under bold labels once there are more than about six.
- Name anything deliberately left for a follow-up, in one line.
If a PR genuinely can't be explained in ~350 words, say so and suggest splitting
it — don't quietly write 800.
PR Description Template
Use the project's PR template file at .github/PULL_REQUEST_TEMPLATE as the base
structure for every PR description. Read that file each time to get the latest
section headings and reference tables — if the template is updated in the future,
your descriptions will automatically stay in sync.
Section-by-section filling guidance
When populating the template, follow these instructions for each section:
Describe the changes in this pull request — Size it from the length budget
above: 2-3 bullets for a small PR, up to ~10 for a large one. Say what was
broken or missing and what the PR does about it. Add the why only when it
isn't obvious from the what. Mention a design decision only if a reviewer
would otherwise question the approach. No commit-by-commit breakdown.
Describe if there are any user-facing changes — One line per question that
actually applies (command line, configuration, installation, reports). Show the
new flag or config key literally instead of describing it. If nothing applies,
write exactly "No user-facing changes." and nothing more.
How was this pull request tested? — 1-3 lines. Name the real tests or
commands (TestFooBar, make unit-tests), and say plainly if something is only
manually tested or still uncovered. No prose like "testing was performed to
ensure correctness".
Does your PR have changes in callhome/yugabyted payloads? — One line: "No."
or "Yes — payload version bumped to N."
Does your PR have changes to on-disk structures that can cause upgrade issues?
— One line: "No." or "Yes — ", naming them from the reference table
at the bottom of the template.
Example
Too long — narrates the diff, pads with filler, explains nothing new:
Describe the changes in this pull request
This PR introduces a comprehensive set of changes in order to improve the
robustness of the CDC event handling code path. In handleEvent, we now
leverage the error returned by WaitUntilNoConflict rather than discarding it.
Various call sites in event_processor.go were updated accordingly, and the
function signature was changed to return an error. It is worth noting that
this makes the behavior consistent with the rest of the package.
Right size — one problem, one fix, one consequence:
Describe the changes in this pull request
handleEvent silently dropped the error from WaitUntilNoConflict. An import
then kept applying events after a conflict wait had failed. It now propagates
the error, so the import fails fast instead of writing bad data.
An example earns its place when a sentence can't show the shape of the change:
Describe if there are any user-facing changes
New optional flag on import data:
--on-conflict-wait-timeout 30s
A large PR — a lede, then one line per reviewable piece, still scannable:
Describe the changes in this pull request
Adds resumable data export to the fall-back flow.
- Export — writes a per-tablet checkpoint after each batch.
- Restart — resumes from the last checkpoint instead of re-exporting the
whole snapshot.
- State — new
export_checkpoint table in MetaDB. It is created lazily, so
existing export dirs keep working.
- CLI —
export data --resume replaces --restart-if-interrupted. The old
flag stays as a hidden alias.
- Not in this PR — resumption for
export data from target (DB-1234).
Workflow: Create a PR
When the user asks to create a PR:
Gather context — run these commands in parallel:
git status to check for uncommitted changes
git log main..HEAD --oneline to see all commits on the branch
git diff main...HEAD --stat to get a summary of changed files
git diff main...HEAD to get the full diff
Analyze the full diff holistically — understand the overall purpose of the
changes as a unified body of work, not as individual commits.
Draft the PR description using the template above. Fill in each section
based on the diff analysis, then run the "Trim pass" checklist below before
showing it to anyone.
Draft a concise PR title — a short imperative sentence summarizing the change
(e.g., "Add retry logic for failed CDC events").
Present the title and description to the user for review before creating.
Create the PR using gh pr create:
git push -u origin HEAD
gh pr create --title "the title" --body "$(cat <<'EOF'
<filled template>
EOF
)"
Return the PR URL to the user.
Workflow: Update a PR Description
When the user asks to update an existing PR description:
Get the current PR — determine which PR to update:
- If the user provides a PR number/URL, use that.
- Otherwise, use
gh pr view --json number,title,body,url on the current branch.
Get the current description and show it to the user.
Gather the full PR diff (branch vs base, i.e. the entire PR — not just
changes since the last description update):
gh pr diff to get the complete diff of the PR
gh pr view --json commits to see all commits on the branch
Analyze the full PR diff holistically and draft an updated description
using the template. The description must reflect the totality of changes
in the PR, as if writing it from scratch — length budget included. An update
is a rewrite, not an append: never grow a description by tacking the newest
changes onto the old text. Run the "Trim pass" checklist before showing it.
Show the user exactly what will change — present the proposed new description
clearly, highlighting what's different from the current one. Use a format like:
Here's the updated PR description I'd like to apply:
(show full new description)
Key changes from the current description:
- (bullet list of what changed and why)
Would you like me to apply this update?
Wait for explicit user approval before making any changes. Do NOT update
the PR description without the user confirming.
Apply the update only after approval:
gh pr edit <number> --body "$(cat <<'EOF'
<filled template>
EOF
)"
gh pr edit can fail on this repo with a GraphQL error about Projects
(classic) being deprecated. The edit does not go through when that happens.
Fall back to the REST API, and check the body afterwards either way:
gh api -X PATCH repos/yugabyte/yb-voyager/pulls/<number> -F body=@- <<'EOF'
<filled template>
EOF
gh api repos/yugabyte/yb-voyager/pulls/<number> --jq '.body'
Confirm the update was applied and show the PR URL.
Writing Guidelines
- Short, not partial: A short description that gets read fully is worth more
than a thorough one that gets skipped. So cut hard — but cut words, filler, and
anything the diff already says, never a fact the reviewer needs.
- Holistic, not granular: Describe the PR as one cohesive change. Don't list
commits or say "in commit X, we did Y".
- Simple words: Explain it the way you would to a teammate in chat. No
marketing adjectives, no abstract noun where a verb works.
- Low density: One fact per sentence. A reader should never have to unpack a
sentence twice. Short sentences are what make a short description readable —
cramming the same content into fewer, denser lines defeats the point.
- Why over what: One clause of motivation beats a paragraph of mechanics.
- Be specific in testing: Name actual tests, commands, or scenarios — not
just "tested manually".
- Be honest about gaps: If testing is incomplete, say so in a few words.
Don't fabricate test coverage.
Trim pass
Before showing any description to the user, delete:
- any sentence a reviewer could get from the file list or the diff
- any word from the filler list in "Core rule" above
- any example that only repeats what the prose already said
- any background the team already knows
- restated headings ("This section describes the changes...")
Then split: any sentence carrying two facts becomes two sentences, and any bullet
with a semicolon becomes two bullets.
Then check it against the length budget for this PR's size. If it's over, cut
again — a large PR is a licence for more bullets, not for padding. Never pad a
section to look thorough: "No user-facing changes." is a complete answer.
1---2name: pr-description3description: Create and update GitHub pull request descriptions using the project PR template. Use when the user asks to create a PR, write a PR description, update a PR description, or manage pull requests.4---56# PR Description Management78## Overview910This skill creates and updates GitHub PR descriptions for the yb-voyager project.11Descriptions summarize the **entire PR diff as a whole** — not individual commits.1213## Core rule: the shortest, most pragmatic description that completely explains the change1415A PR description is skimmed in under a minute. Optimize for that, always.1617Completeness is the floor, not the goal. The description has to cover everything a18reviewer needs to judge the change. Shortness is how it gets there — cut words,19never facts.2021- **Match the length to the PR** — see "Length budget" below. Spend the budget on22 distinct facts, never on longer sentences.23- **Short answers stay one line.** The callhome and on-disk questions, and the24 user-facing section when nothing applies, are one line each no matter how large25 the PR is. Testing is 1-3 lines.26- **Simple language.** Plain words, active voice, present tense. Write "fixes a27 crash when a table has no primary key", not "addresses a suboptimal behavioral28 characteristic in the primary-key-less code path".29- **One idea per sentence.** Aim for about 20 words. Don't chain facts together30 with commas, semicolons, or "and". Split them instead — a bullet that needs a31 semicolon is two bullets. Two plain sentences beat one clause-stacked one.32- **No filler.** Drop "this PR", "in order to", "it is worth noting that",33 "comprehensive", "robust", "leverage", "various", "as mentioned above".34- **No diff narration.** The reviewer can see the file list. Don't walk through35 files, functions, or commits.36- **Examples only when they earn their place.** One short snippet — a command, a37 config line, a before/after — when it is genuinely clearer than a sentence.38 At most one per PR, at most ~5 lines. Otherwise skip it.3940### Length budget4142| PR size | "Describe the changes" | Whole description |43| :-- | :-- | :-- |44| Small — one fix, 1-3 files | 2-3 bullets, or 2-3 sentences | ~100 words |45| Typical — one feature or fix, a handful of files | 3-5 bullets | ~200 words |46| Large — new feature, refactor, or several subsystems | one-sentence lede + one bullet per reviewable piece (usually 6-10) | ~350 words |4748**Big PRs get more lines, not longer lines.** For a large PR:49501. Open with one sentence saying what the PR delivers as a whole.512. Then one bullet per independently reviewable piece, one line each. A 15-file52 PR earns 8 bullets; it never earns 8 paragraphs.533. Group the bullets under bold labels once there are more than about six.544. Name anything deliberately left for a follow-up, in one line.5556If a PR genuinely can't be explained in ~350 words, say so and suggest splitting57it — don't quietly write 800.5859## PR Description Template6061Use the project's PR template file at `.github/PULL_REQUEST_TEMPLATE` as the base62structure for every PR description. Read that file each time to get the latest63section headings and reference tables — if the template is updated in the future,64your descriptions will automatically stay in sync.6566### Section-by-section filling guidance6768When populating the template, follow these instructions for each section:6970- **Describe the changes in this pull request** — Size it from the length budget71 above: 2-3 bullets for a small PR, up to ~10 for a large one. Say what was72 broken or missing and what the PR does about it. Add the *why* only when it73 isn't obvious from the *what*. Mention a design decision only if a reviewer74 would otherwise question the approach. No commit-by-commit breakdown.7576- **Describe if there are any user-facing changes** — One line per question that77 actually applies (command line, configuration, installation, reports). Show the78 new flag or config key literally instead of describing it. If nothing applies,79 write exactly "No user-facing changes." and nothing more.8081- **How was this pull request tested?** — **1-3 lines.** Name the real tests or82 commands (`TestFooBar`, `make unit-tests`), and say plainly if something is only83 manually tested or still uncovered. No prose like "testing was performed to84 ensure correctness".8586- **Does your PR have changes in callhome/yugabyted payloads?** — One line: "No."87 or "Yes — payload version bumped to N."8889- **Does your PR have changes to on-disk structures that can cause upgrade issues?**90 — One line: "No." or "Yes — <structures>", naming them from the reference table91 at the bottom of the template.9293## Example9495Too long — narrates the diff, pads with filler, explains nothing new:9697> ### Describe the changes in this pull request98> This PR introduces a comprehensive set of changes in order to improve the99> robustness of the CDC event handling code path. In `handleEvent`, we now100> leverage the error returned by `WaitUntilNoConflict` rather than discarding it.101> Various call sites in `event_processor.go` were updated accordingly, and the102> function signature was changed to return an error. It is worth noting that103> this makes the behavior consistent with the rest of the package.104105Right size — one problem, one fix, one consequence:106107> ### Describe the changes in this pull request108> `handleEvent` silently dropped the error from `WaitUntilNoConflict`. An import109> then kept applying events after a conflict wait had failed. It now propagates110> the error, so the import fails fast instead of writing bad data.111112An example earns its place when a sentence can't show the shape of the change:113114> ### Describe if there are any user-facing changes115> New optional flag on `import data`:116> ```117> --on-conflict-wait-timeout 30s118> ```119120A large PR — a lede, then one line per reviewable piece, still scannable:121122> ### Describe the changes in this pull request123> Adds resumable data export to the fall-back flow.124>125> - **Export** — writes a per-tablet checkpoint after each batch.126> - **Restart** — resumes from the last checkpoint instead of re-exporting the127> whole snapshot.128> - **State** — new `export_checkpoint` table in MetaDB. It is created lazily, so129> existing export dirs keep working.130> - **CLI** — `export data --resume` replaces `--restart-if-interrupted`. The old131> flag stays as a hidden alias.132> - **Not in this PR** — resumption for `export data from target` (DB-1234).133134## Workflow: Create a PR135136When the user asks to create a PR:1371381. **Gather context** — run these commands in parallel:139 - `git status` to check for uncommitted changes140 - `git log main..HEAD --oneline` to see all commits on the branch141 - `git diff main...HEAD --stat` to get a summary of changed files142 - `git diff main...HEAD` to get the full diff1431442. **Analyze the full diff holistically** — understand the overall purpose of the145 changes as a unified body of work, not as individual commits.1461473. **Draft the PR description** using the template above. Fill in each section148 based on the diff analysis, then run the "Trim pass" checklist below before149 showing it to anyone.1501514. **Draft a concise PR title** — a short imperative sentence summarizing the change152 (e.g., "Add retry logic for failed CDC events").1531545. **Present the title and description** to the user for review before creating.1551566. **Create the PR** using `gh pr create`:157 ```bash158 git push -u origin HEAD159 gh pr create --title "the title" --body "$(cat <<'EOF'160 <filled template>161 EOF162 )"163 ```1641657. Return the PR URL to the user.166167## Workflow: Update a PR Description168169When the user asks to update an existing PR description:1701711. **Get the current PR** — determine which PR to update:172 - If the user provides a PR number/URL, use that.173 - Otherwise, use `gh pr view --json number,title,body,url` on the current branch.1741752. **Get the current description** and show it to the user.1761773. **Gather the full PR diff** (branch vs base, i.e. the entire PR — not just178 changes since the last description update):179 - `gh pr diff` to get the complete diff of the PR180 - `gh pr view --json commits` to see all commits on the branch1811824. **Analyze the full PR diff holistically** and draft an updated description183 using the template. The description must reflect the totality of changes184 in the PR, as if writing it from scratch — length budget included. An update185 is a rewrite, not an append: never grow a description by tacking the newest186 changes onto the old text. Run the "Trim pass" checklist before showing it.1871885. **Show the user exactly what will change** — present the proposed new description189 clearly, highlighting what's different from the current one. Use a format like:190191 > Here's the updated PR description I'd like to apply:192 >193 > *(show full new description)*194 >195 > **Key changes from the current description:**196 > - *(bullet list of what changed and why)*197 >198 > Would you like me to apply this update?1992006. **Wait for explicit user approval** before making any changes. Do NOT update201 the PR description without the user confirming.2022037. **Apply the update** only after approval:204 ```bash205 gh pr edit <number> --body "$(cat <<'EOF'206 <filled template>207 EOF208 )"209 ```210211 `gh pr edit` can fail on this repo with a GraphQL error about Projects212 (classic) being deprecated. The edit does not go through when that happens.213 Fall back to the REST API, and check the body afterwards either way:214215 ```bash216 gh api -X PATCH repos/yugabyte/yb-voyager/pulls/<number> -F body=@- <<'EOF'217 <filled template>218 EOF219 gh api repos/yugabyte/yb-voyager/pulls/<number> --jq '.body'220 ```2212228. Confirm the update was applied and show the PR URL.223224## Writing Guidelines225226- **Short, not partial**: A short description that gets read fully is worth more227 than a thorough one that gets skipped. So cut hard — but cut words, filler, and228 anything the diff already says, never a fact the reviewer needs.229- **Holistic, not granular**: Describe the PR as one cohesive change. Don't list230 commits or say "in commit X, we did Y".231- **Simple words**: Explain it the way you would to a teammate in chat. No232 marketing adjectives, no abstract noun where a verb works.233- **Low density**: One fact per sentence. A reader should never have to unpack a234 sentence twice. Short sentences are what make a short description readable —235 cramming the same content into fewer, denser lines defeats the point.236- **Why over what**: One clause of motivation beats a paragraph of mechanics.237- **Be specific in testing**: Name actual tests, commands, or scenarios — not238 just "tested manually".239- **Be honest about gaps**: If testing is incomplete, say so in a few words.240 Don't fabricate test coverage.241242## Trim pass243244Before showing any description to the user, delete:245246- any sentence a reviewer could get from the file list or the diff247- any word from the filler list in "Core rule" above248- any example that only repeats what the prose already said249- any background the team already knows250- restated headings ("This section describes the changes...")251252Then split: any sentence carrying two facts becomes two sentences, and any bullet253with a semicolon becomes two bullets.254255Then check it against the length budget for this PR's size. If it's over, cut256again — a large PR is a licence for more bullets, not for padding. Never pad a257section to look thorough: "No user-facing changes." is a complete answer.