You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(meshcore): opt-in auto-retry for automated channel sends on zero-heard miss (#3979) (#3988)
Part 2 of #3979 (builds on merged Part 1, PR #3987, which made the
"heard repeaters" echo-attribution trustworthy).
A MeshCore channel/broadcast send is an unacked, fire-and-forget flood, so
there is no firmware ACK to confirm delivery. When the Part 1 echo signal
reports that ZERO repeaters re-flooded our packet within 30s, the message
likely reached no one. This adds an opt-in, one-shot resend for that case.
- New global setting `meshcoreChannelRetryEnabled` (default OFF), wired through
VALID_SETTINGS_KEYS, SettingsContext, and a new "MeshCore Messaging" section
in global Settings (SettingsTab).
- Applies to AUTOMATED channel senders only (Automation Engine
action.sendMessage, Auto-Acknowledge, auto-responder, auto-announce, timer
triggers), threaded via a new `autoRetryOnMiss` opt-in flag on
sendMessage/sendMessageWithResult/performScopedSend. User-initiated route
sends never opt in, so they never retry.
- New channel-retry state machine (`pendingChannelRetries`,
`maybeArmChannelRetry`, `handleChannelRetryTimeout`) parallel to and
non-colliding with the DM ack-retry (#3977/#3980): the DM path keys on the
firmware ACK CRC (toPublicKey set); the channel path keys on the echo-heard
signal (channelIdx set) — mutually exclusive branches of performScopedSend.
- One-shot: the resend goes out with isAutoRetry=true (no new message row, no
`message`/bus emit — so it cannot spawn a fresh automation) and
autoRetryOnMiss=false (re-registered for echo correlation but never re-armed).
- Pending channel retries cleared in the disconnect() bulk cleanup.
- Tests: src/server/meshcoreManager.channelRetry.test.ts covers zero-heard
resend, heard→no-resend, no-bus-reentry, one-shot, user-send never arms,
setting-off never arms, disconnect clears, and DM/channel non-collision.
- Docs: docs/features/meshcore.md (new section) + automation-engine.md note.
Closes#3979
Claude-Session: https://claude.ai/code/session_015AFBA76hsjqhsXe1BdnYub
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
-**Three actions** — send a **text** message (token expansion supported) to a channel or contact, fire a MeshCore **advert**, or **run a script** (token-expanded args).
430
430
-**Last-run telemetry** — the UI surfaces the last fire time and outcome per trigger.
431
431
432
+
## Automated Channel-Send Auto-Retry
433
+
434
+
MeshCore channel (broadcast) messages are unacked, fire-and-forget floods — unlike a direct message, there is no firmware ACK to confirm delivery. MeshMonitor instead listens for nearby repeaters re-flooding your own packet (the "heard repeaters" signal, see [Message route line](#message-route-line)). When **no** repeater is heard, the message likely reached no one.
435
+
436
+
The **MeshCore Messaging** section of global **Settings** hosts an opt-in toggle, **Auto-retry automated MeshCore channel sends** (default **off**). When enabled:
437
+
438
+
- An **automated** channel send that hears **zero** repeaters within **30 seconds** is resent **exactly once**.
439
+
- It applies only to automated senders: the [Automation Engine](/features/automation-engine)`Send message` action, Auto-Acknowledge, the [Auto-Responder](#auto-responder), [Auto-Announce](#auto-announce), and [Timer Triggers](#timer-triggers).
440
+
-**User-initiated sends are never retried** — a message you type into the send bar goes out once regardless of this setting.
441
+
- It is **one-shot**: the resend is never itself retried, so at most one extra transmission ever occurs per logical send.
442
+
- The resend does **not** create a second message bubble and does **not** re-enter the automation event bus, so it can never trigger a fresh automation.
443
+
444
+
This is **distinct from the direct-message retry**, which is always on and follows the firmware's own same-path/flood ACK cadence. Because a channel send has no delivery ACK, the retry can only guess from the heard-repeater signal — so with this enabled you may occasionally see a duplicate on the mesh if a late echo arrives right around the 30-second mark. Leave it off if duplicates are unacceptable for your deployment.
445
+
432
446
## Room Servers
433
447
434
448
Room servers (advType=3) are BBS-style MeshCore nodes that store posts and push-sync them to connected clients. The **Rooms** view in the MeshCore page lists discovered room servers and provides:
{t('settings.meshcore_channel_retry_description','When enabled, an AUTOMATED MeshCore channel/broadcast message (Automation Engine, Auto-Acknowledge, auto-responder, auto-announce and timer triggers) that hears no repeaters within 30 seconds is resent exactly once. User-initiated sends are never retried. This is opt-in, channel-only, and one-shot — distinct from the always-on retry for direct messages. You may occasionally see a duplicate on the mesh.')}
0 commit comments