A sent channel message learns its pkt_payload — and therefore its route
badge, repeater list and Analyzer link — only by hearing its own echo come
back. Correlation kept a single _pending_echo slot, so any second send or
resend overwrote it and the first message's echo was filed as foreign
traffic. Proven on prod: msg #71179 lost its badge because a resend of
#71177 fired 33 ms before its echo arrived. 16 of 471 own messages over 30
days had no payload; 3 of those were correlation failures (this bug, plus
echoes arriving 62 s and 200 s after the send, past the 60 s expiry).
- _pending_echoes: one entry per message, capped at 32, so concurrent sends
no longer evict each other
- exact-payload matching stays valid for 5 min (repeats do arrive minutes
late); the loose channel-hash fallback keeps its 60 s window because it
can grab a foreign message on the same channel
- resend re-arms from _payload_from_raw_packet() when the message has no
pkt_payload yet — previously it re-armed only when a payload already
existed, which is precisely the case that never needs repairing
Verified live against the test device: reproducing the exact prod sequence
(send, then resend an older message 0.4 s later) now correlates both, and
resending a badge-less message recovers its badge.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>