32 KiB
Research Synthesis
Status
- Files synthesized: stack.md, pitfalls.md, architecture.md, prior-art.md, codex-analysis.md, PROJECT.md
- Files missing: none
- Overall confidence: HIGH
Executive Summary
This project is now a firmware-only MeshCore companion bot, not a host-side bot permission layer and not a VPS coordinator replacement by emulation. The proven path is to keep upstream meshcore-dev/MeshCore as the firmware/build substrate, use Arduino C++/PlatformIO exactly as upstream does, and add a compact Colorado Mesh bot runtime at the companion application layer. agessaman/meshcore-bot, the Colorado VPS/community coordinator, and stale Codex coordinator-first notes are useful only as behavioral/prior-art references; they must not drive the runtime architecture.
The recommended implementation is a small embedded command responder plus passive response coordinator inside examples/companion_radio/MyMesh: receive DMs and allowed channel messages, classify commands, enforce channel policy, compute semantic fingerprints, schedule bounded delayed responses, cancel when a trusted known bot has already answered, and send via existing MeshCore sendMessage() / sendGroupMessage() APIs. Normal bot traffic should be limited to private DMs, #bot, and #testing; #emergency should use a dedicated Public forwarding path with the exact required emergency announcement semantics and strict dedup/rate limiting. Do not repurpose MeshCore txdelay, direct.txdelay, or rxdelay for bot election; use bot-specific role/delay/suppression settings.
The top risks are RAK4631 flash/RAM limits, heap fragmentation, packet-pool exhaustion, unsafe text parsing, wrong channel routing, spoofed suppression, emergency amplification, hidden nodes, and companion protocol breakage. Mitigate by designing to RAK4631 first, keeping v1 commands deterministic and single-packet, using fixed static state with no hot-path heap allocation, keeping runtime suppression state in RAM, persisting only a small versioned BotPrefs, and measuring PlatformIO size deltas in CI. The user's plugged-in Heltec v3 is the correct first hardware smoke target because it is available and has generous flash, but RAK4631 BLE remains the release gate.
Key Decisions (resolved by research)
- Build in MeshCore's firmware stack. Use upstream MeshCore Arduino C++/PlatformIO and current upstream dependency pins; do not introduce ESP-IDF-only, Zephyr, Rust, embedded Python/JS, MQTT firmware logic, SQLite, or a custom radio stack. Source refs: ITEM-stack-1, ITEM-stack-4, ITEM-prior-art-1.
- Use a submodule plus patch/overlay workflow. Keep
meshcore-dev/MeshCorepinned as an upstream submodule and maintain Colorado bot code as a small patch/overlay series applied during builds. Source refs: ITEM-stack-2, ITEM-architecture-14. - Implement a firmware-resident bot, not host-side coordination. Phase 1 should generate selected bot responses directly in firmware;
meshcore-botis a behavior oracle only. Source refs: ITEM-stack-6, ITEM-prior-art-3, ITEM-pitfalls-2, ITEM-architecture-8. - Place bot logic at the companion application layer. Integrate with
MyMeshcallbacks and loop; leaveDispatcher,Mesh::routeRecvPacket(), ACKs, path returns, retransmit timing, and packet duplicate tables untouched. Source refs: ITEM-architecture-1, ITEM-stack-5. - Use strict channel policy. Normal bot handling is DMs,
#bot, and#testing; Public is ignored except for the dedicated#emergencyforwarding path. Source refs: ITEM-architecture-3, ITEM-stack-7, ITEM-prior-art-12, ITEM-pitfalls-7. - Forward emergencies explicitly and safely.
#emergencyshould produce Public text beginningEMERGENCY MESSAGE FROM <user>and preserve/truncate original text with bounded one- or two-packet formatting, deduplication, loop prevention, and rate limiting. Source refs: ITEM-architecture-4, ITEM-prior-art-12, ITEM-pitfalls-8. - Coordinate with passive listen-before-answer first. Use semantic fingerprints, bounded delayed sends, and cancellation on trusted known-bot responses. Do not add claim frames in v1. Source refs: ITEM-architecture-5, ITEM-architecture-6, ITEM-pitfalls-9, ITEM-pitfalls-10.
- Trust known bot identities only. Suppression must be keyed to known bot public keys where possible; plain group text names are spoofable hints and must not suppress emergency forwarding. Source refs: ITEM-architecture-7, ITEM-pitfalls-11.
- Design storage and RAM for RAK4631. Heltec v3 is comfortable, but the nRF52840 RAK4631 app/RAM limits define the portable v1 budget. Source refs: ITEM-stack-9, ITEM-stack-10, ITEM-stack-11, ITEM-stack-12, ITEM-architecture-10, ITEM-pitfalls-1.
- Instrument and size-gate from the start. CI should build Heltec v3 USB/BLE and RAK4631 USB/BLE, capture PlatformIO size output, and enforce bot delta thresholds after baseline. Source refs: ITEM-stack-8, ITEM-stack-13, ITEM-architecture-13, ITEM-pitfalls-1.
- Start hardware smoke tests on the plugged-in Heltec v3. Use the local Heltec v3 for first flash/build smoke only after the implementation plan is approved; expand to RAK4631 before release. Source refs: PROJECT.md, ITEM-stack-8, ITEM-stack-9.
Questions for User
Q-1: Which exact firmware MVP commands should ship first?
- Category: scope
- Why it matters: Every command adds flash, response strings, parser cases, tests, and possible airtime. The v1 command set determines whether the feature remains firmware-feasible on RAK4631.
- Default recommendation: Ship
ping,test,help/cmd,about,statuswith battery/storage, simpledice/roll, DM replies,#bot/#testingreplies, and#emergencyforwarding. Defer weather, AQI, sports, jokes via web APIs, satellite/solar forecasts, Discord/web viewer, SQLite stats, and repeater-management workflows. - Source refs: ITEM-stack-6, ITEM-prior-art-3, ITEM-architecture-8, ITEM-pitfalls-2
- Priority: HIGH
Q-2: Should the bot be enabled by default after flashing, or require explicit enable/configuration?
- Category: ux
- Why it matters: A firmware bot that responds immediately after flashing can surprise users or create channel noise if channels/known bots/tier are not configured correctly.
- Default recommendation: Default to enabled for DMs and local smoke-test commands only, but require explicit channel policy resolution and role configuration before responding on
#bot/#testing; always require explicit#emergencysource/destination channel validation before Public forwarding. - Source refs: ITEM-architecture-3, ITEM-architecture-9, ITEM-pitfalls-7, ITEM-pitfalls-16
- Priority: HIGH
Q-3: What should the default response role/tier be for the user's plugged-in Heltec v3 bot node?
- Category: ux
- Why it matters: The first hardware smoke target is also intended to become the user's bot node. Its default role affects response latency, suppression behavior, and whether it defers to fixed infrastructure.
- Default recommendation: Configure the plugged-in Heltec v3 as
LOCALorSUBURBANfor smoke tests, with a conservative 300-1500 ms response window; change role later based on deployment location. - Source refs: PROJECT.md, ITEM-stack-9, ITEM-architecture-12, ITEM-pitfalls-14
- Priority: HIGH
Q-4: What duplicate-response and latency targets are acceptable for v1?
- Category: constraints
- Why it matters: Passive suppression can reduce noise but cannot guarantee exactly-once behavior in hidden-node topologies. The target determines delay windows and whether claim frames become necessary later.
- Default recommendation: Accept rare duplicates in v1. Target p95 added latency under 3 seconds for normal channel commands and duplicate bot replies under 5-10% in field scenarios, with metrics before adding claim frames.
- Source refs: ITEM-architecture-6, ITEM-pitfalls-9, codex-analysis
- Priority: HIGH
Q-5: How should known bot identities be provisioned and maintained?
- Category: technical
- Why it matters: Suppression should trust known bot identities only, but firmware needs a bounded, field-serviceable way to store and update public keys.
- Default recommendation: Store 16 known bot full public keys plus optional labels/capability flags in versioned
BotPrefs; expose rescue CLI commands and later companion protocol commands to add/remove/list keys. - Source refs: ITEM-architecture-7, ITEM-architecture-9, ITEM-architecture-10, ITEM-pitfalls-11
- Priority: HIGH
Q-6: Should unauthenticated group-text responses ever suppress a local pending response?
- Category: risk
- Why it matters: MeshCore group text names are spoofable. Suppressing based on text alone can silence the real bot or block emergency forwarding.
- Default recommendation: For v1, allow weak group-text suppression only for low-risk normal
#bot/#testingreplies that match known bot labels and fingerprints; never use weak hints for#emergencyforwarding or safety-critical behavior. - Source refs: ITEM-architecture-7, ITEM-pitfalls-11, ITEM-pitfalls-8
- Priority: HIGH
Q-7: What exact #emergency behavior should occur when the original text is too long?
- Category: ux
- Why it matters: MeshCore text/frame limits mean the required emergency header plus original text may not fit in one message. Truncation policy affects safety and airtime.
- Default recommendation: Use a two-stage formatter when needed: first Public packet
EMERGENCY MESSAGE FROM <user>, second Public packet containing the original text truncated to fit with an explicit truncation marker. Do not send unlimited multipart emergency messages in v1. - Source refs: ITEM-architecture-4, ITEM-pitfalls-5, ITEM-pitfalls-8, ITEM-prior-art-2
- Priority: HIGH
Q-8: What channel names and matching rules should be canonical?
- Category: technical
- Why it matters: Channel indexes are local and can change; substring matching could make the bot respond on unintended channels such as
#botnet. - Default recommendation: Use exact normalized channel names
Public,#bot,#testing, and#emergency; resolve to channel details at boot and after channel changes; refuse channel operation if names are missing, duplicated, or ambiguous. - Source refs: ITEM-architecture-3, ITEM-pitfalls-7
- Priority: HIGH
Q-9: What persistent configuration surface is acceptable for v1?
- Category: technical
- Why it matters: Appending to
NodePrefscan break existing binary layout, but compile-time-only config is hard to field-tune. - Default recommendation: Add a separate versioned
/bot_prefs_v1file with magic/version/length/CRC for enable flag, tier, delay/jitter, cooldowns, allowed channels, emergency mapping, known bots, command bitset, and small stats reset marker. Do not insert fields into existingNodePrefsoffsets. - Source refs: ITEM-architecture-9, ITEM-pitfalls-15, ITEM-pitfalls-16, ITEM-prior-art-10
- Priority: HIGH
Q-10: What are the hard size budgets for accepting v1?
- Category: constraints
- Why it matters: Research estimates are feasible but unmeasured locally because PlatformIO was unavailable. The plan needs explicit thresholds to prevent feature creep.
- Default recommendation: Treat RAK4631 BLE as the gate: aim for <=25 KB incremental app flash and <=2 KB static RAM initially; hard-review anything above 40-60 KB flash or 4 KB RAM. Persistent bot config should stay under 4 KB. Capture exact deltas in CI.
- Source refs: ITEM-stack-10, ITEM-stack-11, ITEM-stack-12, ITEM-stack-13, ITEM-architecture-10, ITEM-architecture-11, ITEM-pitfalls-1
- Priority: HIGH
Q-11: Should private key import/export be disabled in production bot builds?
- Category: risk
- Why it matters: Known-bot trust makes bot identities valuable. If private keys remain exportable/importable, a compromised host or BLE session can clone a trusted bot identity.
- Default recommendation: Disable private key export/import for production bot firmware. Use a separate provisioning build or a physical-button-gated temporary window if identity migration is required.
- Source refs: ITEM-pitfalls-18
- Priority: HIGH
Q-12: What host/app protocol extensions are needed in v1, if any?
- Category: technical
- Why it matters: New companion protocol frames can break apps if they collide with existing commands or appear unexpectedly. But field config and stats need some access path.
- Default recommendation: Keep v1 usable with rescue CLI plus minimal queried stats/config frames only. Gate all new protocol commands by firmware capability/version and never change existing frame semantics.
- Source refs: ITEM-architecture-9, ITEM-architecture-13, ITEM-pitfalls-13
- Priority: MEDIUM
Q-13: Which hardware targets define “done” for the first release candidate?
- Category: constraints
- Why it matters: The project wants all companion device types eventually, but first release quality needs a focused representative set.
- Default recommendation: Inner-loop builds: Heltec v3 USB, Heltec v3 BLE, RAK4631 USB, RAK4631 BLE. First hardware smoke: the plugged-in Heltec v3. Release gate: RAK4631 BLE builds and passes size/stress tests. Expand all companion builds after representative success.
- Source refs: PROJECT.md, ITEM-stack-8, ITEM-stack-9, ITEM-stack-10, ITEM-pitfalls-17
- Priority: MEDIUM
Q-14: How much telemetry should be exposed to users versus debug tooling?
- Category: ux
- Why it matters: Operators need visibility into suppression and hidden nodes, but normal users should not see noisy internal state over LoRa.
- Default recommendation: Expose compact local stats through CLI/protocol (
observed,sent,suppressed,duplicates,emergency forwards, queue failures, storage used/total). Do not post coordinator diagnostics into normal channels except explicit debug commands. - Source refs: ITEM-architecture-13, ITEM-pitfalls-12, ITEM-pitfalls-4
- Priority: MEDIUM
Q-15: Should future explicit claim frames be planned in the protocol now, even if disabled in v1?
- Category: technical
- Why it matters: Planning the fingerprint/state model now can avoid repainting the architecture later, but implementing claims immediately adds airtime and spoofing risks.
- Default recommendation: Reserve state-machine hooks and stats for
known_claim_seen, but do not transmit claim frames in v1. If later added, claims must be compact, versioned, length-checked, fingerprint-bound, scoped, and authenticated by known bot identity. - Source refs: ITEM-architecture-6, ITEM-architecture-7, ITEM-pitfalls-9, ITEM-pitfalls-11
- Priority: MEDIUM
Technical Direction
Stack
- Firmware/runtime: C++ in upstream MeshCore companion firmware, Arduino framework, PlatformIO, upstream dependency pins preserved. Source refs: ITEM-stack-1, ITEM-stack-4.
- Repository shape: wrapper repo with pinned
upstream/MeshCoresubmodule, Colorado overlay files, and deterministic patch queue applied into a build worktree. Source refs: ITEM-stack-2, ITEM-architecture-14. - Target baseline: current MeshCore main pinned intentionally, not stale local-only assumptions. Source refs: ITEM-stack-3.
- Build matrix: use upstream
build.sh; inner loop buildsHeltec_v3_companion_radio_usb,Heltec_v3_companion_radio_ble,RAK_4631_companion_radio_usb, andRAK_4631_companion_radio_ble; later run all companion builds. Source refs: ITEM-stack-8. - Firmware coding style: fixed-size arrays/ring buffers, compile-time flags, no heap allocation in receive/parse/schedule/send paths, bounded
char[]parsing, terse single-packet responses. Source refs: ITEM-stack-5, ITEM-pitfalls-3, ITEM-pitfalls-5, ITEM-pitfalls-6. - Host-side tooling: Python only for tests, fixtures, worktree/patch tooling, simulations, and size-report parsing. No Python runtime dependency in deployed firmware. Source refs: ITEM-stack-14.
Architecture
The bot should be a FirmwareBot/BotRuntime owned by companion MyMesh. MyMesh adapts MeshCore callbacks into compact BotMessage inputs, invokes policy/classification/execution/coordination, and sends approved BotResponse outputs through existing MeshCore send APIs. Core modules should be:
BotPolicy: enabled state, exact channel policy, known bots, command bitset, emergency rules, rate limits.CommandClassifier: bounded normalization, prefix/verb matching, semantic fingerprint inputs.CommandExecutor: fixed C++ handlers for v1 commands with short response buffers.ResponseCoordinator: passive listen-before-answer FSM and fixed pending/recent tables.EmergencyForwarder: dedicated#emergencyto Public path with dedup, loop prevention, and bounded formatting.BotPrefs/KnownBotRegistry/BotStats: small persisted config, explicit trusted keys, and metrics.
Recommended v1 data flow:
- MeshCore receives/decrypts a DM or group message and invokes
MyMeshcallbacks. BotPolicyrejects all normal Public traffic and only allows DMs,#bot, and#testing;#emergencyis diverted toEmergencyForwarder.CommandClassifierparses(const char*, length), normalizes only safe ASCII command verbs, and derives a 64-bit semantic fingerprint from stable application fields.CommandExecutorcreates a short candidate response without allocating a MeshCore packet.ResponseCoordinatorschedules the response in a fixed table using role/delay/jitter/score. It does not allocate a packet until the timer wins.- If a trusted known bot response for the same fingerprint is heard first, the pending response is suppressed and stats are updated.
- When due,
MyMeshsends a single concise DM/group message via existing APIs. - Runtime fingerprints, suppression windows, emergency recent cache, and counters remain bounded and mostly volatile.
Storage / Flash / RAM Estimates
| Target | Hardware/app region facts | Current signal from research | Recommended v1 bot budget | Implication |
|---|---|---|---|---|
| Heltec WiFi LoRa 32 V3 | ESP32-S3, 8 MB flash, 512 KB SRAM, no PSRAM; PlatformIO default 8 MB partition gives ~3,342,336 bytes per OTA app slot and ~1,572,864 bytes SPIFFS | v1.15 release app signals around 615 KB USB / ~1.2 MB BLE non-merged; Heltec has wide flash margin | 10-25 KB flash target, hard review above 40-60 KB; 0.5-4 KB RAM; 0-4 KB persistent bot prefs | Comfortable first smoke target. Do not optimize for Heltec alone because it hides RAK constraints. Source refs: ITEM-stack-9, ITEM-stack-11, ITEM-stack-12, ITEM-pitfalls-1 |
| RAK4631 | nRF52840, 1 MB flash, 256 KB RAM; MeshCore companion app capped at 712,704 bytes and RAM region ~237,568 bytes after SoftDevice/linker reservations | v1.15 UF2 assets ~933-949 KB container / ~467-475 KB zip proxy; exact ELF headroom requires local PlatformIO build | Aim <=25 KB additional flash and <=2 KB static RAM initially; design under 4 KB runtime RAM and under 4 KB filesystem storage; hard review above 40-60 KB flash or 4-8 KB RAM | Release gate and limiting target. No large help text, APIs, databases, logs, dynamic plugins, or persistent histories. Source refs: ITEM-stack-10, ITEM-stack-11, ITEM-stack-12, ITEM-architecture-10, ITEM-architecture-11, ITEM-pitfalls-1 |
Concrete compact state target: 8-12 pending coordinator entries, 16-24 recent fingerprint entries, 16 known bot keys, counters under 256 B, and one shared 160-byte response scratch buffer. Persistent storage should contain only versioned config and known bot keys; suppression history and emergency caches should be RAM-only.
Prior Art to Leverage
- Upstream MeshCore companion firmware: patch base, transport, storage, send APIs, callbacks, and multi-target build system. Source refs: ITEM-prior-art-1.
- MeshCore companion protocol: short-message and storage-report constraints; useful for future stats/config access, not a runtime bot API. Source refs: ITEM-prior-art-2.
- agessaman meshcore-bot: command names, channel policy concepts, cooldown/rate-limit behavior, and response wording. Do not port HTTP/API/SQLite/plugins. Source refs: ITEM-prior-art-3.
- Colorado Mesh community/VPS bot: observable coordination semantics: DMs bypass, channel responses coordinated, local scoring, fallback delays. Preserve concepts without preserving host infrastructure. Source refs: ITEM-prior-art-4.
- Meshtastic firmware modules: proof that small fixed embedded modules are the right pattern; use bounded config, static messages, rate limits, and compile-time flags. Source refs: ITEM-prior-art-5.
- disaster.radio console: practical model for bounded firmware command parsing. Source refs: ITEM-prior-art-6.
- Cyclenerd meshcore-bot: conservative scope lesson: DM/private/opt-in channels are safer than Public. Source refs: ITEM-prior-art-8.
- LoRa APRS and MESH-API/MESH-AI: conceptual lessons for duplicate buffers, origin markers, and loop prevention, but do not reuse GPL/heavy host code in firmware. Source refs: ITEM-prior-art-7, ITEM-prior-art-9.
Detailed Planning Implications
- Repository initialization: create wrapper repo structure, add/pin MeshCore submodule, define overlay/patch application script, and document exact upstream SHA. Verify upstream builds before bot patches. Source refs: ITEM-stack-2, ITEM-stack-3, ITEM-architecture-14.
- Build/tooling gate: add
scripts/build-representative.shto apply patches, build Heltec v3 USB/BLE and RAK4631 USB/BLE, parse PlatformIO size output, and archive artifacts. Source refs: ITEM-stack-8, ITEM-stack-13, ITEM-pitfalls-1. - First smoke target: after plan approval, use the plugged-in Heltec v3 for first firmware smoke because it is locally available and has generous flash. Keep flashing steps explicit and reversible. Source refs: PROJECT.md, ITEM-stack-9.
- RAK4631 release gate: do not declare firmware feasibility complete until RAK4631 BLE builds with measured app/RAM headroom and passes stress tests. Source refs: ITEM-stack-10, ITEM-pitfalls-1.
- Patch boundaries: keep patches small: bot source files,
MyMeshhook/adapters,BotPrefs/DataStore integration, optional CLI/protocol constants, and CI/build flags. Source refs: ITEM-architecture-14. - Parser first: implement bounded
(ptr,len)parser/normalizer with unit/fuzz cases for max-length messages, missing colon, repeated colon, UTF-8, NUL, controls, empty commands, and exact channel names. Source refs: ITEM-pitfalls-6. - Policy before execution: implement exact channel resolution and disabled/conservative defaults before adding command handlers so Public noise is structurally impossible. Source refs: ITEM-architecture-3, ITEM-pitfalls-7.
- Emergency path as its own step: implement
EmergencyForwarderseparately from normal command execution, with dedup TTL, loop prevention, formatting tests, and rate-limit counters. Source refs: ITEM-architecture-4, ITEM-pitfalls-8. - Command MVP: add short deterministic command handlers and golden behavior fixtures from
meshcore-bot; ensure every output fits MeshCore text constraints with node-name prefix. Source refs: ITEM-stack-6, ITEM-pitfalls-5, ITEM-prior-art-3. - Coordinator FSM: implement fixed-size passive suppression after basic command handling works; defer any claim frames. Verify all state transitions, TTL expiry, queue-full, and cancel-on-known-response paths. Source refs: ITEM-architecture-6, ITEM-pitfalls-4, ITEM-pitfalls-9.
- Known bot registry: implement full-key storage, labels, bounded capacity, and trust decisions before allowing suppression across nodes. Source refs: ITEM-architecture-7, ITEM-pitfalls-11.
- Persistence isolation: add versioned
BotPrefs; do not mutate existingNodePrefsbinary layout. Default disabled/safe on missing, corrupt, or incompatible prefs. Source refs: ITEM-architecture-9, ITEM-pitfalls-16. - Instrumentation: add
BotStatsfrom day one, including observed, eligible, scheduled, sent, suppressed, weak-suppressed, emergency forwarded, duplicate emergency, queue/pool failures, and storage totals. Source refs: ITEM-architecture-13. - No hot-path heap: add review/static checks forbidding
String,malloc/new,std::vector, maps, JSON builders, and variable heap strings in bot receive/parse/schedule/send code. Source refs: ITEM-pitfalls-3. - Protocol compatibility: keep new companion protocol frames optional/query-only in v1; no unsolicited new frames to old apps unless version/capability-gated. Source refs: ITEM-pitfalls-13.
- Security/release flags: decide production key export/import policy before distributing trusted bot firmware. Source refs: ITEM-pitfalls-18.
Risk Register
| Priority | Risk | Impact | Mitigation | Source refs |
|---|---|---|---|---|
| CRITICAL | RAK4631 BLE exceeds flash/RAM | Build failure or unstable constrained target | Treat RAK4631 BLE as gate; CI size deltas; cap v1 at compact command set | ITEM-pitfalls-1, ITEM-stack-10, ITEM-stack-12 |
| CRITICAL | Python bot feature creep | Firmware bloat, off-grid failure, unmaintainable partial clone | Firmware MVP only; Python as behavior oracle; defer API/web/SQLite features | ITEM-pitfalls-2, ITEM-stack-6, ITEM-prior-art-3 |
| CRITICAL | Heap fragmentation | Long-running crashes, packet allocation failures, BLE instability | Fixed arrays/rings, no hot-path heap, bounded buffers, no String/JSON |
ITEM-pitfalls-3 |
| CRITICAL | Packet pool/offline queue exhaustion | Dropped user traffic and failed sends | Keep pending responses separate from packets; allocate only when timer wins; small fixed pending table | ITEM-pitfalls-4 |
| CRITICAL | Unsafe parsing | Buffer errors, command misfires, corrupted output | (ptr,len) parser, explicit NUL bounds, snprintf, fuzz/unit tests |
ITEM-pitfalls-6 |
| CRITICAL | Wrong channel routing | Bot answers on Public or misses emergency policy | Exact channel name/hash resolution, diagnostics, refuse ambiguous config | ITEM-pitfalls-7, ITEM-architecture-3 |
| CRITICAL | Emergency forwarding loops/amplification | Public flood during emergencies | Separate emergency path, idempotency TTL, no recursive forwarding, rate limits | ITEM-pitfalls-8, ITEM-architecture-4 |
| CRITICAL | Spoofed suppression | Malicious/mistaken node silences real bots | Known bot public keys; weak hints only for low-risk channels; no weak emergency suppression | ITEM-pitfalls-11, ITEM-architecture-7 |
| CRITICAL | Blocking companion loop | BLE/serial/radio/display stalls | Timestamp FSM in loop(), no delay(), no busy waits |
ITEM-pitfalls-12, ITEM-architecture-6 |
| CRITICAL | NodePrefs layout breakage | Existing settings corrupted | Separate versioned BotPrefs; default safe on invalid prefs |
ITEM-pitfalls-16, ITEM-architecture-9 |
| CRITICAL | Target-specific APIs break portability | Works on Heltec only; fails nRF/RP2040/STM32 | Platform-neutral bot core behind MyMesh/DataStore abstractions; representative build matrix |
ITEM-pitfalls-17 |
| CRITICAL | Production key export/import remains enabled | Trusted bot identity can be cloned | Disable export/import in production bot firmware or gate provisioning | ITEM-pitfalls-18 |
| MODERATE | Text/frame limits truncate replies | Lost context and high airtime from multipart chatter | Single-packet command responses; emergency two-message max when needed | ITEM-pitfalls-5, ITEM-prior-art-2 |
| MODERATE | Passive suppression cannot solve hidden nodes | Duplicate replies still occur | Set expectations, measure, deterministic jitter, optional authenticated claims later | ITEM-pitfalls-9 |
| MODERATE | Bad semantic fingerprint | False suppression or missed duplicates | Fingerprint stable app fields, not raw packet hash or text alone; tests | ITEM-pitfalls-10, ITEM-architecture-5 |
| MODERATE | RSSI/SNR overused as “closest” signal | Wrong bot wins | Use SNR/RSSI only as weak zero-hop/direct hint; tier/health/path/tiebreaker dominate | ITEM-pitfalls-14 |
| MODERATE | Flash wear/storage fill | DataStore corruption or lost contacts/channels | Persist only config; runtime caches in RAM; lazy coarse counters only | ITEM-pitfalls-15, ITEM-prior-art-10 |
Conflicts & Tradeoffs
- Heltec-first smoke vs RAK-first design. The plugged-in Heltec v3 is the right first hardware smoke target, but its 8 MB flash can hide the real release constraint. Resolution: smoke on Heltec, budget and release-gate on RAK4631 BLE. Source refs: PROJECT.md, ITEM-stack-9, ITEM-stack-10, ITEM-pitfalls-1.
- Full firmware bot vs Python feature parity. Firmware-only is the project goal, but Python bot parity is not feasible on RAK4631-class MCUs. Resolution: firmware-native MVP with deterministic local commands; host/Python remains only a behavior reference and tooling source. Source refs: ITEM-stack-6, ITEM-pitfalls-2, ITEM-prior-art-3.
- Passive suppression vs exactly-once responses. Passive suppression saves airtime and avoids new frames but cannot guarantee exactly-once under hidden nodes. Resolution: passive first with metrics; future authenticated claims only if field data demands. Source refs: ITEM-architecture-6, ITEM-pitfalls-9, codex-analysis.
- Known identity security vs group-channel realities. Strong suppression wants full public-key identity, but plain group text carries spoofable sender names. Resolution: full-key registry for authoritative trust; weak hints only for low-risk channels; no weak emergency suppression. Source refs: ITEM-architecture-7, ITEM-pitfalls-11.
- Config flexibility vs storage/migration safety. Field operators need tuning, but
NodePrefsbinary layout is fragile and storage is finite. Resolution: separate compact versionedBotPrefs, CLI rescue, optional protocol config later. Source refs: ITEM-architecture-9, ITEM-pitfalls-16. - Emergency reliability vs airtime conservation. Public emergency forwarding may duplicate under hidden nodes, but suppressing too aggressively can drop critical alerts. Resolution: short idempotent forwards, longer emergency dedup TTL, no recursive forwarding, tolerate identical duplicates over missed emergencies. Source refs: ITEM-architecture-4, ITEM-pitfalls-8.
- Topology tier policy vs actual RF quality. LOCAL/SUBURBAN/HILLTOP/MOBILE is useful operator intent but not true proximity. Resolution: role is a delay/score bias, not the sole winner; combine with directness, path freshness, queue health, and deterministic tiebreaking. Source refs: ITEM-architecture-12, ITEM-pitfalls-14.
- Codex supplemental analysis vs refreshed research. Codex recommended useful general cautions, but it was coordinator-first/stale relative to the firmware-only pivot. Resolution: use Codex only where it aligns with refreshed Claude research on passive soft coordination, hidden nodes, airtime, and embedded constraints; ignore host/coordinator-first conclusions. Source refs: codex-analysis, ITEM-stack-6, ITEM-architecture-1.
Confidence Assessment
| Dimension | Status | Confidence | Notes |
|---|---|---|---|
| stack | complete | HIGH | Clear firmware stack: upstream MeshCore Arduino C++/PlatformIO, submodule/patch workflow, representative builds, storage budget estimates. |
| pitfalls | complete | HIGH | Strong local-code-backed risks for RAK4631 limits, heap, queues, parsing, channel routing, emergency loops, protocol compatibility, and keys. |
| architecture | complete | HIGH | Clear companion-layer module architecture, policy/classifier/executor/coordinator split, BotPrefs, known bot registry, stats, passive FSM. |
| prior-art | complete | HIGH | Strong prior art from upstream MeshCore, Python/community bots, Meshtastic modules, disaster.radio, and host-bot examples. |
| codex-analysis | complete | MEDIUM | Optional supplemental research only; stale coordinator-first framing must not override refreshed firmware-only research. Useful only for general embedded cautions. |