Prove it
Conformance
"Speaks blocks.v1" is a testable claim, not a vibe. The suite ships inside @blocksmith/protocol; fork the fixtures, point them at your emitter, and the exit code is your answer.
Run it
# inside the BlockSmith repo (also runs the app↔package drift gate): npm run protocol:conformance # as a third party, in the package: npm install @blocksmith/protocol npx tsx node_modules/@blocksmith/protocol/conformance/run.ts
What it checks
| Category | Fixtures | Assertion |
|---|---|---|
valid/ | minimal-graph · full-acme-graph · fresh-lock | Validate clean, hashes recompute byte-for-byte, lock fresh against its graph |
invalid/ | wrong-schema-field · draft-in-official-graph · bad-content-hash · lock-version-mismatch | Each fails for the DOCUMENTED reason — not just any error |
behavioral/ | golden-vectors.json | blockContentHash + graphHash golden vectors reproduce exactly; graph hash is order-independent; key order never matters |
| registry rules | (in-runner) | Append-only versions enforced; official pointer must reference a recorded version |
The drift gate (reference repo only)
BlockSmith's CI additionally proves the app and the published package never diverge: hash implementations compared on shared vectors, schema copies byte-identical, and live registry output validated against registry.v1. It runs on every PR touching packages/protocol/, src/lib/ir/, or public/schema/ (.github/workflows/protocol-conformance.yml).
This gate caught a real divergence on its very first run — a stray NUL-byte separator in the app's hash input. That is the entire argument for executable conformance: hash law is enforced by CI, not by code review vigilance.
Badge
Adapters and targets that pass may carry blocks.v1 conformant in their README and get a row in the adapter / target registries.