Templates · Engineering
Pull request description template
What changed and why, the linked issue, how to test, screenshots, risk and rollback, and a reviewer checklist
Start with this template →Sign in
Opens on reph with the template ready to start. No account needed; sign in to keep your document.
Filled example
The template filled in for a made-up company, so you can see what good looks like.
Add retry with backoff to webhook delivery
Author: Diego Alvarez · Date: 2026-09-30 · Closes: #2184
What
Webhook deliveries that fail with a 5xx or a timeout are now retried up to 6 times with exponential backoff, instead of being dropped after the first failure.
Why
- Issue: #2184, "Webhooks lost when customer endpoint blips"
- Context: Lumen Labs support logged 37 tickets in August from customers whose endpoint was briefly down during a deploy. Every one of those events was lost for good.
How it works
- New
retry_at and attempt columns on webhook_deliveries (migration 0091).
- The existing delivery worker now picks up rows where
retry_at <= now(), so no new process is needed.
- Backoff is 30s, 2m, 10m, 30m, 2h, 6h, with 10% jitter. After the 6th failure the delivery is marked
failed and shows in the dashboard.
- 4xx responses are not retried, since those are the customer rejecting the payload. Read
delivery/retry.ts first.
How to test
- Run
make dev and register a webhook pointing at http://localhost:9999/hook (nothing listening).
- Trigger an event with
make fake-event. Expected: the delivery row shows attempt = 1 and a retry_at about 30 seconds out.
- Start
npx http-echo -p 9999 and wait for the retry. Expected: the row flips to delivered and the echo server logs the payload once.
- Point the webhook at an endpoint returning 400. Expected: one attempt, then
failed, no retries.
Automated tests: unit tests for the backoff schedule and the 4xx/5xx split; an integration test for the worker pickup. Jitter is not asserted exactly.
Screenshots
| Before |
After |
| Delivery list shows only "Failed" |
Delivery list shows "Retrying (2 of 6), next at 14:32" |
Risk and rollback
- Risk level: Medium
- What it touches: a migration on a table with 48 million rows (adds two nullable columns, no rewrite), and the delivery worker.
- Rollback: set
WEBHOOK_RETRIES=0 to stop retrying without a deploy; the columns are harmless if left in place.
Checklist
The template
Show the blank template
Pull request description
Author: [your name] · Date: [date] · Closes: #[issue]
What
One or two sentences on what this PR changes, written for a reviewer who has not seen the issue.
Why
The problem or goal behind it. Link the issue, ticket or incident; do not restate it in full.
How it works
The approach in a few bullets, plus anything surprising a reviewer should read first. Point at the key files.
How to test
Steps a reviewer can follow exactly, with the expected result for each.
Automated tests: what was added or changed, and what is deliberately not covered.
Screenshots
Before and after for any visible change, same viewport. Delete this section for backend-only changes.
Risk and rollback
What could go wrong in production, and how to undo it.
- Risk level: Low / Medium / High
- What it touches: migrations, auth, billing, shared config, public API
- Rollback: revert the PR, turn off a flag, or a down migration
Checklist
Questions
- How long should a PR description be?
- Long enough that a reviewer can test it without asking you; a one-line fix needs two sentences, a migration needs every section
- Do I need screenshots?
- For any visible UI change, yes; before and after, at the same viewport size
- What counts as a risky PR?
- Anything touching data migrations, auth, billing, shared config, or code without tests; say so in Risk and give the rollback
Fill it with your agent
Connect Claude to reph over MCP, then paste this. The draft arrives as suggestions you accept or reject section by section. How to connect Claude.
Find my reph doc "Pull request description" with search_docs, then read it with read_doc. Draft What and Why from the branch diff, commit messages and linked issue, How to test steps that match the changed code paths, and Risk and rollback from what the diff touches (migrations, flags, config). File it with suggest_edit, one replace_section op per section (heading line kept) so each can be accepted alone. Ask each open question (untested paths or missing screenshots) with add_comment quoting that section's heading line, then call request_review with a one-line summary.
Related templates
RFC (request for comments)
A lightweight proposal circulated for comment before a decision: summary, motivation, proposal, alternatives, drawbacks and open questions, with a comment period and decision record
EngineerTech leadEngineering managerProduct managerDesign doc
Context, goals, proposed design, alternatives and rollout for a technical change
EngineerTech leadEngineering managerADR
Architecture decision record: one decision, its context and consequences
EngineerTech leadEngineering managerTechnical spec
Implementation-level spec: overview, goals, approach, milestones
EngineerTech leadAPI spec
Endpoints, request/response shapes, errors, auth and versioning
EngineerTech leadCode review checklist
What to check before approving a change
EngineerTech lead
Start with this template →Sign in