Souspli

Souspli / Docs / Design notes

Design note — 2026-07-23. A decision record, written when this was built and kept as written. It uses the code's names (thing, shell, cage — see the glossary) and may describe things that have since changed. Current documentation: conformance.

Build brief — @yourproject/conformance (phase 6)

Why

A protocol with one implementation has no interop — it has a reference and a hope. Conformance is the artifact that turns "our code does X" into "X is the rule, and here is how you prove your code does it too." Format spec §11 names it required before publish. This phase builds the format half: the deterministic vectors a second implementation runs to prove it decodes, hashes, verifies, admits, chains, seals, and bounds byte-for-byte identically.

The principle

Vectors are data, not code. The interop contract is the JSON — candidate bytes plus the expected outcome — not any one language's runner. A second implementation must be able to consume vectors/*.json with nothing from this repo. The TypeScript runner (runAll over a ConformanceTarget) is a convenience for TS implementers and the mechanism by which the reference holds itself to the suite; it is not the contract.

Reject, never normalize. The canonical-CBOR vectors are the sharp edge: a decoder that silently normalized non-canonical input would hash differently from the sender and turn an encoder bug into a signature forgery. Every non-canonical input is an expect: "reject".

The reference passes its own suite. test/format/conformance.test.ts runs the whole battery against our format package — self-consistency proof and regression guard in one. Behavioural drift flips a vector.

Scope

Out of scope (later)

Test battery

test/format/conformance.test.ts: one test per vector, plus a guard that all seven categories are present and non-empty. Passing means the reference agrees with its own frozen description of the format.