fact_robotics_audit. The console
renders it at Audit log · Robotics. This page describes the record
itself so that you can read it outside the console, correlate it with
telemetry, and understand how the console derives what it shows.
What gets recorded
The log covers operator and system actions against robots in an org: teleop sessions, e-stops, control transfers, alerts, and deploys. Rows are written as the action happens, by the service that performs it — the log is not reconstructed after the fact. Every row is scoped to an org.fleetRobotics.auditLog takes orgId
and returns only rows for that org, so a caller cannot read another
tenant’s actions through it.
The audit row: actor, kind, target, detail
A row as returned byfleetRobotics.auditLog carries these fields:
Two of these are nullable, and the console substitutes placeholders
rather than blanking the cell:
actor_labelmissing → the console displayssystemand swaps the avatar for a CPU glyph. Treatsystemas “no human actor recorded on this row”, not as the name of a principal.robot_idmissing → the Target column shows—.kindmissing → the Action column shows—.
detail has no fixed schema. When it is an object, the console
JSON-stringifies it for the Detail column; when it is a string it is
rendered verbatim. Write your own consumers to handle both shapes.
Action kinds and severity
kind is the vocabulary you filter and alert on. The audit table itself
stores no severity or verdict column. Severity is derived from the
kind string, and the console does that derivation client-side:
Matching is substring-based on the lowercased kind, so
estop_engaged
and fleet_estop_clear both derive bad. Kinds whose name begins with
estop are additionally rendered in the danger colour in the Action
column.
Because this mapping is a naming convention rather than a stored
column, a new kind inherits its severity from how it is named. If you
emit or parse kinds yourself, keep the convention: put estop,
error, alert, warn or flag in the name when the action deserves
attention.
The verdict input on the procedure applies the same classification
server-side, so filtering by bad and colouring a row bad always
agree.
Retention and append-only guarantees
The table is append-only. There is no procedure to edit or delete a row, and the console exposes none — the log is the compliance artefact for ISO 27001 and SOC 2 controls over operator actions on physical hardware. Corrections are made by appending a new action, not by rewriting history. The log’s window is bounded by what the query range covers, not by the console’s default range. The screen opens on the last six hours purely as a default; supply a widerfromMs / toMs to read further back.
Reading the log over the API
The console screen is a thin client over one procedure. You can call it directly:
The response is
{ rows, total }. Filtering, searching and pagination
all happen server-side, so total counts the rows matching the full
predicate — range, verdict and search — not just the rows on the
current page. Derive page count as ceil(total / perPage).
Two details worth copying from the console when you build your own
poller:
- Round your range bounds. The console floors
fromMsand ceilstoMsto the minute so that a relative range likenow-6h → nowproduces a stable query key instead of a new one every render. - Debounce search. The console waits 300 ms after the last keystroke before issuing a query, and resets to page 1 whenever the range, verdict or search changes.
Correlating an e-stop with robot telemetry
An audit row gives you three join keys:ts, robot_id, and kind.
To investigate an e-stop:
- Filter the log to
verdict: "bad"over the window in question, or search forestopdirectly. - Take
robot_idandtsfrom the matching row. - Query your telemetry store for that robot around that timestamp. The audit row tells you who commanded the stop and when; the metrics and traces tell you what the robot was doing either side of it. See Telemetry for the stream shapes and how to correlate them.
- Read
actor_labelto distinguish an operator-initiated stop from one with no recorded human actor.
bad verdict alone
does not tell you whether the event was an e-stop or an error. Read
kind for that distinction, and detail for the context the emitting
service attached.
Related
- Telemetry — metrics, traces and capture streams to correlate against
- Authentication — how a caller is authorised for control-plane procedures

