ReplyFailureCode
Why one review in `mutateReplyReviews` did not get its reply.
Stable codes, not prose. Clients branch on these to decide whether offering a retry is honest, so
renaming a member is a breaking change; `FailedReplyReview.reason` stays free text beside it.
`retryable` rides on the member rather than living in a lookup table, so a new code cannot be
added without deciding whether re-sending the identical request could ever succeed. Note this is
a property of the SOURCE as much as of the error: a Google reply is an idempotent PUT, so
retrying a timeout is harmless, while DinnerBooking posts — a timed-out request that actually
landed would post a second reply on retry.

