# Check a run

URL: /investigate/runs

Confirm that a run arrived whole before you build on it. The run page lists each original file with its hash, clock, anchor and error bound, the topics the flight log carried and every step of the import.



A run is one flight or bench session of one vehicle, assembled from the files that cover it. Every incident sits on a run, so the run limits what the incident can claim. Check it first: which sources arrived, how their clocks line up and whether the flight log carried the topics the rules read.

## Before you start [#before-you-start]

* Anyone who can inspect original evidence can read a run. Admins and investigators import them: see [Import files in the console](/collect/import-files).
* The examples use R-0931 from the example dataset: UAS-04 on Route Iron, the run behind INC-0142.

## Find the run [#find-the-run]

<Steps>
  <Step title="Open the Runs list">
    Select **Runs** in the sidebar. While a run is parsing, the item shows a counter such as **1 parsing**. The list holds every flight and bench run Foxborne has imported, newest start first.

    The status buttons read **All**, **Complete**, **Partial**, **Needs attention** and **Parsing**, each with a count. **Needs attention** collects quarantined and rejected runs. The search box, **Filter by run, label or vehicle**, narrows it further, as does the **All vehicles** list.

    | Column           | What it shows                                                                                                                     |
    | ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |
    | **Run**          | The label, with the run ID under it                                                                                               |
    | **Platform**     | The vehicle and its frame, such as UAS-04, Q4 recon quad                                                                          |
    | **Started, UTC** | The date, with the start time under it                                                                                            |
    | **Duration**     | Such as 22 min 46 s, or **Unknown**                                                                                               |
    | **Sources**      | Four glyphs, always in this order: flight log, companion journal, process samples, ground receive log. A missing source is dimmed |
    | **Import**       | The status. A parsing run shows **Parsing** with a meter and its percentage                                                       |
    | **Clock**        | The clock state, or **Not parsed** for quarantined and rejected runs                                                              |
    | **Incidents**    | Links to the incidents opened on the run, or **None**                                                                             |
    | **Size**         | The total size of the run's files                                                                                                 |
  </Step>

  <Step title="Open the run">
    Select the row. An incident link in the row opens the incident instead. The page title is the run label, with the run ID. The header holds **Import job**, **Run rules again** and, when the run has incidents, a button such as **Open INC-0142**. A **Complete** or **Partial** run with no incident shows **Open an incident** instead; see [Open a new incident](/investigate/incidents#open-a-new-incident). Its panels run one under the other, each the full width of the page.
  </Step>
</Steps>

## Read the status and the clock [#read-the-status-and-the-clock]

| Status          | Meaning                                                                        |
| --------------- | ------------------------------------------------------------------------------ |
| **Complete**    | Parsed, with no expected source missing                                        |
| **Partial**     | A source is missing. The run page names it                                     |
| **Parsing**     | Foxborne is validating, hashing, parsing, aligning and running rules           |
| **Quarantined** | A file failed a check. Foxborne keeps it but shows nothing from it as complete |
| **Rejected**    | Foxborne cannot read a file, so nothing from it is parsed                      |

| Clock                 | Meaning                                                                     |
| --------------------- | --------------------------------------------------------------------------- |
| **Aligned ±46 ms**    | Every source is anchored. The value is the widest bound between two sources |
| **Not aligned**       | A source has no anchor, typically a companion clock that never synchronized |
| **Elapsed time only** | The flight log has no GPS fix, so the run has no UTC anchor                 |
| **Pending**           | The run is still parsing                                                    |

One status note can sit at the top of the run page. Foxborne picks the first that applies, in this order:

| Note                                   | Text in the example dataset                                                                                                                                                  | Button                |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| **Quarantined**                        | R-0933: "The flight log ends inside a data message at 41.2 MB. The file was truncated, most likely when power was cut during logging. Nothing from it is shown as complete." | **Replace the file**  |
| **Rejected**                           | R-0932: "The flight log is encrypted. Foxborne does not decrypt logs. Import the decrypted .ulg exported from your key holder."                                              | **Replace the file**  |
| **Partial**                            | R-0930: "No companion journal for this run. Findings that depend on the missing source are not produced, and reports list the gap under Limitations."                        | None                  |
| **Elapsed time only**                  | R-0936: "Indoor run with no GPS fix, so there is no UTC anchor. Times are shown from log start. Nothing on this run is shown as wall-clock time."                            | None                  |
| **The companion clock is not aligned** | R-0922: "chrony never synchronised on uas07-orin, and collector 0.7.3 does not record SYSTEM\_TIME. Companion evidence is kept on its own clock."                            | **Align in INC-0139** |

**Replace the file** opens **Import files**. While a run parses, a **Parsing** panel shows the step, the percentage and a progress bar. The steps run in order: "Validating type, size and schema", "Hashing originals", "Parsing the flight log", "Parsing journal and samples", "Aligning clocks" and "Running rules".

The summary strip below reads **Vehicle**, **Started**, **Duration**, **Import**, **Clock** and **Imported**, which names who imported the run and when. For an elapsed-only run, **Started** gives the date and **wall time unknown**. When the run has a GPS track, **Where** draws the whole run, subtitled with the site name and &#x2A;*Whole run from vehicle\_global\_position,** then the duration. See [Read the map](/investigate/map).

## Check the source files [#check-the-source-files]

The **Source files** panel lists each original. Its subtitle names how the run arrived, such as &#x2A;*Assembled from 3 sources. Hashed on arrival and stored unmodified.** The incident's **Sources** tab shows the same panel.

| Column               | What it shows                                                                                                                                 | R-0931 flight log                                     |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| **Source**           | The kind of file and its path                                                                                                                 | Flight log, `log/2026-09-24/14_13_19.ulg`             |
| **Clock and anchor** | The clock the file keeps and what ties it to UTC                                                                                              | PX4 boot time. GPS time from sensor\_gps, 1,081 fixes |
| **Bound**            | The clock error. Receive logs add **+ latency**. **No anchor** means no error can be stated, and **None** marks a file that failed validation | ±40 ms                                                |
| **SHA-256**          | The first 12 and last 4 hex digits of the hash taken on arrival. **Copy SHA-256** copies all 64                                               | `f60310be1687…f69f`                                   |
| **Parser**           | The parser and its version                                                                                                                    | `ulog 0.9.2`                                          |
| **Records**          | The number of records read                                                                                                                    | 1,388,540                                             |
| **Size**             | The file size                                                                                                                                 | 64.8 MB                                               |

The other three files of R-0931:

| Source                                       | Clock and anchor                                                                    | Bound            | Parser          |
| -------------------------------------------- | ----------------------------------------------------------------------------------- | ---------------- | --------------- |
| Companion journal, `uas04-orin-journal.json` | Companion wall clock. "chrony, synchronised, offset −1.8 ms"                        | ±6 ms            | `journal 0.6.0` |
| Process samples, `uas04-orin-samples.jsonl`  | Companion monotonic, same boot as journal. Shared boot ID 9b2e4c1d with the journal | ±6 ms            | `agent 0.8.1`   |
| Ground receive log, `rc1-receive.jsonl`      | Range control receiver clock. "NTP, synchronised, offset +0.4 ms"                   | ±15 ms + latency | `receive 0.4.1` |

Copying a hash confirms with **SHA-256 to the clipboard**.

## Check the ordering bounds [#check-the-ordering-bounds]

**Ordering bounds between sources** appears when the run has more than one readable file. Its subtitle reads &#x2A;*Two events closer than this cannot be put in order.** It is a matrix with one row and one column per source: **Flight log**, **Journal**, **Processes** and **Receive**.

| Cell                             | When it appears                                                                                                                                                                                                           |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A minus sign                     | The same source on both axes                                                                                                                                                                                              |
| **Same clock**                   | Both files keep one clock. The journal and process samples share the companion clock, so their order is always known                                                                                                      |
| **No claim**                     | One of the files has no anchor, and no manual alignment covers it                                                                                                                                                         |
| A combined bound, such as ±46 ms | The two bounds added. A second line, such as **plus 412 ms latency**, gives the link latency, kept apart from the ± figure. On an incident's **Sources** tab, **manual** follows a bound that rests on a manual alignment |

For R-0931, the matrix reads ±46 ms between the flight log and either companion source. The journal and process samples share **Same clock**. The flight log and the receive log read ±55 ms, plus 412 ms latency.

**How a bound is built**, at the right of the matrix's header, opens a dialog of the same name, subtitled "Each source keeps its own clock. The bound says how far apart two of them can be." It gives four lines:

* "The flight log counts microseconds from boot. GPS time in sensor\_gps pins boot to UTC within about 40 ms."
* "The companion journal and process samples share one clock. chrony reports its offset, so the bound is small when it is synchronised and absent when it is not."
* "A receive record says when a packet arrived, not when it was sent. Link latency is added on one side only."
* "Above 2.0 s Foxborne makes no before or after claim at all."

The last line follows the ordering bound an admin sets in **Settings**, under **Time and position**. [Clocks, anchors and error bounds](/concepts/clocks) explains each bound.

## Check the topics and the import job [#check-the-topics-and-the-import-job]

**Flight log topics** lists the topics Foxborne expects in the flight log, each with a check or a cross. Its subtitle reads, for example, **11 of 13 expected topics were logged**, and a missing topic reads **Not logged**. On the Q4 runs of the example dataset, `distance_sensor` and `vehicle_imu_status` are missing. So `vibration_high`, which reads `accel_vibration_metric` in `vehicle_imu_status`, has nothing to read on those runs.

Without a flight log, the panel reads **No flight log in this run**. A flight log that failed validation reads &#x2A;*Not parsed. The file did not pass validation.**

**Import job**, at the top right of the run page, opens a drawer subtitled &#x2A;*Deterministic. The same files and parser versions give the same event IDs.** It lists each step with its result and duration, then the total. For R-0931:

| Step                              | Time   |
| --------------------------------- | ------ |
| Validate type, size and schema    | 0.4 s  |
| Hash originals (SHA-256)          | 1.2 s  |
| Parse flight log, 11 of 13 topics | 38.1 s |
| Parse journal and samples         | 2.6 s  |
| Align clocks                      | 0.3 s  |
| Run 13 rules                      | 0.9 s  |
| Total                             | 43.5 s |

A step that failed carries its reason. On R-0933, **Parse flight log** ends in "Truncated inside a data message, quarantined". On R-0932, **Validate type, size and schema** ends in "Encrypted log, stopped". While the run parses, the panel reads &#x2A;*Steps and timings appear here when parsing finishes.**

## Run the rules again [#run-the-rules-again]

**Run rules again** runs the rules over the same files at the same rule versions. Foxborne confirms with &#x2A;*Rules ran again. Results are identical to the previous run.** The audit log records **Ran rules again** against the run ID. It shows a reviewer that the same files and rule versions give the same findings.

**Incidents on this run**, at the foot of the page, lists each incident opened on the run with its status, owner and last update. Select a row to open it.

**Notes** appears above **Source files** when the person who imported the run wrote notes in **Run details**. Each note carries its author and time, and notes are never treated as evidence.

## What to check before investigating [#what-to-check-before-investigating]

* **Import** reads **Complete**. On a **Partial** run, findings that need the missing source are not produced, and the report lists the gap.
* Every file shows a bound. **No anchor** on the companion journal means its clock never synchronized: [align it by hand](/investigate/align-a-clock) before you rely on an order against the flight log.
* The matrix shows a bound, not **No claim**, between the sources you need to compare.
* The receive log's bound ends in **+ latency**. Its times are arrivals, and the moment each record describes came earlier.
* The flight log carried the topics your question depends on.
* No step of the import job carries a warning or an error.
* The SHA-256 of each file matches the copy your program holds. See [Verify a report against the originals](/investigate/verify).

## Troubleshoot [#troubleshoot]

**Quarantined.** Foxborne kept the file but shows nothing from it as complete. **Replace the file** opens **Import files** for a complete copy, and [Import statuses and fixes](/collect/troubleshoot-imports) lists every reason.

**Rejected.** Foxborne cannot read the file, as with an encrypted flight log. It does not decrypt logs: import the decrypted `.ulg` from your key holder.

**This run does not exist.** The console adds "It may have been deleted under the retention policy." **Back to runs** returns to the list.

**The Clock column reads Pending.** The run is still parsing. The **Parsing** panel on the run page shows the step it has reached.

## Next [#next]

<Cards>
  <Card title="Work an incident" href="/investigate/incidents" icon="flag">
    Read the reconstruction built on this run.
  </Card>

  <Card title="Import statuses and fixes" href="/collect/troubleshoot-imports" icon="alert">
    Every quarantine and rejection reason.
  </Card>

  <Card title="Clocks, anchors and error bounds" href="/concepts/clocks" icon="clock">
    Where each bound in the Source files table comes from.
  </Card>

  <Card title="Supported file formats" href="/collect/formats" icon="file">
    What each parser reads.
  </Card>
</Cards>
