Problem
src/webhooks/dispatcher.ts implements outbound delivery with exponential backoff (backoffMs), HMAC signing (subscription secret), and a retry pass for pending deliveries. What is not evident is a maximum-attempt cap or a terminal state for deliveries that keep failing, so a permanently unreachable endpoint can be retried indefinitely, and there is no test coverage asserting the backoff schedule or the signature.
What needs to be done
- Enforce a maximum number of delivery attempts; move exhausted deliveries to a terminal "dead-letter"/failed state rather than retrying forever.
- Expose the failed deliveries (query or metric) so operators can see them.
- Make the max attempts and backoff base configurable via env.
- Add tests covering: the backoff schedule produced by
backoffMs, the HMAC signature header, and the transition to the dead-letter state after the cap.
Files
src/webhooks/dispatcher.ts
.env.example
Acceptance deliverables
- Deliveries stop after a configurable maximum and land in a visible terminal state.
- Backoff and signing behavior are covered by tests.
- All CI checks pass; the change cannot be merged until CI is green.
Tests to pass
- Test:
backoffMs returns the expected increasing schedule.
- Test: the delivery HMAC signature matches the subscription secret.
- Test: a delivery is dead-lettered after the maximum attempts.
Problem
src/webhooks/dispatcher.tsimplements outbound delivery with exponential backoff (backoffMs), HMAC signing (subscriptionsecret), and a retry pass for pending deliveries. What is not evident is a maximum-attempt cap or a terminal state for deliveries that keep failing, so a permanently unreachable endpoint can be retried indefinitely, and there is no test coverage asserting the backoff schedule or the signature.What needs to be done
backoffMs, the HMAC signature header, and the transition to the dead-letter state after the cap.Files
src/webhooks/dispatcher.ts.env.exampleAcceptance deliverables
Tests to pass
backoffMsreturns the expected increasing schedule.