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:
| Component | Where it runs | What it does |
|---|---|---|
| Runtime | On the robot, as a container | The ROS 2 control stack: teleoperation, camera encoding, arbitration, episode recording |
Daemon (sentineld) | On the robot host | Supervises the runtime container, fetches config, ships telemetry, syncs episodes. See The Sentinel daemon |
| Platform | Cloud | Auth, episode index, the /v1 API, webhooks, WebRTC signaling, dashboard |
| Operator clients | Browser or Meta Quest | Drive 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):
- Record — the runtime writes into
episode_NNN.in_progress/, renamed to.finalized/on stop. Finalized bags are immutable. - Report — the episode's metadata is sent to the platform, which indexes it and emits the
episode.finalizedwebhook. It is now queryable viaGET /v1/episodes. - Sync — the daemon requests an upload grant, the platform routes the episode to a configured destination, and the daemon uploads over presigned URLs.
- Verify — the platform checks the uploaded checksums against the episode's manifest; the replica becomes
verifiedand theepisode.verifiedwebhook fires. - 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.