A teleop session binds one robot to one human operator for the duration of a remote-control attachment. In ClutchCall robotics, the session is the unit that the Operations wallboard renders and that the admin overview rolls up: it carries the link quality, the safety state, and the operator who is holding the robot right now. Two console screens read this model:

The session record

Each live session exposes the following fields. The wallboard card renders all of them. A session appears on the wallboard once it is attached; the header’s “N attached” count is simply the number of session records returned.

Safety states

Six states exist. The console treats them as a fixed set — each has its own colour token and its own one-line meaning, both used consistently by the wallboard pills and the overview’s Sessions by state table. PROTECTIVE_STOP and DIVERGED are the two states the wallboard treats as alarms: the card border and background pick up the state colour instead of the neutral panel styling, and the state hint is coloured rather than muted.

How the wallboard orders sessions

Cards are sorted by a fixed priority so that the sessions needing a human look are the ones at the top of the grid:
The screen header also carries a live count chip for ARMED, DEGRADED, DIVERGED and PROTECTIVE_STOP, coloured per state. States with no sessions show 0 rather than disappearing.

Divergence, velocity scale, and RTT

The three numbers on a session card are the ones that decide whether a session stays armed. The card highlights them at these display thresholds: velocityScale is shown as a rounded percentage of full speed, so anything under 100% means the session is being scaled back — which is exactly the condition DEGRADED describes. Treat these as the console’s display thresholds for drawing attention, not as the control limits enforced on the edge. On the dispatch side, the admin overview highlights a matched RTT above 250 ms when it reports a successful match, because that is the number the operator will feel as soon as they accept.

Requesting a session from the edge agent

When a robot needs a human, the edge agent asks the platform for a session. The admin overview’s Raise a distress call control issues the same POST /v1/sessions request the edge agent makes, so the console path and the integration path are one code path. The request identifies the robot. The platform derives two things from the robot record:
  • pop — the robot’s point of presence, used for the RTT ranking.
  • skill — the first token of the robot’s required certification (reqCert), split on a middot or whitespace. A robot whose reqCert reads pick-place · tier-2 matches on pick-place.
There are two outcomes: The offer that is pushed to the operator’s console carries:

How the ACD picks an operator

The dispatch selector is claim_lowest_rtt. It takes the robot’s PoP and required skill, plus a pool of operator presences, and returns the lowest-RTT operator who is certified for that skill — or nothing, in which case the call is queued. The pool is assembled in this order:
  1. Live readiness. Operators who have broadcast readiness from the operator Ready screen — in any tab — over the ring channel. A live-Ready operator is always preferred.
  2. Roster fallback. If no operator has broadcast readiness, the directory roster is used instead: operators whose presence is ready or attached, mapped into presences whose certification list is the set of their certification skills. This exists so a freshly opened console can still dispatch.
Each presence carries operatorId, name, available, region, the operator’s certs as skill names, and since.

Certifications and skill matching

Matching is exact on the skill token: the ACD only considers operators whose certification list contains the skill derived from the robot’s reqCert. Certification is a hard filter, applied before the RTT ranking — a nearer operator without the certification is never selected over a farther certified one. If the filter empties the pool, the result is 202 queued, and the response names the skill that went unserved.

Queued calls and offer expiry

A matched call is an offer, not an attachment. The offer is pushed over the ring channel to the named operator’s console, which rings. The operator accepts and lands in the cockpit on that session id. The offer window is 30 seconds: expiresAt is set to 30 seconds after offeredAt at the moment the offer is raised. A queued call (202) holds the robot’s skill requirement and waits. The ACD serves it when a certified operator frees up.

Protective stop handling

PROTECTIVE_STOP is latched — the session stays in it until it is cleared, and the wallboard says so in the card hint (“latched, awaiting clear”). Because it sorts first in the card priority, a latched session is always at the top of the grid. Neither the wallboard nor the admin overview exposes a clear action. Both screens are read-only with respect to safety state: they report it, colour it, and route you to the session detail view. Operator-initiated stops also land in the wallboard’s Safety events feed, which streams the audit records for the org.

When session state and registry status disagree

The session record and the fleet registry are two different sources. The session says an operator is attached; the registry says whether the edge agent is heartbeating. The wallboard joins them per robot and, when the registry reports anything other than online, stamps a warning chip on the card reading robot <status>. That chip means the session record may be stale. Do not read the card’s RTT, divergence or velocity numbers as a live link until the robot heartbeats again.

Session state versus the relay data plane

“Attached” is a control-plane fact. Whether teleop frames are actually moving is a data-plane fact, and the wallboard shows it separately: a relay panel for the robot namespace, scoped to the current org. These two come apart exactly when it matters. A held session that has stopped delivering frames looks identical to a healthy one on the session cards alone — the relay panel is what distinguishes them. The wallboard’s Link health table lists the propagation floor for each operator-to-robot path in use, alongside how many live sessions currently ride it: The floor is the distance, not the stack. No transport change moves it, which is why the ACD ranks on RTT and why operator region is part of the session record.

What the admin overview counts

The four headline metrics on the admin overview are rollups over the same live data the wallboard renders: The Sessions by state table below them counts each state from that same live roster, so its rows always sum to the “Live sessions” headline.