The complete message surface as 42 JSON Schemas — draft 2020-12, version-pinned URN identities, a reference validator, and generated TypeScript types. The contract is machine-enforceable end to end.
$id of the form urn:ipproto:schema:0.1:<name>. The identity does not depend on where the schema is served, so the contract survives any hosting change.additionalProperties open by design — a newer sender carrying extra fields never breaks an older receiver. Strictness lives in the generated TypeScript types, not the wire schema.index.json maps every $id to its path and message type, pinned to the package version.A resolver or converter validates its whole output against urn:ipproto:schema:0.1:resolvedAsset, which composes the Asset Reference and its Resolution Provenance. Conformant output is checkable, not asserted.
Plus defs — shared definitions (URIs, money, ST.3 / ST.16 code types, JSON Pointer).
Implementations depend on @ipproto/schemas and adopt the standard's shapes as their domain model, validating in CI. Extensions go through namespaced custom values, never forks of the schemas — so every implementation stays interoperable and the contract cannot drift.
import Ajv2020 from "ajv/dist/2020.js";
// load every schema in index.json, then:
const validate = ajv.getSchema("urn:ipproto:schema:0.1:resolvedAsset");
if (!validate(emission)) throw new Error("non-conformant output");