GRN event stream

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

3 GRN webhooks failed HMAC verification in the last hour · all three carry key_id=grn-2026-04, which was retired on 22-07 · the GRN app is still signing with the old key, so rotate at the sender, not here · the payloads are retained and replayable once the signature verifies
The IWMS receiver is paused · nothing ingested since 29-07-2026 09:14 · ack cursor sits at 4,182,904 and ops2 is holding 41 events behind it · they will backfill on resume, and that is a property of the cursor, not a hope

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.

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

healthy stale failing idle by design
grn/created
4m ago52
stale after 4hno ledger
grn/counted
8m ago44
stale after 4hno ledger
grn/short_receipt
44m ago7
stale after 30mopens claim
grn/overage
2h ago3
stale after 12hposts QUARANTINE
grn/wrong_sku
6h ago1
stale after 24hposts QUARANTINE
qc/outcome
12m ago68
stale after 2hposts ledger
qc/deferred
19h ago2
idle after 24hno ledger
rts/created
1h ago4
stale after 12hno ledger
rts/shipped
failing0
3 HMAC failsposts ledger
rfid/encode
3m ago67
stale after 4hunit ledger

Events per minute

Last 60 minutes · receiving is bursty by nature, a container arrives and 40 scans land in 4 minutes

live
12 8 4 0 13:14 · 1 event · grn/created 13:16 · 2 events 13:18 · 3 events 13:20 · 2 events 13:22 · 4 events 13:24 · 5 events · CIC container starts landing 13:26 · 7 events 13:28 · 11 events · peak · 9 carton scans on GRN-2026-0418 13:30 · 9 events 13:32 · 6 events 13:34 · 4 events 13:36 · 3 events 13:38 · 2 events 13:40 · 1 event 13:42 · 2 events 13:44 · 4 events 13:46 · 5 events 13:48 · 3 events 13:50 · 4 events 13:52 · 7 events · QC session on GRN-2026-0415 13:54 · 6 events 13:56 · 3 events · all 3 rejected, HMAC key_id grn-2026-04 retired 13:58 · 2 events 14:00 · 4 events 14:02 · 5 events 14:04 · 3 events 14:06 · 2 events 14:08 · 4 events 14:10 · 5 events
13:1413:3013:4414:0014:10

Ingest latency by topic

p50 / p95 / p99 in ms · the 500ms SLA is drawn · qc/outcome is slowest because it is the only topic that writes ledger rows

1 topic over SLA
500ms SLA grn/created grn/created p50 · 80ms grn/created p95 · 130ms grn/created p99 · 170ms grn/counted grn/counted p50 · 120ms grn/counted p95 · 200ms grn/counted p99 · 280ms qc/outcome qc/outcome p50 · 200ms · writes 2N ledger rows qc/outcome p95 · 370ms qc/outcome p99 · 530ms · over the 500ms SLA rts/shipped rts/shipped p50 · 150ms rts/shipped p95 · 230ms rts/shipped p99 · 300ms rfid/encode rfid/encode p50 · 60ms rfid/encode p95 · 100ms
p50 p95 p99 p99 over SLA
View Saved Live · pauses on hover · L
3events selected · Blast radius: replay re-runs the classifier with today's ruleset, not the ruleset in force when the event first arrived. Ledger writes stay idempotent on the receipt key, so a replayed receipt cannot double-post. · Approval required above 10 events

Stream

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

TimeTopicRefLinesUnitsRule · confIdempotency keyStatusLatency
14:10:22qc/outcomeGRN-2026-041563,200qc_pass_clean 0.99qc:8841:pass:noneprocessed214
14:08:41rfid/encodeGRN-2026-041511encode_on_accept 0.99rfid:encode:E280...8F3Cprocessed62
14:04:12grn/countedGRN-2026-04186870po_match_partial 0.94grn:counted:GRN-2026-0418:1processed188
13:58:03qc/outcomeGRN-2026-0402248qc_pass_clean 0.97qc:8829:pass:noneblocked · po_closed142
13:56:44rts/shippedRTS-2026-0184140-ops2:rts_ship:RTS-2026-0184:AX-88421hmac failed18
13:56:40rts/shippedRTS-2026-0183114-ops2:rts_ship:RTS-2026-0183:AX-88420hmac failed16
13:52:18qc/outcomeGRN-2026-0411248qc_damaged_carrier 0.82qc:8824:damaged:local_fixprocessed396
13:48:55grn/countedINF-2318496po_match_fullqty 0.98grn:counted:INF-2318:1blocked · R-06.1204
13:44:02grn/short_receiptGRN-2026-04163158short_receipt_flag 0.91grn:short:GRN-2026-0416:PL-4471claim opened246
13:40:11grn/createdGRN-2026-041860supplier_auto_match 0.96grn:created:GRN-2026-0418processed98
13:34:29grn/overageGRN-2026-0414158overage_to_quarantine 0.88grn:over:GRN-2026-0414:PL-4462processed312
13:28:07grn/countedGRN-2026-04186870-grn:counted:GRN-2026-0418:1duplicate9
13:22:14grn/createdINF-232100unmatchedgrn:created:INF-2321drift audit428
13:14:50grn/wrong_skuGRN-2026-0413160wrong_sku_quarantine 0.93grn:wrongsku:GRN-2026-0413:MST-CRM-42-BLKprocessed268
12:58:33rts/createdRTS-2026-0184140qc_reject_to_rts 0.99iwms:rts:RTS-2026-0184processed176
12:44:19qc/outcomeGRN-2026-040431,800qc_pass_clean 0.99qc:8802:pass:nonereplayed by ahmad302

