brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
writing-pr-descriptionsShapes a PR body into something a reviewer understands at a glance. Use ALWAYS before writing or editing a PR description, before `gh pr create` or `gh pr edit --body`, and when asked to improve an existing description. Puts the effect a person sees in the first line and the mechanism under it, routes each remaining fact to the form that carries it fastest …
Independent GitHub snapshot · Automated classification · Original documentation governs
gh pr create or gh pr edit --body, and when asked to improve an existing description.
Puts the effect a person sees in the first line and the mechanism under it, routes each remaining fact to the form that carries it fastest (bullet, table, diagram, screenshot, collapsed block), cuts everything a reviewer does not need, then holds what survives to a checkable shape: one fact per bullet, sentences under 25 words, active voice, no idioms.
Makes the body stand alone, so a reader who opens no files still knows why the PR is necessary and what it does, sizes the body to the change so a small PR reads as small, and makes every claim either linked to its evidence or labeled as unchecked.
Ends with a scan test over the title and the first lines of Problem and Changes.
Not for commit messages (see AGENTS.md, "Commit types") or user-facing product copy (see /writing-user-facing-copy).A reviewer scans a description in seconds and decides where to spend attention. The body is a scanning surface, not an essay, and it has to stand without the diff. A body that narrates the code, or that would fit any PR equally well, teaches its reader to skip the next one.
Order decides whether they understand the change at all. Form and length only decide how fast. So get the order right first, and never buy shape at the cost of it.
Work in five passes: lead, route, cut, shape, check. Run all five. When a body already exists, pass 0 comes first.
gh pr edit --body replaces the whole body, so every part of your draft that has no home is gone the moment you push it.
An existing body holds work you cannot recreate: screenshots and recordings a person uploaded, links they collected, a checkbox they ticked, a note to a named reviewer.
Read the current body and edit it, rather than writing a fresh one over the top:
gh pr view <number> --json body --jq .body > pr-body.md
# edit pr-body.md
gh pr edit <number> --body-file pr-body.md
Carry every image, video, link and ticked box into the new body, under the heading it belongs to, and add the heading when your draft has none. Replace one only when the change made it wrong, and say in the body that you replaced it.
The first line is the one line you can count on being read. You just spent an hour inside the mechanism, so the mechanism comes out first. Push it down and spend that line on what a person experiences.
Most of the time you already wrote the effect and put it third. Move it up rather than writing a new sentence.
Line 1 can be a bullet or a standalone sentence, whichever reads faster, but one sentence and never a paragraph.
❌ The first three bullets, as written:
- The canvas runtime posts to the host with
port?.postMessage(...), so messages sent before the port exists are silently dropped.- The host delivers the MessagePort only after the artifact iframe's load event, which fires after the app's module scripts ran.
- A
ph.queryissued while the app mounts is dropped and rejects 30 s later with "Canvas request timed out".
✅ The same three facts, reversed:
- A canvas app that queries while it mounts hangs for 30 seconds, then fails with "Canvas request timed out".
- The host delivers the MessagePort only after the iframe's load event, which fires after the app's module scripts ran.
port?.postMessage(...)drops anything posted before that.
Nothing was added and nothing was cut. The reviewer now knows the stakes before they reach the cause.
Prose is the slowest form on the page. Before writing a sentence, ask what carries the fact faster.
| The fact you have | The form that carries it |
|---|---|
| A visual change (any UI a person sees) | Screenshot, before and after. Mandatory, not optional |
| A new action and its effect, which one screenshot cannot show | A feature reel in place of the "after" screenshot |
| A change to a flow or topology (CI wiring, pipelines, state machines, request paths) | Two branded flowchart blocks, before first |
| Several values compared across the same dimensions | A markdown table |
| A config or setting change | A fenced diff block |
| Existing code a reviewer needs to see | A line-range permalink, which GitHub renders as a snippet |
| Test output, logs, long command transcripts | A <details> block |
| A behavior change or a risk a reviewer must not miss | > [!WARNING] or > [!NOTE] |
| Anything else | Bullets, under the shape rule in pass 4 |
No PR needs every form. Reach for one because it makes review faster, never as decoration. An empty section gets one bullet or "None".
A screenshot is the default for every visual change.
A feature reel is an animated WebP of one UI flow, made with reel mode of /qa-frontend.
Use a reel only for a new action and its effect, when a screenshot of the end state hides the action.
Examples are a right-click menu on an element that had none, or a bar that appears when rows are selected.
A new item in an existing menu, a new column, or new copy gets a screenshot, because the reviewer already knows how a person gets there.
Before you make a reel, read references/screenshots-and-reels.md. It has the test, worked examples, and what a reel leaves out.
Take each screenshot from the first source that can show the change:
Capture at deviceScaleFactor: 2. A 1x image looks soft on a high-density screen, and GitHub shrinks a wider image to fit the column. Take the before from the base branch the same way. A new surface has no before, so say that in one line.
Upload with hogli pr:upload-image <file> and paste the markdown it prints. The first run only warns; re-run with --yes. The assets are public forever, so never upload customer data, customer names, secrets, or internal info.
Touching UI code without a visible change is common, and the mandate has to be dischargeable. When nothing looks different, say so in one line. A reviewer cannot tell that case from a missing screenshot, and silence reads as the second.
Keep diagrams simple. A syntax error renders as an error block. Pick TD for tall pipelines, LR for wide paths. Mermaid cannot read CSS vars, so use the hex directly, and pair every fill with a text color so nodes stay legible in GitHub light and dark.
classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
Assign by role (class NodeA,NodeB phBlue;): phBlue agents and primary paths, phRed APIs and external systems, phYellow entry and exit, phGray data and artifacts. Shape by kind: {{hexagon}} agents, [rect] steps.
The body has to stand on its own. Do not assume the reviewer reads the diff first, or at all, or in the order you wrote it. Many go straight to the code and come back only if the body earned it, so write for a reader who has opened no files.
Keep:
git blame in six months needs. They cannot ask you, and the review thread will not tell them.Cut the detail the diff carries better: exact values, per-file narration, the mechanics of code a reviewer reads in context anyway. The test is not "is this in the diff", because a diff holds every detail and none of the point.
One fact per bullet makes prose checkable. It does not make it shorter: a dense paragraph exploded into twelve bullets moves the reviewer's cost rather than removing it. Cut first, and shape only what survives.
Delete:
A body that would fit any PR tells a reader nothing about this one. A reader who meets a few learns to skip them all. When the diff is six lines, the body has to read as the body of a six-line change.
Small does not mean partial. Three bullets still have to carry why the change is necessary and what it does.
The description is the only artifact in a PR that nothing validates. The code has CI. This has you, so make every claim cheap to disprove.
This governs claims about the world: what you ran, measured, or saw in production. A statement about how the code behaves needs no link, because the reader checks it against the code. "The fallback never fires" is the second kind. "One source has failed every run since May" is the first.
Problem and Changes carry the review. Everything under them is evidence and provenance, and a reviewer reaches it last or never. When the lower half outgrows the upper half, cut the lower half.
<details> block.The test: the body must come out shorter than your first draft. Pass 5 checks it.
The shape is checkable. Tone is not, which is why this skill does not ask for one.
Rule 2 orders the words inside a bullet. Pass 1 orders the bullets. They never conflict: the effect goes first, and the bullet that states it starts with the person it happened to.
A reviewer scans, stops, checks one claim, moves on. A sentence that packs four facts into three clauses makes them hold all four to check any one. Split it.
This governs prose only. A table cell is not a sentence, and a diagram is not prose.
❌ One bullet, five links in a causal chain, 28 words:
When the signals job's artifact glob matches one artifact (every selective-mode run),
download-artifactextracts it flat, so spans getjob_key ...:Noneand re-run recovery joins miss.
✅ Three bullets, each checkable on its own, 22 words:
download-artifactextracts the files flat in selective mode.- The span gets the job key
...:None.- Re-run recovery cannot join on that key.
The cut removed the glob matching one artifact. That is one level below what a reader needs, and "in selective mode" still names the condition. It kept every identifier, and every link in the chain a reviewer has to check.
Copy the second one. It is shorter, not just flatter.
## 🤖 Agent context, not a voice the body speaks in.Run both checks over the body you just wrote, before gh pr create or gh pr edit. Fix what fails.
Read only the title, the first line of Problem, and the first bullet of Changes. Cover the rest.
A "no" anywhere means the body is ordered for the writer, not the reader. Go back to pass 1. Nothing in the line check can rescue a body that fails here.
<!-- --> template comment survive anywhere? That section is unfilled. Fill it or delete it.## 🤖 Agent context section filled, naming the exact model and listing the skills invoked?references/examples.md runs merged PRs through every pass, with a table of what each cut removed and why. Read it when you want the rules applied end to end rather than to one sentence.
Pass 1 rests on three findings. Readers scan before they read: 15 of 19 participants in NN/g's web writing study approached unfamiliar text by scanning, and a version that was concise, scannable and front-loaded measured 124% higher usability than the original. What a scanner sees is the start of each line, so the first words decide whether the rest gets read at all. And review time goes to understanding the change rather than to finding defects (Bacchelli and Bird, ICSE 2013), which makes handing over that understanding the body's first job. Google's CL description guidance says the same thing, and grounds pass 3 too: the description carries the problem and the reason for this approach, with enough context for a reader who is not in the code.
Pass 4 adapts a subset of the 53 writing rules in ASD-STE100 Simplified Technical English (Issue 9, January 2025). The 25-word ceiling is the standard's limit for descriptive text; it caps procedural text at 20, which a PR body rarely contains. Rules 1 and 2 are our own: STE writes "one instruction per sentence" for procedures and "one topic per paragraph" for descriptions, and a bullet sits between the two, while front-loading comes from the scanning research above.
The other half of the standard, a dictionary of roughly 900 approved words each carrying one meaning, is licensed and deliberately not part of this. Vocabulary stays a judgment call.
Nothing here is enforced by a check. Pass 5 is the enforcement.