feat(meshcore): channel "heard repeaters" via self-echo correlation (#3700)#3707
Conversation
…3700) MeshCore channel (broadcast) messages carry no protocol ACK, so nothing told you whether any repeater relayed an outgoing channel post. We now infer it best-effort by self-echo correlation: when a nearby repeater re-floods one of our GRP_TXT channel packets, our device hears the re-flood as an inbound `ota_packet` whose relay-hash chain names the relaying repeaters; we attribute those hashes to the most recent matching outgoing channel send within a 30s window. - New per-source side table `meshcore_heard_repeaters` (migration 102, all three backends, idempotent) — one row per (message, repeater hash), unique on (sourceId, messageId, repeaterHash), tracks max SNR. - Correlation runs on raw ota_packet data BEFORE the opt-in packet-monitor gate, so it works regardless of the monitor setting. - Relay hashes resolved to repeater names best-effort via the contact prefix resolver; raw hash shown when unknown. - Outgoing channel messages enriched with `heardBy[]`; incremental `meshcore:channel-heard` WS event (mirrors send-confirmed). - UI: count badge (📡 N) + expandable repeater list in the message stream. - Tests: pure findEchoMatch (match/window/dedup/type-gate), integration correlation (monitor-off, no-match, DM-ignored), repo per-source isolation + dedup/max-SNR/grouping. Closes #3700 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011JEaCGwY9Wz8jeV4e22GW4
|
Claude finished @Yeraze's task —— View job PR Review: feat(meshcore): channel "heard repeaters" via self-echo correlation
Overall AssessmentThis is a well-structured, thoughtfully implemented feature. The self-echo correlation approach is sound given the MeshCore protocol's lack of channel ACKs, and the implementation correctly treats it as best-effort throughout. The code quality is high overall with a few observations worth addressing. Potential Bug:
|
System Test ResultsMeshMonitor System Test ResultsTest Run: 2026-06-24 08:40:11 EDT ❌ Overall Result: FAILEDAborted on first failing test (fail-fast mode). Remaining tests skipped. Failed Test
|
System Test ResultsMeshMonitor System Test ResultsTest Run: 2026-06-24 08:49:01 EDT ❌ Overall Result: FAILEDAborted on first failing test (fail-fast mode). Remaining tests skipped. Failed Test
|
System Test ResultsMeshMonitor System Test ResultsTest Run: 2026-06-24 08:59:07 EDT ❌ Overall Result: FAILEDAborted on first failing test (fail-fast mode). Remaining tests skipped. Failed Test
|
Summary
MeshCore channel (broadcast) messages carry no protocol-level ACK, so nothing told you whether any repeater actually relayed an outgoing channel post (DMs get
meshcore:send-confirmed; channel sends don't). This adds a best-effort "heard repeaters" signal via self-echo correlation.When a nearby repeater re-floods one of our
GRP_TXT(0x05) channel packets, our device hears the re-flood as an inbound OTA packet (LogRxData→ota_packet) whose relay-hash chain (path_hops) names the relaying repeaters. We attribute those hashes to the most recent matching outgoing channel send within a 30s window. It's best-effort by design (we don't have the outgoing payload bytes to prove identity) and bounded by window + GRP_TXT type + a pending channel send — matching the issue's guidance and the original MeshCore app's heard-repeater list.What's included
meshcore_heard_repeaters(migration 102, SQLite/PostgreSQL/MySQL, idempotent). One row per (message, repeater hash), unique on(sourceId, messageId, repeaterHash), tracks max SNR. Scoped bysourceIdper the multi-source rules.ota_packetdata BEFORE the opt-in packet-monitor gate, so it works regardless of the monitor setting.recordHeardRepeater,getHeardRepeatersForMessage,getHeardRepeatersForMessages) using Drizzle query builders; outgoing channel messages enriched withheardBy[].meshcore:channel-heardWS event (mirrorsmeshcore:send-confirmed).Tests
findEchoMatch(pure): match / window-expiry / dedup / type + path gating.handleBridgeEvent('ota_packet'): records repeaters and emits the WS event with the packet monitor OFF; ignores no-match and non-GRP_TXT (DM) packets.migrationTablescoverage updated.Full Vitest suite green (7399 passed, 0 failed). Frontend build + server tsc clean.
Closes #3700
🤖 Generated with Claude Code
https://claude.ai/code/session_011JEaCGwY9Wz8jeV4e22GW4