Reports

Last updated on June 16, 2026

TofuPilot records every test run with phase outcomes, measurements, logs, and attachments, and uploads it to your organization.

You can access run results in two ways:

  • Dashboard — every run appears in Runs with full phase, measurement, log, and attachment detail.
  • JSON event stream — run your procedure with --json to consume results programmatically.

If the upload fails (e.g. no network), the run is persisted to a local queue and retried automatically. See tofupilot queue for inspecting and exporting queued runs.

JSON event stream

You can use tofupilot run --json to emit one JSON event per line on stdout while the run executes:

tofupilot run --json
{"type":"run_started","procedure_id":"FVT1","protocol_version":"1"}
{"type":"phase_started","phase_key":"check_voltage","attempt":1,"started_at":"2026-06-10T14:30:00Z"}
{"type":"measurement_recorded","phase_key":"check_voltage","name":"voltage","value":3.3,"outcome":"unset","unit":"V"}
{"type":"phase_finished","phase_key":"check_voltage","outcome":"pass","attempt":1,"duration_ms":1776}
{"type":"run_finished","outcome":"pass","exit_code":0}

Each event is tagged with a type field. Key event types:

TypeDescription
run_startedFirst event, carries the procedure id
phase_started / phase_finishedPhase lifecycle with outcome, timestamps, and duration
measurement_recordedA measurement value was set (validation happens at phase close)
attachment_addedA phase attached a file or data blob
ui_requestAn operator UI prompt is waiting for input
run_finishedTerminal event with run outcome and exit code
run_crashedThe procedure subprocess died; includes a stderr tail for diagnosis

This stream is line-delimited JSON, so you can pipe it into tools like jq:

tofupilot run --json | jq 'select(.type == "phase_finished")'

How is this guide?

On this page