Files
mesh-sdk/conformance/README.md
T
jschoubben 8f5b786a6b Conformance fixtures: what two implementations may not disagree about
Tasks 3.1 and 3.3 of novox/hq ADR 0116. One fixture directory, read by
every implementation's own runner rather than copied into each — a fixture
copied twice is two fixtures, and two fixtures drift.

The README settles what ADR 0074's byte-for-byte can and cannot mean. The
envelope is exact: the subject, the required headers, each name and format,
because those are what two implementations get wrong invisibly. The body is
not: it is the module's payload, and Go sorts a map's keys where JavaScript
keeps insertion order, so demanding identical bytes would commit every
implementation to a canonical JSON encoder to buy a property the mesh never
uses. Said plainly, because read strictly it would have sent somebody
writing one.
2026-09-26 23:40:59 +02:00

1.7 KiB

Conformance fixtures

What two implementations of the mesh's module protocol may not disagree about (novox/hq ADR 0074, design 19). A fixture is data, not prose: every implementation produces it and consumes it, and an implementation that passes the fixtures for a capability claims that capability.

What "byte-for-byte" means, and what it cannot

ADR 0074 says the fixtures must match byte for byte. Taken literally that is more than the mesh needs and more than two languages can give:

  • The envelope is exact. The subject, the set of required headers, each header's name, and the format of each value. This is what an implementation can get wrong in a way that makes two meshes silently ignore each other, so this is what is pinned.
  • The body is not. It is the module's own payload, opaque to the mesh, and its serialisation is the language's. Go's encoding/json sorts a map's keys; JavaScript's JSON.stringify keeps insertion order. Demanding identical bytes there would mean committing every implementation to a canonical JSON encoder — a large promise, bought for a property the mesh never uses. The fixture pins that the body round-trips: what goes in comes out equal.

So: exact where disagreement is invisible, semantic where it is not. Stated here because "byte-for-byte" read strictly would have sent somebody implementing a canonical encoder.

Running them

The TypeScript implementation: node conformance/run.mjs (against a NATS server; see the file). The Go implementations read this directory by sibling path, the way the lab finds its siblings.

Layout

events/            one emitted event, and what it must look like on the wire