Fixtures and pinned versions
A schema says what is allowed. A fixture corpus shows it: realistic cases that must pass and, just as important, cases that must fail, each with the reason. Products in different languages run the same cases, so they agree without sharing code.
The corpora
Section titled “The corpora”| Corpus | In the repository | Published in | What it pins |
|---|---|---|---|
| Identity | fixtures/ecosystem-identity/ |
treaty-ecosystem-identity, every file by its own subpath |
The id grammar, token claims, the card prompt, the run join key, and the chat events a gate, question or permission crosses Matrix on |
| SuperPipeline events | fixtures/superpipeline-events/examples.json |
not published; in the repository only | For each schema under schemas/superpipeline/, the bodies it must accept and refuse |
| Matrix events | fixtures/matrix-events/examples.json |
treaty-matrix-events, as examples.json |
For each board-room type, content a sender may emit and content it must not |
| CloudEvents binary mode | fixtures/cloudevents/binary-mode.json |
not published; in the repository only | What the codec must do over HTTP and NATS: encode, decode, refuse, percent-encoding |
Every event page in the catalogue and the Matrix catalogue shows its first valid case in full, the others folded, and every refused case with its reason.
The Matrix corpus says what refuses each case
Section titled “The Matrix corpus says what refuses each case”Each invalid case in fixtures/matrix-events/examples.json names what refuses it:
schema: the type’s JSON Schema;unique: anx-uniqueByrule of that schema, the one rule JSON Schema cannot state;recorded: only the carrier, against what it recorded when it posted (an option it did not offer, a binding to another subject). A renderer is not asked to refuse these.
The file is generated by scripts/matrix-examples.ts from the identity corpus’s Matrix cases and
from the package’s own builders (cases labelled built:). Never edit it by hand.
Negative cases are the point
Section titled “Negative cases are the point”A corpus of valid examples alone proves little: a well-formed id of the wrong entity passes every
check that only looks at shape. So the identity corpus gives every entity a reject list (wrong
prefix, too short, wrong alphabet, empty, prefix only, and a valid id of a different entity), and
every schema’s examples carry refused cases.
Testing against a pinned version
Section titled “Testing against a pinned version”A product pins an exact treaty version and tests its own code against that version’s data. The three ways products do it today:
- Validate what you build. SuperPipeline’s tests validate the bodies its builders produce
against the schemas in
@superjackfruitlabs/treaty-event-schemas. A type that moves without its schema fails there, in SuperPipeline, not in a consumer. - Run the corpus through your own reader. AgentPod drives its id validators from the identity corpus’s accept and reject lists.
- Vendor the files and check the copies. SuperMessage’s Rust core reads the corpora with
include_str!, so it keeps copies. Its CI downloads the pinned package withnpm packand fails when a copy differs from it.
Moving to a newer treaty release is then one change in the product: bump the pin (and the copies), run the tests, and fix what they report. A release of treaty alone changes nothing for anyone.
import grammar from "@superjackfruitlabs/treaty-ecosystem-identity/id_grammar.json" with { type: "json" };import gatePending from "@superjackfruitlabs/treaty-event-schemas/superpipeline/gate.pending.v1.json" with { type: "json" };import examples from "@superjackfruitlabs/treaty-matrix-events/examples.json" with { type: "json" };Go and Swift read the same JSON files without TypeScript.