Files
contracts/docs/GUIDELINES.md
T
mikkeli 34140cc666
/ crosscheck (push) Successful in 1s
Rust consumers (L4T) / Clippy, test, build, glibc for every service that compiles contracts in (push) Failing after 6s
Decoded Z27AG signals: layouts in signals.json can blocks, the only source
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
2026-10-13 21:31:51 +09:00

2.3 KiB
Raw Blame History

type
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. 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