mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-09-27 03:07:54 +00:00
The ESP32 observer firmware now emits a periodic /neighbors report carrying the observer's own configured region scopes (`self`) plus, for each zero-hop neighbor, the scopes fetched via an OTA scope query. This records that CONFIRMED configuration into a new nodes.configured_scope column, kept strictly separate from the existing inferred `default_scope` (observed advert transport scope) and transported_scopes (transmissions.scope_name). Provenance is modelled explicitly rather than overloading default_scope: default_scope is overwritten on every advert observation, so writing neighbor scopes there would let the next inferred observation clobber a confirmed value. A dedicated configured_scope (+ configured_scope_at) column preserves the distinction and structurally satisfies the report contract. Report semantics honored: - Only neighbors with status=="responded" update configured_scope. A timeout is NOT evidence the scopes were cleared, so it never writes. - Absence of a neighbor is never a signal: the report is size-capped and truncates by ordering, so missing != gone — no deletes ever happen. - A responded neighbor with empty scopes is a valid "no scopes configured" statement and IS stored (the handler gates on status, not emptiness). - self scopes are keyed by origin_id (the observer node pubkey) and need no OTA query. Report pubkeys are uppercase; nodes.public_key is lowercase hex, so keys are lowercased before the UPDATE. Unknown neighbors are a no-op until a later advert creates the node. - Out-of-order reports can't clobber newer data (last-write-wins on configured_scope_at). Changes: - dbschema: additive ensureConfiguredScopeColumns migration on nodes + inactive_nodes (marker nodes_configured_scope_v1), asserted via mustCol. - ingestor: handleNeighborsReport dispatch on topic meshcore/<region>/<observer_id>/neighbors (analogous to /status); Store.UpdateNodeConfiguredScope writer. - server: PRAGMA-detect configured_scope (hasConfiguredScope) and expose it + configured_scope_at on the node read path. - UI: node-detail (nodes.js + live.js) shows a "Configured scope" row marked confirmed, with last-confirmed timestamp, distinct from the observed scope. - tests: handleNeighborsReport (responded writes, timeout/absence never clears, empty-responded stored, unknown no-op) + last-write-wins. Topic format meshcore/<region>/<observer_id>/neighbors is assumed by analogy to the /status topic; noted for reviewer confirmation against the firmware. Co-Authored-By: Claude <noreply@anthropic.com>