Files
meshcore-bot/modules/service_plugins
agessaman 4e49c0557f fix(path,capture): restore silently dead packet and path-scoring paths
Four code paths that produced no result, or a wrong one, without ever
logging an error. Each looked correct in review and failed only against
real inputs.

- packet_capture: read RAW_DATA from the "payload" field. meshcore's
  reader dispatches RAW_DATA as {"SNR", "RSSI", "payload"}, but the
  handler looked for "data" and "raw_hex" and returned early when it
  found neither, so every RAW_DATA event was dropped with no log line.
  Existing tests passed because they fabricated {"data": ...}. The
  sibling RX_LOG handler already preferred "payload".

- packet_capture: key both RF correlation caches on uppercase hex.
  RX_LOG_DATA cached prefixes in the lowercase the wire supplies, while
  RAW_DATA uppercased before looking up, so the two never correlated and
  no RAW_DATA packet ever picked up cached SNR/RSSI. This was masked
  until now by the drop above. The event's own SNR/RSSI are also folded
  into the lowercase spelling the rest of the pipeline reads, via an
  explicit None check so a legitimate 0 is not discarded.

- path_inference: run the bot path-validation bonus. Its scoring block
  sat inside an `if (len(decoded_path_hex) % path_n) != 0` branch, and
  for a uniform-width path that remainder is always 0, so the body was
  unreachable. A candidate with a perfect historical path match scored
  0.0 instead of 0.3. The web sibling was indented correctly.

- path_inference: compare path segments case-insensitively in the web
  variant. decoded_nodes came from the uppercased path_context while
  stored_nodes were lowercased, so a segment match was impossible for
  any path containing a hex letter; a perfect match scored 0.15 rather
  than 0.3. This raises some web decode confidence values, so the
  module docstring's byte-for-byte parity note now records the
  deliberate exception. No node resolves to a different repeater purely
  from case.

Also resolves node hop position by index rather than by value, so a
1-byte prefix appearing twice in one path no longer gives every
occurrence the neighbours and final-hop status of the first. This is
threaded through the shared engine and used by the web decode path,
which returns a list. The bot `path` command deliberately does not pass
it: repeater_info is keyed by node_id, so resolving each occurrence
separately would let the later hop overwrite the earlier one's display.
Fixing that needs repeater_info re-keyed by hop index.
2026-07-28 20:08:23 -07:00
..