34140cc666
engine_rpm moves to source z27ag (no OBD-II on this car's CAN). Ten more: accelerator, brake, handbrake, indicators, side lights, dipped beam, doors, A/C compressor. Guideline 6: no service writes a CAN ID of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
2.3 KiB
2.3 KiB
type
| type |
|---|
| guidelines |
Contract guidelines
1. signals.json is the single source for a signal's identity
- Topic name and the envelope's
unitare 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
monotonicis authoritative for ordering and intervals. It cannot step.timestampis 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 frommonotonic.
3. Raw CAN is not the envelope
yukart/can/rawis 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
qualityis omitted whenok;mockis 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. A decoded signal's layout lives only in its registry entry
- Every
source: z27agsignal has acanblock insignals.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.