The PR description I started writing as a tester
I learned to write PR descriptions before I ever opened one. Nine years later, it's still the cheapest review tool I have.
The first PR description I wrote was a bug report
Early in my first year at FPT Software HCM, I was on the test team and we filed bugs in a Jira instance that someone had wired up to a noisy Slack channel. The dev lead — a soft-spoken Hanoi-accent guy whose desk was three over from mine — would skim the bugs at standup, and the ones with bad descriptions came back with a single comment: "Repro?"
That one word made me rewrite a ticket more times than I want to count. He never explained why. He didn't have to. By the third comeback I was reading other people's bug reports to figure out what mine were missing.
It was always the same three things. What I did. What I expected. What actually happened. In that order. With the build number on top.
Three years later, when I switched from testing into frontend work, the first real PR I opened — a small fix for a date formatter in a real-time UI at Remolution — got merged before lunch. The reviewer's only comment was a thumbs up. I thought I'd gotten lucky. Then I looked at the PRs around mine and noticed most of them had no description at all. Just the commit subject mirrored into the title.
That was when I realized I'd been writing bug reports for my own changes without thinking about it.
What QA taught me to put in there
The PR template I use today has four sections. Three of them are the bug-report skeleton, lightly reframed. The fourth one took me longer to learn.
The repro section that became "how to verify"
In QA, the repro section answers can the dev recreate what I'm seeing. In a PR, the same section answers can the reviewer recreate what I'm claiming this fixes. Same shape, different direction.
I write it as a numbered list. Steps a human would actually follow, with the test data attached. Not "see the unit test" — the unit test is in the diff, the reviewer can find it. The verify section is for the case the unit test doesn't cover, which is usually the interesting one.
If I can't write the verify steps in under ten lines, the PR is probably doing two things and I split it.
The risk section that became "blast radius"
The bug report has a severity field. The PR has something I started calling blast radius, after an incident at Remolution where a one-line change to an email helper fired the wrong template through a batch of candidate-facing messages. The change had passed review in minutes because the description said "small refactor".
The blast radius section is one sentence: "If this is wrong, what breaks and for whom." For the email helper, it would have been "every candidate-facing email across multiple tenants." I would have written it. The reviewer would have read it. We probably would not have shipped it on a Friday afternoon.
Now I make myself write the sentence even when I'm sure the radius is zero. The act of writing it sometimes catches me realizing it isn't zero.
The rollback paragraph
This one came from the bug-report habit of marking "workaround" on tickets. If a bug had a workaround, the support team needed to know. If a PR has a rollback path that isn't "just revert the commit" — a feature flag to flip, a migration to undo, a queue to drain — the reviewer and the future on-call person need to know.
I write it as one paragraph. If the rollback is a clean revert, I say so explicitly. If it's not, I list the steps. The first time I had to write "revert isn't safe — the migration is forward-only, you'd need a restore from backup" I sat with that paragraph for a long minute and then rewrote the PR.
The reviewer I'm actually writing for is me, six months later
The thing nobody tells you about PR descriptions is that the audience isn't really the reviewer. The reviewer is going to read the diff anyway and will catch most of what matters in there.
The audience is the person who runs git blame on a Wednesday afternoon eight months from now, in the middle of a different incident, trying to understand why this line exists. That person has no context. They have the commit, the PR description, and maybe a Slack thread if they're lucky. The diff tells them what changed. The description has to tell them why.
The PR description is the only document your future self will trust, because it's the only one written at the moment the decision was made.
I now write the description before I open the PR — sometimes before I write the code. Not the full thing, but the blast radius sentence and the verify steps. If I can't write the blast radius sentence, I don't know enough about the change to ship it yet. If I can't write the verify steps, the change is probably too entangled, and I should split it before I waste a reviewer's time.
What carried over to agents
At PSA I'm now working on autonomous storefronts and a virtual company of AI employees. The "diff" is sometimes a tool-call trace, and the "reviewer" is sometimes another agent. I expected the PR-description discipline to fall apart in that world. It didn't. If anything, agents need it more.
When an agent ships a change in our system, we attach the same four sections to the run: what it tried to do, how a human can verify, what breaks if it's wrong, how to roll back. The agent that wrote the change can't anticipate the on-call human who'll read the trace at 2am. So the structure has to.
I keep landing on the same answer. The dev lead at FPT never told me any of this. He just kept asking for repros until I stopped giving him bad ones. The artifact has changed three times since — from bug ticket to PR to tool-call trace — and the four sections still hold.
Build number on top. What I did. What I expected. What actually happens — or in the PR case, what will happen, and what breaks if I'm wrong.
It's still the cheapest review tool I have.