Skip to content

Node "Heard By" card: decide whether to show direct-RF observers (defer) #76

Description

@dborup

Why this issue exists

Upstream merged Kpa-clawbot/CoreScope#2057 ("list only observers that heard the node on air"). This issue records the options so we can decide later. Nothing is planned yet.

What we do today

GetNodeHealth and GetBulkHealth (cmd/server/store.go) walk byNode[pubkey], meaning every transmission the node is involved in: as originator, as destination, or as a resolved relay hop. For each transmission they aggregate the representative observation's observer, SNR and RSSI. The "Heard By" card on the node page shows that list with packet count, avg SNR and avg RSSI.

The same observers array feeds:

  • the home page, through the My Nodes "Heard by" line (home.js);
  • the Analytics "most observers" ranking (analytics.js, via bulk-health);
  • the Live node panel (live.js).

Known problem: the SNR and RSSI in a row belong to whichever node last transmitted the copy the observer received, often a repeater, and not to the node the card is about. For a repeater, the list mixes observers that hear it on air with observers that only heard its traffic further downstream.

Options

A. Keep today's behaviour

Pros

Cons

  • The SNR and RSSI columns are misleading. They describe the last transmitter, not the node.
  • "Heard by" suggests radio range that often isn't there, which matters most for repeater owners judging coverage.
  • The card label and the data disagree.

B. Port upstream Kpa-clawbot#2057

Rule: flood routes credit the last path hop; an empty flood path credits the ADVERT originator; the hop must resolve to exactly one relay-capable node; direct routes never credit. The results come from a background recomputer (every 5 min, full pass over all observations under the store read lock) and are published as an atomic snapshot. Observers outside the direct set are reported as relayObserverCount.

Pros

  • Signal numbers are attributed to the node that actually transmitted.
  • Requests are cheap: reads are O(direct observers) from a snapshot.
  • Upstream parity makes future upstream health-card changes easier to take.

Cons

  • Zero-hop adverts are dropped. Firmware sends them as ROUTE_TYPE_DIRECT with path_len = 0 (Mesh::sendZeroHop), and the rule excludes every direct route. That is the clearest direct-RF evidence there is. We reported it upstream on fix(node-health): list only observers that heard the node on air Kpa-clawbot/CoreScope#2057; it is unresolved at the time of writing.
  • Sparse result. By upstream's own numbers, only 234 of 1,860 nodes get any direct observer, so for most nodes the card becomes an empty list plus a relay count.
  • Uniqueness is not proof. The last-hop credit relies on 1-byte prefixes. A hop matching exactly one known node can still belong to an unknown node, or to a node in another region that shares the prefix.
  • Semantic change elsewhere. observers changes meaning in home.js, analytics.js and live.js, which upstream did not update or test.
  • Cost. One more recomputer holding s.mu.RLock over the whole store (about 63 ms per 3M observations in upstream's benchmark), and data up to 5 min stale.
  • Merge conflicts with fix(nodes): separate advert timestamps from confirmed relay activity #64 in GetNodeHealth and GetBulkHealth.

C. Own variant: direct RF from the node's own adverts only

Credit an observer as "heard directly" only for observations of the node's own ADVERT with an empty path, covering both flood adverts with an empty path and zero-hop direct adverts. Show all other observers as a count, without signal numbers.

Pros

  • No prefix guessing: the advert carries the pubkey in the clear, and an empty path means the observer heard the node itself. SNR and RSSI are genuinely the node's.
  • Can be computed per request without a recomputer, because it only walks observations of the node's own adverts (few per node). No new lock hold over the whole store.
  • Covers repeaters well, since they send periodic zero-hop adverts.
  • Small, self-contained change, with a lower conflict surface than B.

Cons

  • Misses nodes that are heard directly but whose adverts never reach an observer zero-hop, for example companions that rarely advert, or nodes heard only through their traffic.
  • Diverges from upstream, so future upstream changes to this card need manual merging.
  • Still changes what observers means for home, analytics and live, so those consumers need a deliberate decision (keep the old list under a new field, or relabel).

Suggested decision criteria

Not in scope

No implementation, staging or upstream work until a decision is made here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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