# Clock uncertain

URL: /rules/clock-uncertain

Warns when a source has no trustworthy anchor to UTC or its error exceeds the ordering bound. It is always on, because every before and after claim between sources depends on it.



<RuleHeader id="clock_uncertain" />

## What it reads [#what-it-reads]

The rule reads what alignment produced for each source in a run: its clock, its anchor and its error bound. The run page shows the same values in **Source files**, under **Clock and anchor** and **Bound**. The other rules each read one source, and this one checks them all.

Two cases in the example dataset leave a source without an anchor:

* **A flight log with no GPS fix.** The indoor run R-0936 shows the anchor **None: no GPS fix during the run**, and Foxborne marks it **Elapsed time only**.
* **A companion clock that chrony never synchronized.** Run R-0922 shows **None: chrony never synchronised** for both the journal and the process samples.

## When it fires [#when-it-fires]

The threshold reads **Anchor missing or error above 2 s**. The rule warns when a source has no trustworthy anchor, or when its estimated error exceeds the ordering bound, 2.0 s by default. Above that bound, Foxborne makes no before or after claim between sources, whatever the times say.

The warning changes what the console claims about the source. For a companion clock without an anchor:

* The journal and the process samples stay on their own clock, below a **Companion clock** divider that reads "Own clock. No order is claimed against the lanes above."
* Their events get no place on the map: "No position. This event is on the companion clock, which is not aligned, so it cannot be placed on the track."
* **Order against nearby events** shows **No claim** for them, because "The companion clock has no shared anchor with the flight log."
* The report's **Clock** line reads "The companion clock is not aligned. No order is claimed between the companion and the flight log."
* Findings on the companion's own clock get no flag in the **Findings** row.

## Wording and evidence level [#wording-and-evidence-level]

Every finding reads **Warning: ordering between sources is uncertain**. It is the only rule whose wording starts with Warning. It speaks about the evidence, not about the vehicle.

## What the finding does not mean [#what-the-finding-does-not-mean]

* **The companion's events are not wrong.** Events on one clock keep their order, because events on the same clock are always ordered. In INC-0139 the CUDA error came 57 ms before the core dump, on the companion's clock.
* **The other rules still run.** A source on its own clock still produces findings. INC-0139's [process\_exit](/rules/process-exit) finding sits on the companion's own axis.
* **It says nothing about the vehicle.** In INC-0139 the flight log stayed anchored to GPS time at ±40 ms. Only the companion's evidence lost its place on the shared timeline.

## Threshold and overrides [#threshold-and-overrides]

The rule is locked, and its **Edit** button is disabled. Its **Enabled** switch is disabled too, with the tooltip "Always on. Every ordering claim depends on it."

The scope reads **All sources**. The ordering bound is a setting of its own, which admins change in **Settings** under **Time and position**. The choices are 0.5 s, 1.0 s, 2.0 s and 5.0 s.

The console's hint for that setting reads "Lowering it makes more pairs unknown. Raising it is recorded in every report produced afterwards."

### Aligning a clock by hand [#aligning-a-clock-by-hand]

An engineer can place an unanchored companion clock on UTC by hand, from two events that happened at the same moment on both clocks. In INC-0139 the pair is `mavlink-routerd` opening the flight controller's UART and PX4 seeing the first onboard controller heartbeat on TELEM2. The proposal gives an offset of +11:03:04.916 with a bound of ±1.04 s, from the 1 s heartbeat period and the 40 ms GPS anchor.

That bound sits under the 2.0 s ordering bound, so before and after claims become possible, each marked as manual. After **Apply alignment**, the incident's clock chip reads **Manual ±1.09 s**. That is the 1.04 s bound plus 6 ms for the journal and 40 ms for the flight log.

The report lists the alignment under Limitations, with the pair it came from. **Remove alignment** restores the original state.

For future runs, collector 0.8.1 records `SYSTEM_TIME` pairs, which give companion evidence a shared anchor with the flight log. The **Vehicle collectors** tab tags older versions **No SYSTEM\_TIME**.

## Example finding [#example-finding]

In INC-0139, UAS-07 flew pass 3 of the berm line survey. chronyd on its companion logged `No suitable source for synchronisation` at boot, and collector 0.7.3 does not record `SYSTEM_TIME`. The journal and the process samples had no shared anchor with the flight log.

The incident's **Activity** tab records the result as a Foxborne entry: "rule clock\_uncertain 1.0 flagged the companion clock: no anchor". The incident list shows the clock chip **Not aligned**, and the run page shows the note **The companion clock is not aligned**.

The investigator wrote the report's finding as unknown. `perception_node` crashed with a CUDA illegal memory access, but the crash cannot be placed before or after the 71 s obstacle data stall. The next check is to align the clock from the matching pair, then upgrade UAS-07 to collector 0.8 so future runs carry `SYSTEM_TIME`.

## Related [#related]

* [Clocks, anchors and error bounds](/concepts/clocks) explains the anchor and the bound of each source.
* [Alignment and event order](/concepts/alignment) explains when an order is reported as unknown.
* [Align a clock by hand](/investigate/align-a-clock) walks through the INC-0139 alignment.
* [The companion collector](/collect/collector) covers `SYSTEM_TIME` in collector 0.8.1.
