Conformance

The golden vectors are the compatibility contract. A Hub, Surface, Companion, or widget is conformant when it accepts every message in the valid set, ignores (never rejects) structurally valid envelopes with unknown types, and rejects malformed envelopes. Changing any of these boundaries is a major-version protocol change.

  • 46 valid messages (session, context, turn, tools, ui, pair, error, action)
  • 2 forward-compat (ignore) cases
  • 17 malformed (reject) cases
  • 4 pairing cases (pair-token claims and .well-known documents)
  • 17 sealing byte vectors (nonces, padding, sealed frames) — parse-only, see below

sealing.json pins the parsing guarantee of Content sealing (retired) — bytes a peer must still parse, not behavior to implement.

Run them against your implementation

The paragraph above was, until recently, a claim with a vitest suite behind it — which proves the TypeScript contracts agree with the vectors and says nothing about a Hub written in Go, a Companion in Swift, or a service in Python. Those are the implementations interoperability depends on, and they had no way to make the claim.

npx ocp-conform --exec "python3 my_parser.py"

The runner knows no schema of its own. Your adapter reads {kind, value} on stdin and writes one of three verdicts:

  • accept — plus the parsed value, re-serialised
  • ignore — an unknown message TYPE, which is what makes the protocol additive
  • reject — a known type whose payload is malformed

Three, not two, and the distinction is the whole of §2. An implementation that collapsed ignore into reject would pass a binary harness while refusing every frame a later minor version sends it. Returning the parsed value is not optional either: “it parses” is equally satisfied by a parser that silently drops a field it does not know, so every value a vector declares must still be there afterwards.

@schwaizer/ocp-protocol ships the vectors, the ocp-conform binary, a ~30-line reference adapter to copy, and its own vitest suite.