ryu-hardware 0.1.5

Ryu Hardware Protocol (RHP v1) node backend — an extracted Core capability crate: the paired-device registry (SQLite store + revocable per-device tokens), pairing nonce verification, the Opus/WAV codec edge, the per-connection realtime session state machine (audio buffering + ambient meeting bridge), the live device-sender registry, the display-nudge loop, and the device-registry + TRMNL display HTTP surface. In-process default; Core consumes it as a NON-optional path dependency (the codec is also used by the voice module, the store backs ServerState in every build). The public ws/pair ingress route + the chat-turn orchestration (welded to Core's run_text_turn/voice/TTS session loop) stay Core-side as consumers of this crate's types.
Documentation

ryu-hardware

Ryu Hardware Protocol (RHP v1) node backend — an extracted Core capability crate. It is the node half of the protocol in apps/hardware/PROTOCOL.md: Ryu devices (watch / necklace / desk, all ESP32-S3) talk to a node over a WebSocket, either directly over WiFi (Mode B) or tunneled through the mobile app over BLE (Mode A, transparent to the node).

Role in the decomposition

A primitive lifted out of apps/core. It owns the paired-device registry, token lifecycle, the audio codec edge, the per-connection realtime session state machine, the display-nudge loop, and the device-registry + TRMNL display HTTP surface. The crate has zero dependency on apps/core (it depends only on the ryu-dashboards and ryu-meetings app-store backends for the display + ambient-meeting bridges).

Layout / key modules

  • protocol — serde structs/enums mirroring PROTOCOL.md §3 (the wire contract shared by the firmware and mobile relay).
  • store — device registry (SQLite): paired devices, per-device revocable Bearer tokens, last-seen/battery presence. DeviceStore, DeviceRecord, hash_token.
  • pairing — pairing-nonce verification and token issuance.
  • codec — the Opus/WAV codec edge, so the rest of Core sees PCM/WAV.
  • session — the realtime session state machine (audio buffering + ambient meetings bridge), the live device-sender registry, HardwareSession, TurnInput, SessionOutput.
  • nudge — the live display-nudge loop (dashboard change → device re-poll).
  • api — device-registry CRUD (/, /:device_id) + TRMNL display (/:device_id, /:device_id/image) axum router.

What stays Core-side (consumers of this crate's types)

The public ws/pair ingress route (a per-device Bearer/nonce that the global RYU_TOKEN require_auth cannot gate, plus mesh/SSRF-guarded node-URL resolution) and the chat-turn orchestration (welded to Core's run_text_turn / voice ASR / TTS session loop) stay in apps/core and consume this crate's session/protocol types.

Placement (Core vs Gateway)

The device registry, token lifecycle, and realtime session decide what runs → Core.

Consumed as

Compiled-into-core crate (non-optional path dependency): the codec is reused by the voice module and the store backs ServerState in every build.