--- type: guidelines --- # Contract guidelines ## 1. `signals.json` is the single source for a signal's identity - Topic name and the envelope's `unit` are both **derived** from a registry entry. Neither is authored by hand anywhere else. - ⚠ **The unit appears in both the topic name and the payload, so they can contradict each other.** Generating both from one entry is what stops that; a hand-written `"unit"` reintroduces the failure it was meant to prevent. - Signal names carry their unit (`vehicle_speed_kph`, `coolant_temp_c`), so a unit mismatch is visible at the call site rather than one registry lookup away. ## 2. Two clocks, and they answer different questions - `monotonic` is authoritative for **ordering and intervals**. It cannot step. - `timestamp` is the **absolute reference** and can step: the car boots with no network, LTE connects several minutes in, and NTP corrects the clock mid-drive. - ⚠ **Never derive a duration from `timestamp`.** A step lands inside the interval and the result is silently wrong, most likely during exactly the drive worth keeping. Durations come from `monotonic`. ## 3. Raw CAN is not the envelope - `yukart/can/raw` is binary. A four-key JSON object at 1000–3000 frames/sec is not a reasonable encoding. - The envelope is for decoded signals, which are low-rate by comparison. ## 4. Absent means default - `quality` is omitted when `ok`; `mock` is omitted when false. A consumer treats absence as the default, never as an error. ## 5. This repo is versioned by git tag - There is no version in any topic or payload. A recorded session names the contracts tag it was captured under, which is what keeps old captures readable. ## 6. To be added