Verification happens locally
The credential exchange, the signature validation, and the age decision all run on the verifier. No round trip is involved, so no round trip can fail.
Offline reliability
Checks are made on the verifier. Connectivity only affects when reporting catches up — not whether your door keeps moving.
01 · The five properties
The credential exchange, the signature validation, and the age decision all run on the verifier. No round trip is involved, so no round trip can fail.
A completed outcome is written to a bounded transactional on-device outbox. Once an event reports queued, its identity survives retry, process death, force-stop, reboot, response loss, and partial synchronization.
When the network comes back the outbox drains in the background. Staff do nothing; there is no “sync now” button to forget to press.
An exact retry is acknowledged without incrementing a counter twice. A replay whose payload or scope has changed fails closed rather than being accepted as new.
The counter you read after an outage is the counter you would have read without one — because the effect of delivering an event twice is defined to be the same as delivering it once.
02 · The honest model
Exactly-once delivery over an unreliable network is not achievable, and vendors who claim it are describing something else. Here is the actual model, which is stronger in the only place that matters: your numbers.
Transport
The device keeps retrying until the platform acknowledges. Duplicates are expected, not exceptional.
Identity
Each event carries a random ID assigned at enqueue time. The same event keeps that ID across every retry, restart, and reboot.
Processing
The platform claims each identity atomically before updating a counter, so a repeat is a no-op rather than a second increment.
Result
Not a delivery guarantee — an effect guarantee. It is the property your reports actually depend on.
03 · Bounds
An unbounded queue is a way of postponing a failure until it is someone else’s problem. The outbox has explicit limits, and reaching one is a visible, quarantined condition rather than a silent eviction of rows a verifier already accepted.
04 · What we will not overstate
The result is rendered to staff first and enqueued asynchronously. A process kill in the narrow interval after the result is shown but before the outbox commit can lose that one aggregate event. Every event that reports queued is durable from that point on.
This is a reporting-completeness edge case, not a verification failure: the patron was still correctly checked, and the door still moved correctly. We would rather name it than round it away.
Queue depth, queue age, and a bounded synchronization category are reported so you can see a device falling behind. Queued event bodies, credentials, mobile-ID data, and patron-derived values are never included.
Pilots include a deliberate connectivity-interruption exercise, because that is the test that matters.