PR Description
Shared Knowledge: This skill builds on brain/knowledge/writing-style.md (apply it in full; a PR
description is exactly the kind of prose that must not read as AI-generated) and
brain/knowledge/vault-operations.md §"Artifact archives (pinned vault projects)". Stack detection
and layer rules come from brain/knowledge/github-pr-stacks.md: on a stacked branch, each PR gets
its own description scoped to its layer's diff.
You are writing a pull-request description for a change just made (by the user or an agent on their behalf).
Use the diff, commit messages, and any context provided. Output only the description in the exact format
below. No preamble, no closing remarks.
When to Use This Skill
- Opening a PR (e.g. before
gh pr create)
- Asked to write, rewrite, or update a PR description
- Summarising a completed branch for review
Step 1: Gather Inputs
- Stack check first. Run
gh stack view --json per brain/knowledge/github-pr-stacks.md. Exit 2,
or gh/the stack extension missing, means no stack; any other outcome follows the detection table
in that file. On exit 0 the branch is part of a PR stack and the inputs change: the description
covers one layer, so diff and log against the branch directly below that layer
(fromRef: "<branch-below>...<layer-branch>", three-dot), never against main/master. Default to
the layer the current branch is on; write descriptions for other layers only when the user asks,
each from its own layer diff. Never describe changes that live in a lower layer, and never run any
gh stack command other than view (that file's ⛔ Hard Rules; submitting the stack is the
user's job).
git_diff with fromRef = base branch and toRef = HEAD (or statOnly first to see the shape).
On a stacked branch, substitute the layer refs from step 1.
git_log with ref: "<base>..HEAD" for the commit narrative (layer refs on a stacked branch).
- Fold in any extra context the user gave you.
Step 2: Retrieve Similar Past PRs
vault_list with project: "pr-descriptions" (pass it explicitly) and a query/tags from the change.
vault_get the closest matches and mirror their structure and phrasing so descriptions stay consistent
across the team. Treat them as precedent for form, not as facts about the current change.
Step 3: Write the Description
Format
> [!TIP]
> TL;DR: <one-sentence summary>
# Changes
1. **<Category>**: <Short title>
- <1–3 sentence explanation>
2. **<Category>**: <Short title>
- <1–3 sentence explanation>
...
# Caveats
...
# Test evidence
Rules
TL;DR. One sentence. Lead with the user- or system-visible outcome ("Adds a new X endpoint..."),
then briefly mention key supporting work if it's load-bearing. No marketing tone.
Categories. Each numbered item begins with a bolded category, then a colon, then two spaces, then a
short title. Use these categories:
Main Change: the core functionality being delivered (the feature, fix, or new endpoint the PR
exists for).
Improved code reusability: refactors that extract shared abstractions or remove duplication.
Improved robustness: error handling, cancellation, retries, validation, reliability.
Extensibility: scaffolding or new models that enable future work without using it yet.
- If a change genuinely fits none of these, invent a short category in the same style. Prefer the
canonical ones.
Sub-bullet. Each numbered item has exactly one nested bullet ( - ...) with the explanation. Be
concrete: name the function, class, type, file, or endpoint involved (in backticks). Include enough
detail that a reviewer understands the change without reading the diff, but stay tight. Usually 1 to 3
sentences.
Ordering. Main Change items first (in logical or dependency order), then improvements and
refactors.
Formatting details.
- Exactly two spaces after the colon following the bold category.
- Backticks around identifiers, types, paths, endpoints, HTTP verb plus path.
- Full sentences with terminal periods in the sub-bullets.
- No emoji, no images, no tables unless asked.
Caveats and Test evidence. Leave these for the user to fill in. Output Caveats with a literal
... placeholder on the next line. Output Test evidence with nothing after the header. Do not invent
caveats or test results.
Writing Style
Follow brain/knowledge/writing-style.md in full. The hard bans matter most here: no em-dashes, no
"not just X but Y," no throat-clearing transitions, no trailing "..., ensuring/allowing/making it..."
clauses, no closing summary (the list is the summary), and none of the AI vocabulary set. Apply its
"Commit messages, PR descriptions, and summaries" section too: name changes, not virtues ("Split
parse() in two," never "improved clarity and readability"), no compliance assurances, no reflexive
"while preserving existing behavior" tails, no chat voice. Write like an engineer describing the change
to a teammate. Prefer concrete over abstract ("Returns 0 when the member has no transfers" beats
"gracefully handles the empty case"). Vary bullet openings.
Also run the brain/knowledge/machine-privacy.md self-check before outputting: no absolute local paths,
OS usernames, or hostnames in the description; paths go repo-relative.
Step 4: Archive in the Vault
After the description is settled, archive it: vault_save with project: "pr-descriptions" passed
explicitly, the full description as the body. Run the machine-privacy self-check once more before
saving. Name, summary, and tags follow vault-operations.md §"Artifact archives (pinned vault
projects)".
Example Output
[!TIP]
TL;DR: Adds a new campaign balance endpoint that returns how many entries (or points/cash) a member has earned in a campaign, backed by scroll-paginated point transfer fetching and a shared paginated result abstraction.
Changes
Main Change: New GET /campaign/{campaignId}/balance/{walletType} endpoint
- Exposes the member's balance for a given wallet type within a campaign. Supports
entries, points, and cash, mapped to their internal OpenLoyalty wallet codes. Returns 0 if the member has no transfers.
Improved robustness: CancellationToken propagation
GetMemberBalanceAsync and related interfaces now accept and forward a CancellationToken, so callers can cancel in-flight requests.
Caveats
...
Test evidence
1---2name: pr-description3description: Generate a pull-request description in the house format from a diff and commit history. Retrieves similar past PRs for consistency and archives the result in the vault. Use when opening a PR, or when asked to write or update a PR description.4---56# PR Description78> **Shared Knowledge**: This skill builds on `brain/knowledge/writing-style.md` (apply it in full; a PR9> description is exactly the kind of prose that must not read as AI-generated) and10> `brain/knowledge/vault-operations.md` §"Artifact archives (pinned vault projects)". Stack detection11> and layer rules come from `brain/knowledge/github-pr-stacks.md`: on a stacked branch, each PR gets12> its own description scoped to its layer's diff.1314You are writing a pull-request description for a change just made (by the user or an agent on their behalf).15Use the diff, commit messages, and any context provided. **Output only the description in the exact format16below. No preamble, no closing remarks.**1718## When to Use This Skill1920- Opening a PR (e.g. before `gh pr create`)21- Asked to write, rewrite, or update a PR description22- Summarising a completed branch for review2324## Step 1: Gather Inputs25261. **Stack check first.** Run `gh stack view --json` per `brain/knowledge/github-pr-stacks.md`. Exit 2,27 or `gh`/the stack extension missing, means no stack; any other outcome follows the detection table28 in that file. On exit 0 the branch is part of a PR stack and the inputs change: the description29 covers one layer, so diff and log against the branch directly below that layer30 (`fromRef: "<branch-below>...<layer-branch>"`, three-dot), never against main/master. Default to31 the layer the current branch is on; write descriptions for other layers only when the user asks,32 each from its own layer diff. Never describe changes that live in a lower layer, and never run any33 `gh stack` command other than `view` (that file's ⛔ Hard Rules; submitting the stack is the34 user's job).352. `git_diff` with `fromRef` = base branch and `toRef` = `HEAD` (or `statOnly` first to see the shape).36 On a stacked branch, substitute the layer refs from step 1.373. `git_log` with `ref: "<base>..HEAD"` for the commit narrative (layer refs on a stacked branch).384. Fold in any extra context the user gave you.3940## Step 2: Retrieve Similar Past PRs4142`vault_list` with `project: "pr-descriptions"` (pass it explicitly) and a `query`/`tags` from the change.43`vault_get` the closest matches and mirror their structure and phrasing so descriptions stay consistent44across the team. Treat them as precedent for *form*, not as facts about the current change.4546## Step 3: Write the Description4748### Format4950```51> [!TIP]52> TL;DR: <one-sentence summary>5354# Changes55561. **<Category>**: <Short title>57 - <1–3 sentence explanation>58592. **<Category>**: <Short title>60 - <1–3 sentence explanation>6162...6364# Caveats65...6667# Test evidence6869```7071### Rules72731. **TL;DR.** One sentence. Lead with the user- or system-visible outcome ("Adds a new X endpoint..."),74 then briefly mention key supporting work if it's load-bearing. No marketing tone.75762. **Categories.** Each numbered item begins with a bolded category, then a colon, then two spaces, then a77 short title. Use these categories:78 - `Main Change`: the core functionality being delivered (the feature, fix, or new endpoint the PR79 exists for).80 - `Improved code reusability`: refactors that extract shared abstractions or remove duplication.81 - `Improved robustness`: error handling, cancellation, retries, validation, reliability.82 - `Extensibility`: scaffolding or new models that enable future work without using it yet.83 - If a change genuinely fits none of these, invent a short category in the same style. Prefer the84 canonical ones.85863. **Sub-bullet.** Each numbered item has exactly one nested bullet (` - ...`) with the explanation. Be87 concrete: name the function, class, type, file, or endpoint involved (in backticks). Include enough88 detail that a reviewer understands the change without reading the diff, but stay tight. Usually 1 to 389 sentences.90914. **Ordering.** `Main Change` items first (in logical or dependency order), then improvements and92 refactors.93945. **Formatting details.**95 - Exactly two spaces after the colon following the bold category.96 - Backticks around identifiers, types, paths, endpoints, HTTP verb plus path.97 - Full sentences with terminal periods in the sub-bullets.98 - No emoji, no images, no tables unless asked.991006. **Caveats and Test evidence.** Leave these for the user to fill in. Output `Caveats` with a literal101 `...` placeholder on the next line. Output `Test evidence` with nothing after the header. Do not invent102 caveats or test results.103104### Writing Style105106Follow `brain/knowledge/writing-style.md` in full. The hard bans matter most here: **no em-dashes**, no107"not just X but Y," no throat-clearing transitions, no trailing "..., ensuring/allowing/making it..."108clauses, no closing summary (the list is the summary), and none of the AI vocabulary set. Apply its109"Commit messages, PR descriptions, and summaries" section too: name changes, not virtues ("Split110`parse()` in two," never "improved clarity and readability"), no compliance assurances, no reflexive111"while preserving existing behavior" tails, no chat voice. Write like an engineer describing the change112to a teammate. Prefer concrete over abstract ("Returns `0` when the member has no transfers" beats113"gracefully handles the empty case"). Vary bullet openings.114115Also run the `brain/knowledge/machine-privacy.md` self-check before outputting: no absolute local paths,116OS usernames, or hostnames in the description; paths go repo-relative.117118## Step 4: Archive in the Vault119120After the description is settled, archive it: `vault_save` with `project: "pr-descriptions"` passed121explicitly, the full description as the body. Run the machine-privacy self-check once more before122saving. Name, summary, and tags follow `vault-operations.md` §"Artifact archives (pinned vault123projects)".124125## Example Output126127> [!TIP]128> TL;DR: Adds a new campaign balance endpoint that returns how many entries (or points/cash) a member has earned in a campaign, backed by scroll-paginated point transfer fetching and a shared paginated result abstraction.129130# Changes1311321. **Main Change**: New `GET /campaign/{campaignId}/balance/{walletType}` endpoint133 - Exposes the member's balance for a given wallet type within a campaign. Supports `entries`, `points`, and `cash`, mapped to their internal OpenLoyalty wallet codes. Returns `0` if the member has no transfers.1341352. **Improved robustness**: `CancellationToken` propagation136 - `GetMemberBalanceAsync` and related interfaces now accept and forward a `CancellationToken`, so callers can cancel in-flight requests.137138# Caveats139...140141# Test evidence