Retry ladder in flight
Six backoff steps then a dead letter · the ladder is per subscriber and editable
Outbound fanout to the siblings · HMAC signed, one immutable idempotency key per subscriber, retry ladder, dead letters with an owner
The sequencing checklist is the L18 guard made visible: a topic cannot be enabled until the sibling has confirmed the subscription
One row per (message, subscriber) · the idempotency key is generated once at enqueue and is immutable, so attempt 7 carries the same key as attempt 1
| Enqueued | Topic | Subscriber | Idempotency key | Att | HTTP | Latency | Next attempt | Status | ||
|---|---|---|---|---|---|---|---|---|---|---|
| 14:41:22 | i3.balance.changed | ops2 | i3:i3.balance.changed:8a11…ff02:ops2 | 1 | 202 | 118ms | - | delivered | ||
| 14:41:22 | i3.balance.changed | csd | i3:i3.balance.changed:8a11…ff02:csd | 1 | 202 | 96ms | - | delivered | ||
| 14:41:22 | i3.balance.changed | skuintel | i3:i3.balance.changed:8a11…ff02:skuintel | 3 | 503 | 10.0s | 15:11:22 | retrying | ||
| 14:39:04 | i3.unit.state_changed | rfid | i3:i3.unit.state_changed:c4d2…0091:rfid | 1 | 200 | 142ms | - | delivered | ||
| 14:34:19 | i3.reservation.confirmed | csd | i3:i3.reservation.confirmed:71bd…4a10:csd | 1 | 202 | 184ms | - | delivered | ||
| 14:31:07 | i3.claim.decided | ops2 | i3:i3.claim.decided:d902…1f77:ops2 | 1 | 202 | 96ms | - | delivered | ||
| 14:28:44 | i3.stockout.raised | ops2 | i3:i3.stockout.raised:4e18…bb31:ops2 | 1 | 202 | 128ms | - | delivered | ||
| 14:22:10 | i3.balance.changed | skuintel | i3:i3.balance.changed:2c74…8e05:skuintel | 4 | 502 | 8.4s | 16:22:10 | retrying | ||
| 14:18:33 | i3.receipt.posted | rfid | i3:i3.receipt.posted:9fa1…7c22:rfid | 1 | 200 | 210ms | - | delivered | ||
| 14:16:08 | i3.balance.changed | ops2 | i3:i3.balance.changed:6bd0…03c9:ops2 | 2 | 202 | 308ms | - | delivered on 2 | ||
| 14:12:51 | shopify.inventory_level.set | shopify | i3:shopify.inventory_level.set:aa03…5512:shopify | 0 | - | - | GATE-9 | held by gate | ||
| 14:09:12 | i3.stockout.cleared | csd | i3:i3.stockout.cleared:1d55…9902:csd | 1 | 202 | 104ms | - | delivered | ||
| 11:20:04 | i3.balance.changed | skuintel | i3:i3.balance.changed:70ae…c418:skuintel | 0 | - | - | on resume | pending, paused | ||
| 27-07 03:14 | i3.claim.decided | ops2 | i3:i3.claim.decided:5502…ae71:ops2 | 7 | 422 | 88ms | - | dead letter | ||
| 13:58:41 | i3.unit.state_changed | rfid | i3:i3.unit.state_changed:e770…2d84:rfid | 1 | 200 | 156ms | - | delivered | ||
| 13:44:02 | i3.reservation.rejected | csd | i3:i3.reservation.rejected:b311…6ff0:csd | 1 | 202 | 122ms | - | delivered | ||
| 13:31:19 | i3.balance.changed | ops2 | i3:i3.balance.changed:cd47…7b19:ops2 | 1 | 202 | 142ms | - | delivered |
Six backoff steps then a dead letter · the ladder is per subscriber and editable
Nothing is auto-discarded. A dead letter needs an owner, then either a successful replay or an explicit discard with a reason. Both are audited.
| Failed at | Topic | Subscriber | Att | Last error | Claimed by | Age | |
|---|---|---|---|---|---|---|---|
| 27-07 03:14 | i3.claim.decided | ops2 | 7 | 422 unknown anchor_key format | ahmad | 2d 11h | |
| 25-07 21:40 | i3.balance.changed | skuintel | 7 | timeout after 10.0s ×7 | fatima | 3d 17h | |
| 29-07 10:52 | i3.receipt.posted | grn | 1 | 404 endpoint not found | unclaimed 4h | 4h 12m |
A replay is not a new message. It reuses the key so that if ops2 processed attempt 4 and lost the ACK, the replay is a no-op on their side. Resetting the counter would hide how many times i3 has already knocked.
Endpoint comes from an environment variable name. There is no default URL anywhere in i3, and a subscriber with no secret reference cannot be active.
Subscriber cards keep their heights, so the sequencing checklist does not shift as counts arrive.
Six subscribers registered, four confirmed, and no message enqueued. Before Phase 2 that is the expected state, not a fault. Zero-filter names the chips doing the hiding.
The fanout worker is a separate process group and keeps draining. This page failing does not pause delivery.
Claiming or discarding a dead letter needs role >= ops_manager plus i3.outbox_admin. Payload bodies and request headers are gated the same way, since a payload can carry customer detail.
A sibling deploy window is a pause, not a stop. Messages accumulate at pending with a visible backlog age, and the fanout.backlog_age condition fires at P2 past one hour.
4,182 Shopify write-back rows are held at pending with the topic disabled until the Phase 9 cutover gate. The card shows the gate, the count and the oldest age rather than an empty tab.