You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
backends/crates/sms-provider/src/capabilities.rs — states the guarantee this
ticket enforces: "routing must not promise a caller a DLR that will never arrive."
backends/crates/sms-api/src/route_simulator.rs:86 — records that Provider.healthy is never written, because §7.5's probe_providers does not exist.
backends/apps/sms-gateway/src/commands/mtn_subscribe_dlr.rs — MTN's DLR
registration as "an operator action rather than something serve does on startup."
Live deployment, 2026-09-18: delivery_receipts holds 2 rows, both predating
the Orange rail going live.
Intent
An operator should be able to tell, without leaving vsms, whether a provider's
delivery receipts are actually working. Today they cannot: a provider that has
never been registered with its upstream looks identical to one that simply has
not been sent anything. Both are silence.
That silence is not hypothetical — it is the current state of the Orange rail,
and MTN is being configured now with the same manual registration step through a
different portal.
Context: what is and is not already uniform
DLR ingestion is uniform and needs no change. /dlr/{providerKey} looks the
provider up, calls SmsProvider::parse_dlr, and hands the result to sms_api::dlr::ingest, which knows nothing about its origin. A new adapter gets
that for free.
What is not uniform is knowing whether DLR is wired. Two holes:
1. supports_dlr is written and never read.bootstrap.rs:132 and seed_dispatch.rs:311 both hardcode supportsDlr: true; nothing consults the
column. The guarantee in capabilities.rs is documented and unenforced. It is the
mirror of Provider.healthy — one column nobody writes, one nobody reads, both
looking like working features from the schema alone.
2. Provisioning is external state nothing records. Orange's endpoint is
whitelisted by a manual support ticket; MTN's is registered by running mtn_subscribe_dlr once, by hand, against an account that may not be the one the
running gateway holds. So a provider can carry supports_dlr: true, ship a correct parse_dlr, serve a live endpoint, and receive nothing forever because a human
never finished a step in someone else's portal.
Evidence.delivery_receipts holds 2 rows, both delivered, both against
the Orange provider, received 2026-09-13 15:06 and 2026-09-14 01:54. The Orange
rail went live on real credentials at roughly 2026-09-17 20:10. Both predate that:
they came from sms-fake-orange in demo mode. Zero real Orange receipts since
go-live, and nothing anywhere says so.
Acceptance Criteria
Routing consults supports_dlr. A provider with supports_dlr = false is never
selected for a message whose caller requires a receipt, and the refusal is
explained in the routing Decision trail rather than being silent.
Per-provider DLR liveness is queryable — at minimum "last receipt received",
derivable today from delivery_receipts.provider_id + received_at with no
schema change.
A provider that claims DLR, has submissions inside the window, and has received
no receipt inside that window, is reported as a distinct condition. A provider
with no submissions is not reported — quiet must not read as broken.
That condition is visible to an operator without a database query: the console's
providers or dashboard screen, plus a log line and metric.
The check runs on a schedule, not only on demand.
A test proves the warning fires for the not-registered case and stays silent for
the no-traffic case. Both directions — the no-traffic half is what stops this
becoming noise that gets ignored.
Definition of Ready
Source of truth cited and re-verifiable.
Reproduced against the live deployment, with data.
Home identified: §7.5's probe_providers, already designed and named, and
already the would-be writer of Provider.healthy — a DLR-wiring probe and a
provider-health probe are one job asking two questions about the same row. Role::Jobs dispatches by kind through a JobHandler registry, with expire_stale as the wired example to copy.
Window length and reporting thresholds agreed (how long is "no receipts" before
it is a warning — depends on real traffic volume, which the Orange rail has not
yet produced).
Decided whether dlrRegisteredAt is stored explicitly, or registration is
inferred purely from receipt arrival.
Definition of Done
All acceptance criteria met.
probe_providers implemented as a job kind, on the existing registry.
The warning is observed firing against the current Orange state, which is a
genuine instance of the condition rather than a synthetic one.
capabilities.rs's guarantee is enforced by code, and its doc comment says
where.
MTN's DLR registration status is visible through the same surface as Orange's,
with no provider-specific special-casing.
AI Usage Declaration
AI (Claude) found both holes, traced them to the code and the live database,
and drafted this ticket.
The condition to warn on was specified by the repository owner ("we even need
a warning when it's not wired in"); the scoping of quiet-vs-broken is the
AI's proposal and is open to revision.
A human reviews and prioritises this before any implementation.
Implemented. Not started.
Why this is worth doing before MTN rather than after
MTN's DLR needs the same manual subscription Orange needed, through a different
portal, and it has never run — the adapter was rewritten against MTN's real
Swagger in #394 and wired into both binaries in #396, both released hours ago in
0.3.3. Without criterion 3, its failure mode is identical and equally silent:
messages send, receipts never arrive, everything reports healthy.
Source of Truth
backends/crates/sms-provider/src/capabilities.rs— states the guarantee thisticket enforces: "routing must not promise a caller a DLR that will never arrive."
backends/crates/sms-api/src/route_simulator.rs:86— records thatProvider.healthyis never written, because §7.5'sprobe_providersdoes not exist.backends/apps/sms-gateway/src/commands/mtn_subscribe_dlr.rs— MTN's DLRregistration as "an operator action rather than something
servedoes on startup."already-closed cause).
delivery_receiptsholds 2 rows, both predatingthe Orange rail going live.
Intent
An operator should be able to tell, without leaving vsms, whether a provider's
delivery receipts are actually working. Today they cannot: a provider that has
never been registered with its upstream looks identical to one that simply has
not been sent anything. Both are silence.
That silence is not hypothetical — it is the current state of the Orange rail,
and MTN is being configured now with the same manual registration step through a
different portal.
Context: what is and is not already uniform
DLR ingestion is uniform and needs no change.
/dlr/{providerKey}looks theprovider up, calls
SmsProvider::parse_dlr, and hands the result tosms_api::dlr::ingest, which knows nothing about its origin. A new adapter getsthat for free.
What is not uniform is knowing whether DLR is wired. Two holes:
1.
supports_dlris written and never read.bootstrap.rs:132andseed_dispatch.rs:311both hardcodesupportsDlr: true; nothing consults thecolumn. The guarantee in
capabilities.rsis documented and unenforced. It is themirror of
Provider.healthy— one column nobody writes, one nobody reads, bothlooking like working features from the schema alone.
2. Provisioning is external state nothing records. Orange's endpoint is
whitelisted by a manual support ticket; MTN's is registered by running
mtn_subscribe_dlronce, by hand, against an account that may not be the one therunning gateway holds. So a provider can carry
supports_dlr: true, ship a correctparse_dlr, serve a live endpoint, and receive nothing forever because a humannever finished a step in someone else's portal.
Evidence.
delivery_receiptsholds 2 rows, bothdelivered, both againstthe Orange provider, received
2026-09-13 15:06and2026-09-14 01:54. The Orangerail went live on real credentials at roughly
2026-09-17 20:10. Both predate that:they came from
sms-fake-orangein demo mode. Zero real Orange receipts sincego-live, and nothing anywhere says so.
Acceptance Criteria
supports_dlr. A provider withsupports_dlr = falseis neverselected for a message whose caller requires a receipt, and the refusal is
explained in the routing
Decisiontrail rather than being silent.derivable today from
delivery_receipts.provider_id+received_atwith noschema change.
no receipt inside that window, is reported as a distinct condition. A provider
with no submissions is not reported — quiet must not read as broken.
providers or dashboard screen, plus a log line and metric.
the no-traffic case. Both directions — the no-traffic half is what stops this
becoming noise that gets ignored.
Definition of Ready
probe_providers, already designed and named, andalready the would-be writer of
Provider.healthy— a DLR-wiring probe and aprovider-health probe are one job asking two questions about the same row.
Role::Jobsdispatches bykindthrough aJobHandlerregistry, withexpire_staleas the wired example to copy.it is a warning — depends on real traffic volume, which the Orange rail has not
yet produced).
dlrRegisteredAtis stored explicitly, or registration isinferred purely from receipt arrival.
Definition of Done
probe_providersimplemented as a job kind, on the existing registry.genuine instance of the condition rather than a synthetic one.
capabilities.rs's guarantee is enforced by code, and its doc comment sayswhere.
with no provider-specific special-casing.
AI Usage Declaration
and drafted this ticket.
a warning when it's not wired in"); the scoping of quiet-vs-broken is the
AI's proposal and is open to revision.
Why this is worth doing before MTN rather than after
MTN's DLR needs the same manual subscription Orange needed, through a different
portal, and it has never run — the adapter was rewritten against MTN's real
Swagger in #394 and wired into both binaries in #396, both released hours ago in
0.3.3. Without criterion 3, its failure mode is identical and equally silent:
messages send, receipts never arrive, everything reports healthy.