From b7cc1dc0ca3509574df8641cda7d3270d94fec92 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 20:05:31 -0600 Subject: [PATCH] =?UTF-8?q?forge:=20add=20patch=209=20=E2=80=94=20widen=20?= =?UTF-8?q?hop-step=20+=20drop=20"ack=20"=20from=20test=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BOT_HOP_STEP_MILLIS_DEFAULT 1500 -> 2500 - BOT_HOP_BIAS_MAX_MILLIS 8000 -> 12000 - BOT_RESPONSE_PENDING_TTL_MILLIS 45000 -> 60000 - BOT_PREFS_VERSION 3 -> 4 (forces re-default of hop_step_ms on existing bots that saved the old 1500 value) - writeAckResponse + executeTest: drop the literal "ack " prefix so test responses now start with "@[sender] ..." Field test showed two bots with token-matching `[1865]` responses both firing because the far bot scheduled its reply before the near bot's reply could propagate back through the mesh. New hop step gives ~5-8 s of margin at the 4-hop boundary. --- ...on-radio-firmware-bot-command-parity.patch | 2 +- ...n-firmware-bot-response-coordination.patch | 2 +- ...03-Allow-prefixless-firmware-bot-DMs.patch | 2 +- ...-bot-commands-with-upstream-behavior.patch | 2 +- ...t-coordination-utility-commands-and-.patch | 2 +- ...-speed-up-initial-advert-default-con.patch | 2 +- ...nses-with-request-token-for-inter-bo.patch | 2 +- ...t-suffix-and-auto-learn-known-bot-pa.patch | 2 +- ...p-drop-ack-prefix-from-test-response.patch | 92 +++++++++++++++++++ tests/firmware_bot/test_firmware_bot.cpp | 10 +- vendor/MeshCore | 2 +- 11 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 patches/meshcore/0009-Widen-hop-step-drop-ack-prefix-from-test-response.patch diff --git a/patches/meshcore/0001-Add-companion-radio-firmware-bot-command-parity.patch b/patches/meshcore/0001-Add-companion-radio-firmware-bot-command-parity.patch index 5d67ec1..d2789af 100644 --- a/patches/meshcore/0001-Add-companion-radio-firmware-bot-command-parity.patch +++ b/patches/meshcore/0001-Add-companion-radio-firmware-bot-command-parity.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Fri, 15 May 2026 11:44:21 -0600 -Subject: [PATCH 1/8] Add companion radio firmware bot command parity +Subject: [PATCH 1/9] Add companion radio firmware bot command parity --- .../companion_radio/BotCommandRegistry.cpp | 121 ++ diff --git a/patches/meshcore/0002-Harden-firmware-bot-response-coordination.patch b/patches/meshcore/0002-Harden-firmware-bot-response-coordination.patch index daa11a3..aa143fd 100644 --- a/patches/meshcore/0002-Harden-firmware-bot-response-coordination.patch +++ b/patches/meshcore/0002-Harden-firmware-bot-response-coordination.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Fri, 15 May 2026 19:58:42 -0600 -Subject: [PATCH 2/8] Harden firmware bot response coordination +Subject: [PATCH 2/9] Harden firmware bot response coordination --- examples/companion_radio/BotCommands.cpp | 2 +- diff --git a/patches/meshcore/0003-Allow-prefixless-firmware-bot-DMs.patch b/patches/meshcore/0003-Allow-prefixless-firmware-bot-DMs.patch index 6c1a284..4f779d6 100644 --- a/patches/meshcore/0003-Allow-prefixless-firmware-bot-DMs.patch +++ b/patches/meshcore/0003-Allow-prefixless-firmware-bot-DMs.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Fri, 15 May 2026 20:09:58 -0600 -Subject: [PATCH 3/8] Allow prefixless firmware bot DMs +Subject: [PATCH 3/9] Allow prefixless firmware bot DMs --- examples/companion_radio/BotPolicy.cpp | 2 +- diff --git a/patches/meshcore/0004-Align-firmware-bot-commands-with-upstream-behavior.patch b/patches/meshcore/0004-Align-firmware-bot-commands-with-upstream-behavior.patch index 650eb65..4282505 100644 --- a/patches/meshcore/0004-Align-firmware-bot-commands-with-upstream-behavior.patch +++ b/patches/meshcore/0004-Align-firmware-bot-commands-with-upstream-behavior.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 04:12:02 +0000 -Subject: [PATCH 4/8] Align firmware bot commands with upstream behavior +Subject: [PATCH 4/9] Align firmware bot commands with upstream behavior --- .../companion_radio/BotCommandRegistry.cpp | 25 +- diff --git a/patches/meshcore/0005-Add-hop-aware-bot-coordination-utility-commands-and-.patch b/patches/meshcore/0005-Add-hop-aware-bot-coordination-utility-commands-and-.patch index 31c2d73..842ca92 100644 --- a/patches/meshcore/0005-Add-hop-aware-bot-coordination-utility-commands-and-.patch +++ b/patches/meshcore/0005-Add-hop-aware-bot-coordination-utility-commands-and-.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 12:38:13 -0600 -Subject: [PATCH 5/8] Add hop-aware bot coordination, utility commands, and +Subject: [PATCH 5/9] Add hop-aware bot coordination, utility commands, and bounded delays Adds new utility commands (TIME, LORA, ID, NEIGHBORS), neighbor tracking, diff --git a/patches/meshcore/0006-Mark-bot-adverts-speed-up-initial-advert-default-con.patch b/patches/meshcore/0006-Mark-bot-adverts-speed-up-initial-advert-default-con.patch index 04a8d5c..45d74f8 100644 --- a/patches/meshcore/0006-Mark-bot-adverts-speed-up-initial-advert-default-con.patch +++ b/patches/meshcore/0006-Mark-bot-adverts-speed-up-initial-advert-default-con.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 18:58:28 -0600 -Subject: [PATCH 6/8] Mark bot adverts, speed up initial advert, default +Subject: [PATCH 6/9] Mark bot adverts, speed up initial advert, default contacts auto-overwrite Three coordination/discoverability fixes: diff --git a/patches/meshcore/0007-Prefix-bot-responses-with-request-token-for-inter-bo.patch b/patches/meshcore/0007-Prefix-bot-responses-with-request-token-for-inter-bo.patch index 6df342b..1d29e2d 100644 --- a/patches/meshcore/0007-Prefix-bot-responses-with-request-token-for-inter-bo.patch +++ b/patches/meshcore/0007-Prefix-bot-responses-with-request-token-for-inter-bo.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 19:33:04 -0600 -Subject: [PATCH 7/8] Prefix bot responses with request token for inter-bot +Subject: [PATCH 7/9] Prefix bot responses with request token for inter-bot suppression Adds a 4-hex request token (low 16 bits of the request fingerprint) as a diff --git a/patches/meshcore/0008-Drop-MCBOT-advert-suffix-and-auto-learn-known-bot-pa.patch b/patches/meshcore/0008-Drop-MCBOT-advert-suffix-and-auto-learn-known-bot-pa.patch index bd64213..c61965a 100644 --- a/patches/meshcore/0008-Drop-MCBOT-advert-suffix-and-auto-learn-known-bot-pa.patch +++ b/patches/meshcore/0008-Drop-MCBOT-advert-suffix-and-auto-learn-known-bot-pa.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: cj-vana Date: Sat, 16 May 2026 19:55:36 -0600 -Subject: [PATCH 8/8] Drop [MCBOT] advert suffix and auto-learn known-bot path +Subject: [PATCH 8/9] Drop [MCBOT] advert suffix and auto-learn known-bot path Removes BOT_ADVERT_MARKER / writeBotAdvertName / isBotAdvertName from FirmwareBot, autoLearnKnownBotAdvert and getAdvertNodeName from MyMesh, diff --git a/patches/meshcore/0009-Widen-hop-step-drop-ack-prefix-from-test-response.patch b/patches/meshcore/0009-Widen-hop-step-drop-ack-prefix-from-test-response.patch new file mode 100644 index 0000000..de24b08 --- /dev/null +++ b/patches/meshcore/0009-Widen-hop-step-drop-ack-prefix-from-test-response.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: cj-vana +Date: Sat, 16 May 2026 20:05:19 -0600 +Subject: [PATCH 9/9] Widen hop-step + drop "ack " prefix from test response + +Two changes: + +1. Coordination timing: bump BOT_HOP_STEP_MILLIS_DEFAULT 1500 -> 2500, + BOT_HOP_BIAS_MAX_MILLIS 8000 -> 12000, BOT_RESPONSE_PENDING_TTL_MILLIS + 45000 -> 60000. Bumps BOT_PREFS_VERSION 3 -> 4 so existing bots + re-derive defaults instead of carrying the old 1500 ms hop step. + + Why: a far bot (4 hops from request) was firing at ~7-10 s while a + near bot (1 hop) fired at ~3-6 s. Across 4-5 mesh hops, the near + bot's response took ~5-10 s of airtime+queueing to reach the far + bot, frequently arriving AFTER the far bot's scheduled fire time. + With 2500 ms/hop, the far bot now schedules at ~12 s, giving ~5-8 s + of margin for the near bot's response to arrive and trigger + token-based suppression. + +2. Test command response: drop the literal "ack " prefix from + writeAckResponse and BotCommands::executeTest. Responses now start + directly with "@[sender] ..." which keeps the user mention and + metadata but matches user preference for less noise. +--- + examples/companion_radio/BotCommands.cpp | 4 ++-- + examples/companion_radio/BotTypes.h | 8 ++++---- + examples/companion_radio/FirmwareBot.cpp | 2 +- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/examples/companion_radio/BotCommands.cpp b/examples/companion_radio/BotCommands.cpp +index 44357a99..1aa4406d 100644 +--- a/examples/companion_radio/BotCommands.cpp ++++ b/examples/companion_radio/BotCommands.cpp +@@ -536,9 +536,9 @@ BotCommandResult executeTest(const BotCommand& command, const BotCommandContext& + char received_at[9]; + formatSecondsHms(context.uptime_seconds, received_at, sizeof(received_at)); + if (command.args_len == 0) { +- return writeFormatted(output, output_len, "ack @[%s] local | recv %s", name, received_at); ++ return writeFormatted(output, output_len, "@[%s] local | recv %s", name, received_at); + } +- return writeFormatted(output, output_len, "ack @[%s] local | recv %s | %s", name, received_at, command.args); ++ return writeFormatted(output, output_len, "@[%s] local | recv %s | %s", name, received_at, command.args); + } + + } +diff --git a/examples/companion_radio/BotTypes.h b/examples/companion_radio/BotTypes.h +index ad249300..5a953639 100644 +--- a/examples/companion_radio/BotTypes.h ++++ b/examples/companion_radio/BotTypes.h +@@ -30,14 +30,14 @@ + #define BOT_NEIGHBOR_RECENT_MILLIS (60UL * 60UL * 1000UL) + #define BOT_RESPONSE_DELAY_BASE_MILLIS 1200UL + #define BOT_RESPONSE_DELAY_JITTER_MILLIS 1800UL +-#define BOT_RESPONSE_PENDING_TTL_MILLIS 45000UL ++#define BOT_RESPONSE_PENDING_TTL_MILLIS 60000UL + #define BOT_RESPONSE_RECENT_TTL_MILLIS 30000UL + #define BOT_KNOWN_BOT_FLAG_SUPPRESS_NORMAL 0x01 + #define BOT_SENDER_KEY_PREFIX_LEN 6 + #define BOT_MIN_AUTH_SENDER_KEY_PREFIX_LEN 4 + #define BOT_KNOWN_BOT_LABEL_LEN 12 + #define BOT_PREFS_MAGIC 0x31504642UL +-#define BOT_PREFS_VERSION 3 ++#define BOT_PREFS_VERSION 4 + #define BOT_PREFS_DEFAULT_LOCAL_ADVERT_MILLIS (24UL * 60UL * 60UL * 1000UL) + #define BOT_PREFS_DEFAULT_FLOOD_ADVERT_MILLIS (24UL * 60UL * 60UL * 1000UL) + #define BOT_PREFS_INITIAL_LOCAL_ADVERT_MILLIS 60000UL +@@ -45,9 +45,9 @@ + #define BOT_PREFS_MAX_DELAY_MILLIS 60000U + #define BOT_PREFS_MAX_ADVERT_MILLIS (7UL * 24UL * 60UL * 60UL * 1000UL) + #define BOT_PREFS_SERIALIZED_SIZE 296 +-#define BOT_HOP_STEP_MILLIS_DEFAULT 1500U ++#define BOT_HOP_STEP_MILLIS_DEFAULT 2500U + #define BOT_HOP_STEP_MILLIS_MAX 30000U +-#define BOT_HOP_BIAS_MAX_MILLIS 8000UL ++#define BOT_HOP_BIAS_MAX_MILLIS 12000UL + + enum BotChannelKind : uint8_t { + BOT_CHANNEL_DM = 0, +diff --git a/examples/companion_radio/FirmwareBot.cpp b/examples/companion_radio/FirmwareBot.cpp +index 3c310173..e228b7c8 100644 +--- a/examples/companion_radio/FirmwareBot.cpp ++++ b/examples/companion_radio/FirmwareBot.cpp +@@ -322,7 +322,7 @@ BotWriteResult writeAckResponse(const BotMessage& message, const BotCommand& com + const char* connection = message.channel_kind == BOT_CHANNEL_DM + ? "direct" + : (message.channel_name[0] ? message.channel_name : "channel"); +- int n = snprintf(output, output_len, "ack @[%s] %s", sender, connection); ++ int n = snprintf(output, output_len, "@[%s] %s", sender, connection); + if (n < 0) { + output[0] = 0; + return BOT_WRITE_NO_SPACE; diff --git a/tests/firmware_bot/test_firmware_bot.cpp b/tests/firmware_bot/test_firmware_bot.cpp index e6064fe..053cd39 100644 --- a/tests/firmware_bot/test_firmware_bot.cpp +++ b/tests/firmware_bot/test_firmware_bot.cpp @@ -539,7 +539,7 @@ static void test_ack_response_format() { char out[BOT_MAX_RESPONSE_LEN + 1]; size_t written = 0; assert(FirmwareBot::writeAckResponse(message, command, out, sizeof(out), &written) == BOT_WRITE_OK); - assert(strcmp(out, "ack @[alice] #bot | 0h SNR 0.00 | recv 21:25:45 | hello") == 0); + assert(strcmp(out, "@[alice] #bot | 0h SNR 0.00 | recv 21:25:45 | hello") == 0); assert(written == strlen(out)); message.channel_kind = BOT_CHANNEL_DM; @@ -547,7 +547,7 @@ static void test_ack_response_format() { message.channel_name[0] = 0; assert(FirmwareBot::parseCommand("!t", 2, &command)); assert(FirmwareBot::writeAckResponse(message, command, out, sizeof(out), &written) == BOT_WRITE_OK); - assert(strcmp(out, "ack @[unknown] direct | 0h SNR 0.00 | recv 21:25:45") == 0); + assert(strcmp(out, "@[unknown] direct | 0h SNR 0.00 | recv 21:25:45") == 0); uint8_t path[] = { 0x12, 0x34, 0xab, 0xcd }; message.channel_kind = BOT_CHANNEL_BOT; @@ -558,12 +558,12 @@ static void test_ack_response_format() { message.path_hash_count = 2; message.packet_snr_quarters = -5; assert(FirmwareBot::writeAckResponse(message, command, out, sizeof(out), &written) == BOT_WRITE_OK); - assert(strcmp(out, "ack @[bob] #bot | 2h@2B SNR -1.25 | recv 21:25:45") == 0); + assert(strcmp(out, "@[bob] #bot | 2h@2B SNR -1.25 | recv 21:25:45") == 0); assert(strstr(out, "Bot test OK") == NULL); char small[16]; assert(FirmwareBot::writeAckResponse(message, command, small, sizeof(small), &written) == BOT_WRITE_TRUNCATED); - assert(strncmp(small, "ack @[bob]", 10) == 0); + assert(strncmp(small, "@[bob]", 6) == 0); } static BotMessage make_message(const char* channel, const char* text) { @@ -628,7 +628,7 @@ static void test_command_outputs() { result = run_command("!test", out, sizeof(out)); assert(result.code == BOT_COMMAND_RESULT_OK); - assert_starts_with(out, "ack @["); + assert_starts_with(out, "@["); assert_contains(out, "recv "); assert(strstr(out, "Bot test OK") == NULL); diff --git a/vendor/MeshCore b/vendor/MeshCore index 459e06e..eda1478 160000 --- a/vendor/MeshCore +++ b/vendor/MeshCore @@ -1 +1 @@ -Subproject commit 459e06ee6e019e04234188641b5c540013081ea7 +Subproject commit eda14782b6decea23048f1a3228a555be2614106