Sentinel

How Sentinel works

The components of a Sentinel deployment and how a robot, the daemon, and the cloud fit together.

Sentinel does live teleoperation over WebRTC and records every attempt as a training-ready episode. Four components:

ComponentWhere it runsWhat it does
RuntimeOn the robot, as a containerThe ROS 2 control stack: teleoperation, camera encoding, arbitration, episode recording
Daemon (sentineld)On the robot hostSupervises the runtime container, fetches config, ships telemetry, syncs episodes. See The Sentinel daemon
PlatformCloudAuth, episode index, the /v1 API, webhooks, WebRTC signaling, dashboard
Operator clientsBrowser or Meta QuestDrive the robot; camera feeds arrive peer-to-peer over WebRTC

On the robot

The daemon is the only thing installed on the host — one systemd service. It starts the runtime container and handles everything that crosses the host boundary:

  • The runtime writes episodes into /var/lib/sentinel/datasets (mounted into the container at /datasets); the daemon watches that directory and syncs it. Your own tools can read the same directory — the on-disk layout is a stable format.
  • The daemon enrolls once with a license key and holds the device identity. The runtime gets short-lived tokens from the daemon.
  • Uploads use short-lived, per-episode grants issued by the platform. The robot stores no cloud credentials.

Teleoperation

The robot keeps an always-on connection to signaling. When an operator selects it, the platform matches the two and they negotiate a direct WebRTC link: cameras stream robot→operator, XR input streams back. Media is peer-to-peer; the cloud never relays video.

Episodes

Each recorded attempt is an episode — a ROS 2 bag (MCAP) plus metadata. The platform indexes the metadata; the recorded contents go only to storage you configure (see data custody):

  1. Record — the runtime writes into episode_NNN.in_progress/, renamed to .finalized/ on stop. Finalized bags are immutable.
  2. Report — the episode's metadata is sent to the platform, which indexes it and emits the episode.finalized webhook. It is now queryable via GET /v1/episodes.
  3. Sync — the daemon requests an upload grant, the platform routes the episode to a configured destination, and the daemon uploads over presigned URLs.
  4. Verify — the platform checks the uploaded checksums against the episode's manifest; the replica becomes verified and the episode.verified webhook fires.
  5. Prune (optional) — with a verified-sync retention policy, the daemon deletes the local copy once every destination has verified.

From there the episodes API is the index: query, annotate, curate into datasets, snapshot, export.