The Orchestrator decides work and the Robot executes it. The Orchestrator keeps a registry of the Robots it can reach. Every governed dispatch asks the registry which one may take the job. A Robot that is offline, stale, busy or missing a required capability is never chosen.
#The robot registry
Each robot is a record under <state root>/robots/<id>.json: an id, a status of online, busy or offline, the last heartbeat, the advertised capabilities, the current job when one is running, an optional hostname, an optional environment and the created time.
# register a worker, then bump its heartbeat and list the registry
tsx orchestrator/cli.ts robot register robot-01 --capabilities web,excel --hostname bench-01
tsx orchestrator/cli.ts robot heartbeat robot-01
tsx orchestrator/cli.ts robot list
A robot with no capabilities registers as caps=[].
#Capabilities a robot advertises
A robot's capabilities are a superset of the capabilities a package needs. The predicate eligibleForCapabilities requires every capability in the package's manifest to be present on the robot, so a ["web","excel"] package will not land on a ["web"] robot.
Most capabilities are engine facts: a robot either has the excel engine or it does not. The answer is stable while the deployment lives. desktop is different. It is a session fact about the host. A desktop session has no keep-alive, so a host that had one yesterday may have none today with no event. A reboot can end it silently. Because of that, a package that declares desktop is refused by name when no robot presents it, with the code DESKTOP_SESSION_INTERACTIVE_REQUIRED. Nobody at the desk is fine. A service has no desktop at all.
#Heartbeats and staleness
A heartbeat is how a robot says it is alive. robot heartbeat <id> bumps the timestamp and sets the status to online, unless the robot is busy, in which case that status is kept. setCurrentJob marks a robot busy while a job runs and online when it clears.
Staleness is a read-time judgement, not a stored fact with a timer. A heartbeat older than the stale window marks a robot offline. A robot whose heartbeat is too old is not eligible even if its status still says online.
Changing a robot's environment over a heartbeat does not move an in-flight job. The next placement uses the new value. Clearing the environment back to unset is allowed and re-opens eligibility for non-prod. No path defaults an unset environment to prod.
#How governed dispatch picks a robot
A job definition names a robot, either as an explicit id or as auto. The dispatcher resolves the effective environment and the required capabilities, then places the job:
- For
auto, the registry chooses among robots that are neither busy nor offline, whose heartbeat is inside the stale window and whose capabilities cover the package's requirements. When the job is prod-effective, the robot's environment must beprod. - For an explicit pin, the dispatcher checks the same two hard rules it cannot skip. A prod job pinned to a robot that is not bound to prod is refused. A package that declares
desktoppinned to a robot without it is also refused.
The registry returns the eligible robot whose last heartbeat is oldest. Every refusal happens before the queue claim and before the spawn, so a refused job produces no run and no evidence. The caller can read why.
A dispatch that does not spawn is classified at the control plane, not by the Robot:
deployment missing hash directory, retired slot, integrity mismatch, credential refusal
capacity no eligible robot for the required capabilities or environment
execution the robot was spawned and its evidence stands
Behind the label, an activation record binds a slot to a package and an environment. A job's version is a slot name; the activation resolves it to a content hash directory. A hash-pinned version bypasses the label.
#Things that catch people out
An unset robot environment is eligible for every non-prod job but never for a prod job. A prod job needs a robot explicitly bound to prod. An explicit pin to a non-prod robot is refused, even though auto would have skipped it.
The registry's pick is the robot that has waited longest since its last heartbeat, which spreads work across the fleet but is not load-aware. Pin a specific robot if you need one. The pin is still subject to the prod and desktop rules.
A robot that fails the capability or environment test is not re-routed. The job is refused. A silent hop to a robot that cannot do the work is what the placement checks prevent.