3 Commits
Author SHA1 Message Date
Nirav PatelandClaude Opus 5 6b3a09ec1c Say when a channel cannot be checked, instead of skipping it
CI / test (push) Successful in 5s
The estate's SendGrid key is send-only: mail.send and the batch scopes,
with no suppression.read, no bounces.read, no stats. So email delivery
cannot be reconciled the way SMS now is.

The tempting move is to check SMS and quietly say nothing about email.
That is precisely how a gap disappears - the daily report looks clean
and the unchecked channel stops being a question anyone asks. It now
reports 'email delivery NOT VERIFIED' with the exact scope that would
fix it, every day, until somebody does.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-18 20:50:37 -04:00
Nirav PatelandClaude Opus 5 349f03015f Ask the carrier what actually happened
CI / test (push) Successful in 5s
A provider 2xx means it accepted the message, not that anyone received
it. Twilio answers 201 Created and the carrier may refuse seconds later,
and nothing watching HTTP status codes will ever know.

That is not hypothetical: the ledger shows 48 consecutive messages to
one number, every one undelivered, going back to January - including a
daily send for seven weeks. Each was recorded upstream as a success, and
each was billed.

Two decisions worth keeping. We poll rather than take a StatusCallback,
because this relay binds to loopback on purpose and no carrier can reach
it - polling costs one API call per run and keeps that property. And we
reconcile against the provider's ledger rather than our own record,
because our own record is exactly what was wrong, and it only knows
about messages we sent; Twilio's knows about the ones another service
sent too, which is how those 48 would have been caught.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-18 20:43:11 -04:00
Nirav PatelandClaude Opus 5 399487862c Reach consumers by network, not by a second host bind
CI / test (push) Successful in 16s
The compose file published a second host port on the docker bridge IP so
sibling containers could reach the relay. That is a host-reachable address for
a service whose entire safety story is that it has exactly one, on loopback.

It joins the consumers' existing docker network instead, and is reached there
by name on the container port. Nothing about a consumer's deployment has to
change to use it, and the relay gains no address outside that network.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-18 19:25:11 -04:00