Blocked events

Classified correctly, refused a posting · the table v2 does not have

6 open
EventTopicBlock ruleWhat happenedAgeResolution
5139qc/outcomepo_closedQC outcome for 48 units arrived 3 days after PO-2026-0104 was closed. Posting it would reopen a closed period.14mreopen PO or drift
5135grn/countedR-06.1Counted event from source_system=iwms with no GRN receipt behind it. IWMS may count, but it may not create a receipt on its own.21mcreate receipt, replay
5118qc/outcomebuckets_unbalancedDispositions summed to 142 against a counted quantity of 144. The 2 missing units are not a rounding error, they are 2 units nobody named.2hre-record outcome
5104rfid/encodeencode_before_qcEncode requested for 24 units on a line still in QC. R-06.19: a unit is encoded only after a pass disposition.4hwait for QC
5091grn/countedlocation_not_permittedReceipt posted against BAS, which has no RECEIVED_NOT_INVOICED policy row. Stores receive transfers, not supplier deliveries.6hreroute to HQ_319
5077qc/outcomegate_not_openCost-bearing disposition arrived while GATE 3 is in shadow at day 4 of 7. Held rather than posted with a provisional cost.11hauto-replay at gate
A gate report that shows zero unmatched while blocks accumulate is not evidence of health, so the open block count travels with the unmatched count on every gate report (AC-06.12).

Payload · event 5139

Raw body, both signatures, and the key formula

{ "topic": "qc/outcome", "grn_ref": "GRN-2026-0402", "grn_line_ref": "GL-99114", "session_id": 8829, "plan_kind": "flat_pct", "sample_size": 10, "buckets": [ { "disposition": "pass", "remedy": "none", "qty": 46 }, { "disposition": "damaged", "remedy": "scrap", "qty": 2, "defect_code": "DENT_SCRATCH", "attribution": "carrier" } ], "photos": ["https://cdn.../qc/8829-a.jpg"], "recorded_by": "ebrahim@minimalist.ae", "occurred_at": "2026-07-29T13:58:03+04:00" }
Source system
iwms
Idempotency key
qc:8829:pass:none
Key formula
qc:<session_id>:<disposition>:<remedy>
Signature received
sha256=4f1c9a...7b2e
Signature computed
sha256=4f1c9a...7b2e · match
Key id
iwms-2026-07
Latency
142ms
Ledger rows
0 · blocked before write
Block rule
po_closed · PO-2026-0104 closed 26-07

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.

Rule frequency

7 days · click a rule to filter the stream · the receipt vocabulary is 14 rules, not 39

RuleTopicPosts ledgerShareHits 7dAvg confBlocked
qc_pass_cleanqc/outcomeyes
4120.981
po_match_fullqtygrn/countedno
3220.971
encode_on_acceptrfid/encodeunit
2840.991
po_match_partialgrn/countedno
1820.920
supplier_auto_matchgrn/createdno
1480.940
qc_minor_deductionqc/outcomeyes
920.880
short_receipt_flaggrn/short_receiptno
580.910
qc_reject_to_rtsqc/outcomeyes
440.960
qc_damaged_carrierqc/outcomeyes
340.840
rts_ship_to_supplier_holdrts/shippedyes
260.993
overage_to_quarantinegrn/overageyes
210.890
sample_to_sample_qcgrn/countedyes
160.950
wrong_sku_quarantinegrn/wrong_skuyes
90.930
unsolicited_to_quarantinegrn/countedyes
40.791
(unmatched)anyno
11-0

States

Loading
Attaching to the stream.

The topic grid and both charts hold height. The stream fills from the top as events arrive.

Empty
The inbox is drained.

Every receipt event today has classified and posted. Zero unmatched, zero blocked. This is what a good day looks like.

Receiving desk
Error
Cannot read the stream.

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

Permission
Payloads are restricted.

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]

Zero-filter
No matches.

4 filters hide all 248 events.

topic: rts/shippedstatus: processedlast hourconf < 0.5
Maintenance · receiver paused
41 events are queued at the sender.

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-blocked
Cost-bearing events are held in shadow.

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

HMAC failures
3 events rejected, none discarded.

All three carry key_id=grn-2026-04, retired 22-07. The bodies are retained so a replay after the sender rotates costs nothing.

Keyboard J K move Enter payload X select ⌘R replay C copy key B blocked only U unmatched only L pause live V cycle view ⌘K palette All shortcuts ↗
Connected to Receiving desk Sibling events IWMS events ops2 events RFID events Shopify events Rules Classifier Webhook outbox Rate limits Drift Conflicts Suppliers RTS POs and PI Audit log Ops health Settings