Refactoring prompts with type-safety locks
The PR description prompt
A good PR description has three parts: what changed, why it changed, and how to verify it. Engineers know this. They still write one-line PRs because the description is the last thing standing between them and pushing the change.
The diff is enough context for a model to write a good description. You shouldn't be doing this work.
Write a PR description for this change. Format:
Summary
(2-3 bullets)
Why
(1-2 sentences, name the root cause)
Test plan
(checklist of 3-4 items)
Diff:
- function isValidEmail(s) { return s.includes("@") && s.includes("."); } + function isValidEmail(s: string): boolean { + if (s.trim() !== s) return false; + const at = s.indexOf("@"); + if (at < 1) return false; + const dot = s.indexOf(".", at); + if (dot < 0) return false; + const tld = s.slice(dot + 1); + return tld.length >= 2 && /^[a-zA-Z]+$/.test(tld); + }
Claude Sonnet 4.5 returned:
## Summary
- Improved email validation to check for leading/trailing whitespace, proper
ordering of `@` and `.` characters, and minimum position requirements
- Added validation for top-level domain (TLD) to require at least 2
alphabetic characters
- Added TypeScript type annotations for better type safety
## Why
The original implementation was too permissive and would accept invalid email
formats like `".@"`, `"@."`, `" user@example.com "`, or `"test@com.1"`, which
could lead to data quality issues and potential security vulnerabilities.
## Test plan
- [ ] Verify valid emails pass: `"user@example.com"`, `"test@domain.co"`
- [ ] Verify invalid emails fail: `"@example.com"`, `"user@"`, `"user@com"`,
`"test@domain.c"`, `"user@domain.1om"`
- [ ] Verify whitespace handling: `" user@example.com"`, `"user@example.com "`
should fail
- [ ] Verify TypeScript compilation succeeds with proper type checking
Captured from Claude Sonnet 4.5 (claude-sonnet-4-5) on 2026-04-27. Re-runs may differ slightly.
This is a publishable PR description. The summary is bullet-pointed and scannable. The "why" names a real failure mode (data quality, security). The test plan lists specific inputs the reviewer should verify, including edge cases the model inferred from the diff.
The format block is doing the work. Without ## Summary, ## Why, ## Test plan, you'd get a single paragraph. The Markdown headers force the structure your team's PR template expects.
The diff → description → reviewer pipeline:
Three principles to follow when adapting this prompt to your team:
- Match your team's template. If your repo's PR template has sections for
## Riskor## Rollback plan, add them to the format block. The model will fill them. - Keep test plans as checkboxes. A reviewer can run them and tick. A reviewer reading prose has to translate it into checkboxes mentally, then run them.
- Ask for the root cause in
## Why. "Refactored email validation" is a description, not a reason. "Original implementation accepted whitespace and short TLDs, leading to bounce rates of 8%" is a reason. The constraint "name the root cause" forces the second.
A small advanced trick: if your PRs go through a code review tool that supports labels, add to the prompt:
Suggest 1-3 labels from this set:
bug,feature,refactor,chore,breaking. Output the labels on a final line asLabels: ....
The label suggestions are usually right. They save you the click. You still review them — the model can be wrong about whether a change is breaking — but the suggestion is ready when you commit.
Next module: turning the same skeleton into review prompts. :::
Sign in to rate