> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Production

> Running a session unattended: supervision, reconnects, tokens, and who is allowed to drive.

## Anyone in the room can drive

Control is first come and unauthenticated. The follower grants the lease to
whoever claims it first and does not check who they are. There is no handover
queue and no operator identity.

The room is the boundary. Treat a room id and a token together as the
credential that lets someone move your hardware.

| Do | Why |
| - | - |
| Mint a room per session, not a long-lived shared one | a room id that leaks stays usable |
| Scope tokens to the room and keep their lifetime short | a token is what admits a peer at all |
| Keep both out of committed files and out of params YAML | `.env` and the environment, never the repo |
| Watch `lease_holder` and `on_control_granted` | this is your only record of who took control |

```python theme={null}
@follower.on_control_granted
def _(lease, holder):
    audit.write(f"{holder} took control, lease {lease}")

@follower.on_control_released
def _(lease, why):
    audit.write(f"control released: {why}")
```

<Warning>
  Do not put a robot that can hurt someone in a room whose id and token are
  shared more widely than the people allowed to drive it.
</Warning>

## Supervision

Run the follower under a process supervisor. systemd, or a Kubernetes restart
policy, or whatever already runs on the host.

```ini theme={null}
[Service]
ExecStart=/usr/bin/python3 /opt/robot/follower.py
Restart=always
RestartSec=5
Environment=ZERORUNTIME_AUTH_TOKEN=...
Environment=ZERORUNTIME_MEETING_ID=abcd-efgh-ijkl
```

A restart is safe. The follower starts in `HOLDING`, applies nothing until a
leader claims control, and nothing resumes on its own.

<Note>
  There is a second watchdog you do not configure: if your own loop stops
  calling `tick()`, the follower notices and enters a failsafe with reason
  `STALLED`. A hung process does not leave the arm armed.
</Note>

## Reconnects

A transport drop is not a pause. The follower drops the lease with reason
`transport:<why>` and enters its failsafe, because the lease belongs to a peer
that is now gone.

When the link comes back, the operator has to claim again. That is deliberate:
a session that silently resumed would put an arm back under the control of
someone who may have walked away.

Set `resume_requires_reclaim=True` to extend the same rule to a watchdog trip,
so the arm stays in `HOLDING` after commands stop until someone calls
`Follower.arm()`.

```python theme={null}
safety = SafetyConfig(watchdog_timeout_s=0.5,
                      resume_requires_reclaim=True)
```

<Warning>
  An emergency stop latches. It survives reconnects and is cleared only by
  `clear_estop()` on the follower, which means someone near the arm.
</Warning>

## Tokens

`ZERORUNTIME_AUTH_TOKEN` is read at construction. A token that expires mid-session does
not stop the session, but the next `start()` fails with a `TimeoutError` from
the transport, which reads like a network problem and is not.

| Setting | What to do |
| - | - |
| Token lifetime | short enough that a leaked one expires, long enough to cover a session |
| Rotation | restart the follower with a new token, which the supervisor already does |

## More than one robot

One room per follower and leader pair. A room holds one arm and whoever is
driving it.

Give each machine its own `robot_id`. It goes into logs, recordings and the
manifest, and two hosts sharing one makes a dataset ambiguous later.

```python theme={null}
follower = MyArm(MEETING_ID, name="arm-07")   # display name in the room
follower.robot_id = "arm-07"                  # the name in every record
```

For a fleet, keep the mapping from robot to room outside the SDK. Nothing here
does discovery.

## Network

A session is one WebRTC connection: a data channel for joints and one video
track per camera.

| Want | Budget |
| - | - |
| Joints alone, 6 joints at 50 Hz | tens of kilobits per second |
| One camera, 640 by 480 at 30 fps | a few megabits per second |
| Two cameras | roughly double it |

Measure rather than assume. `stats()` gives you round trip
time, jitter and loss on the live link, and `max_staleness_ms` should be set
from what you actually see under load rather than from the default.

<Note>
  The defaults are deliberately low. Measure `watchdog_timeout_s` and
  `max_staleness_ms` on your own link, with traffic on it, and set them from
  that. See [SafetyConfig](/robotics/api-reference/python/safety-config).
</Note>

## Before you leave it running

<Steps>
  <Step title="Set limits()">
    The default returns `{}`, which is no position limit at all.
  </Step>

  <Step title="Set slew per joint">
    One number is wrong on a machine whose joints do not share units.
  </Step>

  <Step title="Set max_misalignment on the leader">
    So arming cannot make the arm travel to meet a controller somewhere else.
  </Step>

  <Step title="Check the failsafe matches the hardware">
    `on_starvation=TORQUE_OFF` drops a gravity-loaded arm. `HOLD` is the
    default for a reason.
  </Step>

  <Step title="Watch the numbers">
    Tick overruns, watchdog trips and how many commands correlated. See
    [Monitoring](/robotics/guides/monitoring).
  </Step>
</Steps>

## Related

<CardGroup cols={2}>
  <Card title="Safety" icon="shield-halved" href="/robotics/concepts/safety">
    The checks a command passes, and what none of them catch.
  </Card>

  <Card title="Monitoring" icon="chart-simple" href="/robotics/guides/monitoring">
    Reading a live session's health.
  </Card>

  <Card title="Cloud recording" icon="cloud" href="/robotics/guides/cloud-recording">
    Uploading episodes to your own storage alongside the local copy.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/robotics/guides/troubleshooting">
    Symptoms, and what to change.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.