Files
meshcore-analyzer/cmd
SaarMesh-Bot 573bbde30b test(#1598): red — relay participation must refresh nodes.last_seen
Pins the behaviour that has been silently broken since #1283/#1289.

The server's touchRelayLastSeen (cmd/server/store.go) calls
TouchNodeLastSeen, which issues `UPDATE nodes SET last_seen`. The server
opens SQLite with mode=ro (cmd/server/db.go:54), so that UPDATE fails with
"attempt to write a readonly database" on every call. The call site
discards the error:

    if err := s.db.TouchNodeLastSeen(pk, ts); err == nil {
            s.lastSeenTouched[pk] = now
    }

Net effect: nodes.last_seen tracks ADVERT arrivals only. Relay
participation has never refreshed it, so infra nodes on long advert
cadences look stale while actively carrying traffic.

Verified against a production store (live.saarmesh.de, 1388 nodes): 1362
have last_seen within one minute of their own most recent ADVERT.

Five tests, all against the ingestor (the writer-owning process, which
already resolves hop prefixes to full pubkeys for observations.resolved_path
since #1547):

  - AdvancesLastSeen      — the core regression
  - NeverGoesBackwards    — monotonic guard for out-of-order ingest
  - Debounces             — write amplification guard on the hot path
  - IgnoresEmptyAndUnknown— unresolved hops must not create rows
  - MalformedTimestamp    — unparsable rxTime is a no-op

TouchRelayNodes is stubbed as a no-op and Stats.RelayTouches added so the
suite compiles and reds on assertions rather than on a build error
(AGENTS.md § Test-First red-commit bar).

Red output:
  --- FAIL: TestTouchRelayNodes_AdvancesLastSeen
      last_seen = "2026-07-01T00:00:00Z", want "2026-07-10T12:00:00Z"
      RelayTouches = 0, want 1
  --- FAIL: TestTouchRelayNodes_Debounces
      RelayTouches = 0, want 1 (second touch should be debounced)

Refs #1598, #1611
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-19 10:16:54 +00:00
..