Topic health
10 subscribed topics · each with its own staleness threshold, because qc/deferred being quiet for a day is normal and grn/counted being quiet for a day is not
Every physical receipt, from the GRN app and IWMS into i3 · payloads, idempotency keys, replay, and the events that classified correctly and were still refused a posting
Unmatched and blocked are different failures and are counted separately. Unmatched means no rule recognised the event. Blocked means a rule recognised it perfectly and the ledger refused it anyway, usually because the receipt would have violated the receipt-authority rule. v2 has no concept of the second, so a correctly-classified-but-illegal receipt reads as healthy.
10 subscribed topics · each with its own staleness threshold, because qc/deferred being quiet for a day is normal and grn/counted being quiet for a day is not
Last 60 minutes · receiving is bursty by nature, a container arrives and 40 scans land in 4 minutes
p50 / p95 / p99 in ms · the 500ms SLA is drawn · qc/outcome is slowest because it is the only topic that writes ledger rows
248 events today · idempotency is composite on (source_system, idempotency_key) and the receipt key is always keyed on the receipt event, never on the PO line
| Time | Topic | Ref | Lines | Units | Rule · conf | Idempotency key | Status | Latency | |
|---|---|---|---|---|---|---|---|---|---|
| 14:10:22 | qc/outcome | GRN-2026-0415 | 6 | 3,200 | qc_pass_clean 0.99 | qc:8841:pass:none | processed | 214 | |
| 14:08:41 | rfid/encode | GRN-2026-0415 | 1 | 1 | encode_on_accept 0.99 | rfid:encode:E280...8F3C | processed | 62 | |
| 14:04:12 | grn/counted | GRN-2026-0418 | 6 | 870 | po_match_partial 0.94 | grn:counted:GRN-2026-0418:1 | processed | 188 | |
| 13:58:03 | qc/outcome | GRN-2026-0402 | 2 | 48 | qc_pass_clean 0.97 | qc:8829:pass:none | blocked · po_closed | 142 | |
| 13:56:44 | rts/shipped | RTS-2026-0184 | 1 | 40 | - | ops2:rts_ship:RTS-2026-0184:AX-88421 | hmac failed | 18 | |
| 13:56:40 | rts/shipped | RTS-2026-0183 | 1 | 14 | - | ops2:rts_ship:RTS-2026-0183:AX-88420 | hmac failed | 16 | |
| 13:52:18 | qc/outcome | GRN-2026-0411 | 2 | 48 | qc_damaged_carrier 0.82 | qc:8824:damaged:local_fix | processed | 396 | |
| 13:48:55 | grn/counted | INF-2318 | 4 | 96 | po_match_fullqty 0.98 | grn:counted:INF-2318:1 | blocked · R-06.1 | 204 | |
| 13:44:02 | grn/short_receipt | GRN-2026-0416 | 3 | 158 | short_receipt_flag 0.91 | grn:short:GRN-2026-0416:PL-4471 | claim opened | 246 | |
| 13:40:11 | grn/created | GRN-2026-0418 | 6 | 0 | supplier_auto_match 0.96 | grn:created:GRN-2026-0418 | processed | 98 | |
| 13:34:29 | grn/overage | GRN-2026-0414 | 1 | 58 | overage_to_quarantine 0.88 | grn:over:GRN-2026-0414:PL-4462 | processed | 312 | |
| 13:28:07 | grn/counted | GRN-2026-0418 | 6 | 870 | - | grn:counted:GRN-2026-0418:1 | duplicate | 9 | |
| 13:22:14 | grn/created | INF-2321 | 0 | 0 | unmatched | grn:created:INF-2321 | drift audit | 428 | |
| 13:14:50 | grn/wrong_sku | GRN-2026-0413 | 1 | 60 | wrong_sku_quarantine 0.93 | grn:wrongsku:GRN-2026-0413:MST-CRM-42-BLK | processed | 268 | |
| 12:58:33 | rts/created | RTS-2026-0184 | 1 | 40 | qc_reject_to_rts 0.99 | iwms:rts:RTS-2026-0184 | processed | 176 | |
| 12:44:19 | qc/outcome | GRN-2026-0404 | 3 | 1,800 | qc_pass_clean 0.99 | qc:8802:pass:none | replayed by ahmad | 302 |
Classified correctly, refused a posting · the table v2 does not have
| Event | Topic | Block rule | What happened | Age | Resolution |
|---|---|---|---|---|---|
| 5139 | qc/outcome | po_closed | QC outcome for 48 units arrived 3 days after PO-2026-0104 was closed. Posting it would reopen a closed period. | 14m | reopen PO or drift |
| 5135 | grn/counted | R-06.1 | Counted event from source_system=iwms with no GRN receipt behind it. IWMS may count, but it may not create a receipt on its own. | 21m | create receipt, replay |
| 5118 | qc/outcome | buckets_unbalanced | Dispositions summed to 142 against a counted quantity of 144. The 2 missing units are not a rounding error, they are 2 units nobody named. | 2h | re-record outcome |
| 5104 | rfid/encode | encode_before_qc | Encode requested for 24 units on a line still in QC. R-06.19: a unit is encoded only after a pass disposition. | 4h | wait for QC |
| 5091 | grn/counted | location_not_permitted | Receipt posted against BAS, which has no RECEIVED_NOT_INVOICED policy row. Stores receive transfers, not supplier deliveries. | 6h | reroute to HQ_319 |
| 5077 | qc/outcome | gate_not_open | Cost-bearing disposition arrived while GATE 3 is in shadow at day 4 of 7. Held rather than posted with a provisional cost. | 11h | auto-replay at gate |
Raw body, both signatures, and the key formula
The event is well formed, correctly signed and correctly classified. It is refused because posting it would write into a closed PO period. Nothing about that is a classifier problem, which is exactly why it must not be counted as one.
7 days · click a rule to filter the stream · the receipt vocabulary is 14 rules, not 39
| Rule | Topic | Posts ledger | Share | Hits 7d | Avg conf | Blocked |
|---|---|---|---|---|---|---|
| qc_pass_clean | qc/outcome | yes | 412 | 0.98 | 1 | |
| po_match_fullqty | grn/counted | no | 322 | 0.97 | 1 | |
| encode_on_accept | rfid/encode | unit | 284 | 0.99 | 1 | |
| po_match_partial | grn/counted | no | 182 | 0.92 | 0 | |
| supplier_auto_match | grn/created | no | 148 | 0.94 | 0 | |
| qc_minor_deduction | qc/outcome | yes | 92 | 0.88 | 0 | |
| short_receipt_flag | grn/short_receipt | no | 58 | 0.91 | 0 | |
| qc_reject_to_rts | qc/outcome | yes | 44 | 0.96 | 0 | |
| qc_damaged_carrier | qc/outcome | yes | 34 | 0.84 | 0 | |
| rts_ship_to_supplier_hold | rts/shipped | yes | 26 | 0.99 | 3 | |
| overage_to_quarantine | grn/overage | yes | 21 | 0.89 | 0 | |
| sample_to_sample_qc | grn/counted | yes | 16 | 0.95 | 0 | |
| wrong_sku_quarantine | grn/wrong_sku | yes | 9 | 0.93 | 0 | |
| unsolicited_to_quarantine | grn/counted | yes | 4 | 0.79 | 1 | |
| (unmatched) | any | no | 11 | - | 0 |
The topic grid and both charts hold height. The stream fills from the top as events arrive.
Every receipt event today has classified and posted. Zero unmatched, zero blocked. This is what a good day looks like.
The projection query timed out after 8 seconds. Ingest is unaffected and events are still landing; only this view is blind.
ge-read-3d81 · 29-07-2026 14:12 GST
The stream is visible to any i3 viewer. Raw payloads and replay need role >= ops_manager plus the event_replay feature.
apps.i3.features = [grn_count]
4 filters hide all 248 events.
The cursor is at 4,182,904 and ops2 retains everything above it. Resume replays in order. Nothing is lost because the cursor, not a subscriber list, decides what is unacked.
GATE 3 is at day 4 of 7. Quantity postings run normally; dispositions that would set a landed cost are held and auto-replay when the gate closes, rather than posting a provisional number that finance would then have to unwind.
1 event held · block_rule gate_not_open
All three carry key_id=grn-2026-04, retired 22-07. The bodies are retained so a replay after the sender rotates costs nothing.