2026-09-05 12:54:14 +09:00
|
|
|
|
---
|
|
|
|
|
|
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.
|
2026-10-13 22:50:03 +09:00
|
|
|
|
- Signal names carry their unit (`gnss_speed_kph`, `obd_coolant_temp_c`), so a unit
|
2026-09-05 12:54:14 +09:00
|
|
|
|
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.
|
|
|
|
|
|
|
2026-10-13 21:31:51 +09:00
|
|
|
|
## 6. A decoded signal's layout lives only in its registry entry
|
|
|
|
|
|
- Every `source: z27ag` signal has a `can` block in `signals.json`: frame ID, byte,
|
|
|
|
|
|
bit or length, byte order, scale and offset. The decoder reads those blocks and
|
|
|
|
|
|
nothing else, so a correction lands in one file and every consumer sees it.
|
|
|
|
|
|
- ⚠ **No CAN ID or bit position is written in any service's code.** A layout
|
|
|
|
|
|
hard-coded downstream is a second source that silently disagrees the day the
|
|
|
|
|
|
registry is corrected.
|
|
|
|
|
|
- Each block names the report with its evidence (`evidence`). A layout without
|
|
|
|
|
|
evidence is a guess and does not go in.
|
|
|
|
|
|
|
|
|
|
|
|
## 7. To be added
|