Skip to content

Relay health indicators in the relay list #294

Description

@kwsantiago

Context

Follow-up from the UI/UX overhaul (#293). The relay list in ConnectionCards.kt (RelaysCard) currently shows relay URLs as plain text with no per-relay status. Amber shows color-coded relay health (e.g. Reliable / Slow / Unknown). We want a per-relay status indicator (a colored dot + label: connected / connecting / error/offline, and ideally latency or last-seen).

The UI overhaul deliberately kept this out of scope: it was presentation-only, and relay health needs new data, not just new pixels. The shared components from #293 (the KeepListRow leading-slot + the KeepSuccess/KeepError/KeepMuted color tokens) are the rendering primitives this will use.

Architecture constraint (RMP — we rely on ../keep)

Per the RMP architecture bible (rmp-architecture-bible.md, §1.2/§1.5): networking, WebSocket connections, and relay management are owned by the Rust core (../keep), not the native layer. The golden rule is that native must not own business logic.

That means:

  • Do NOT compute relay health in Kotlin (no probing/pinging relays from the Android layer, no native success-rate tracking). That would put networking + derived business state on the native side, violating the boundary and creating logic that diverges from the core.
  • Do expose per-relay health from the keep Rust core via the FFI as state fields. The Android layer only renders what the core provides.

Concretely this is a cross-repo change:

  1. ../keep (Rust core): extend the live state to carry per-relay health. Today KeepLiveState exposes an aggregate connectionStatus: ConnectionStatus and peers: List<PeerInfo>. Add a per-relay record (e.g. RelayHealth { url, status, last_connected_ms, rtt_ms? }) computed in the core's relay manager and surfaced on KeepLiveState (or via a getRelayHealth() FFI call), pushed through the existing KeepStateCallback reconciler.
  2. Regenerate the UniFFI bindings (keep_mobile.kt) and bump keep.version.
  3. keep-android (this repo): render the health in RelaysCard using a status dot in the KeepListRow leading slot, colored from the existing tokens. Pure presentation — map the core's status enum to a color/label, nothing more.

Acceptance criteria

  • Per-relay health is produced by the keep Rust core and crosses the FFI as typed state (no native probing).
  • Each relay row shows a status dot + short label driven solely by core-provided fields.
  • No relay networking/health logic added to the Kotlin layer (decision framework §1.5 questions all answered "Rust").
  • keep.version bumped to the keep commit that adds the FFI fields; bindings regenerated.

Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthardp3Lowest PriorityuiUser interface

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions