Skip to content

[MeshCore P3] Resolve path_hashes to observed nodes (passive route evidence) #360

@pskillen

Description

@pskillen

Parent

Part of #267 — MeshCore Phase 3 traceroute / path parity.

Cross-repo feature (bot ingest → API resolution → UI visualization).

Repo Issue
Bot meshflow-bot#119
UI meshflow-ui#304

Problem

MeshCore packets carry a path as short repeater ID hashes (1–3 bytes per hop depending on path_hash_size / firmware), not Meshtastic numeric node IDs. Feeders already accept optional path_hashes on ingest (MeshCoreRawPacket / MeshCoreTextPacket; see openapi.yaml and meshcore_packets models). The UI traceroute flow diagram expects enriched route_nodes with meshtastic_node_id / node_id_str — we need an MC equivalent for passive paths observed on forwarded traffic.

Correction vs draft: this is not a TextMessage schema change. Path metadata lives on meshcore_packets rows today; resolution and API exposure are the gap.

Context (current code)

Proposal

  1. ADR / spike (in this PR or follow-up): how to map path_hashes[] (hex segments, variable width) → ObservedNode rows (mc_pubkey / mc_pubkey_prefix). Options to evaluate:
    • Suffix match on known pubkeys/prefixes in DB.
    • Maintain learned hash→pubkey map from path_update / discover_response / ADVERT frames over time.
    • Explicit ambiguity: multiple candidates → return ambiguous: true per hop for the UI.
  2. Resolution service in meshcore_packets (or traceroute if shared): resolve_path_hashes(path_hashes, path_hash_size_hint?) → list[ResolvedHop] with node_id_str, internal_id, confidence, ambiguous.
  3. Expose on read APIs (pick one, document in OpenAPI):
    • GET meshcore packet detail / text message detail includes resolved_path (read-only), or
    • New lightweight MeshCorePathObservation model linked to MeshCoreTextPacket for history/analytics (defer if YAGNI).
  4. Edge cases
    • 1-byte hash collisions: prefer most recently heard ObservedNode (last_heard), else mark ambiguous.
    • Unknown hash: emit placeholder hop (node_id_str: null, display hash) so UI can still render a chain.
    • Channel text (CHANNEL_TEXT): often no sender identity per ADR-0001; path may still be useful for relay visualization on the packet row.

Out of scope (defer to later #267 children)

  • Active MeshCore traceroute commands (AutoTraceRoute + bot send_traceroute).
  • Neo4j / heatmap protocol filters (separate tickets).

Depends on

Acceptance criteria

  • ADR or doc section in docs/features/traceroute/ (or meshcore) describes hash→node algorithm and ambiguity rules.
  • Unit tests: fixture docs/packets/meshcore/rx_log_data_path.json style hashes resolve when matching nodes exist; collision case covered.
  • Read API returns resolved_path (or equivalent) with stable JSON shape documented in openapi.yaml.
  • No change to Meshtastic traceroute storage/enrichment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions