Eformogi
The Record: protocol draft 0.1 (CC BY 4.0; verifier Apache-2.0)

10. Conformance

Draft 0.1. Reference: spec/verifier/verify-offline.js, spec/verifier/run-vectors.sh, spec/verifier/vectors/*.json.

10.1 What conformance means

Conformance says nothing about the truth of the claims inside a Record, the identity of any witness, or acceptance by any receiver. The trademark and conformance-claim policy is pending (LICENSE-PENDING.md).

10.2 Vector structure

Each vector is one JSON file:

fieldtypemeaning
idstringv<nn>-<slug>; the file name without .json
chapterstringthe chapter the vector exercises
titlestringthe normative sentence being tested
checkenumwhich algorithm the verifier runs (section 10.3)
inputobjectthe check's inputs; shapes per check kind
expectobjectverdict: "pass" or "fail", plus expected values (canonical, id, sha256, roots, empty_root, snapshot_sha256) where the check produces values

A vector whose expect.verdict is fail passes when the verifier correctly refuses. Signature vectors were generated once with ephemeral keys; only public halves are embedded, and the vectors do not depend on any live key or endpoint.

10.3 Check kinds

checkinputwhat the verifier does
canonicalizevaluechapter 02 section 2.3 canonical form; compares to expect.canonical
leaf_payloadleaf {receipt_id, prefix, sha256, issued_at}builds the four-field leaf with normalization; refuses non-loggable prefixes
receipt_idkind and the raw inputs for that kind (payload, course, attestation, worksample, note, wall)applies the per-prefix hash domain and derives <prefix>_ + 12 hex
kb_bindingkey_id, public_jwk, established_atderives did:key from x, builds the frozen kb_ payload, derives id and sha256
family_sigleaf_payload, sig, public_jwkEd25519 under eformogi-receipt-sig-v1:
countersigleaf_payload, org_countersig, public_jwkEd25519 under eformogi-witness-countersig-v1:
merkle_rootleaf_payloads[]leaf hashes and RFC 6962 roots over prefixes of the list
inclusionleaf_hash, leaf_index, tree_size, audit_path, root_hashthe RFC 9162 fold
sthsth, public_jwkwhitelist the seven fields, canonicalize, Ed25519 under eformogi-sth-v1:
proofproof, public_jwk, sha256?the four-step algorithm of chapter 06
vc_proofcredential, public_jwkeddsa-jcs-2022 DataIntegrityProof

10.4 The vectors

idchapterexercisesexpected
v01-canonical-json02sorted keys, arrays in order, unicode, nestingpass with exact string
v02-leaf-payload-exact-bytes02id and sha lowercased, ISO ms timestamp, sorted keyspass with exact string
v03-leaf-payload-rejects-ecr02ecr_ is never loggablefail
v04-cr-derivation02cr_ hash domain with credits as posted stringpass, cr_0ad5487e3ca4
v05-att-derivation-ws-target02, 03att_ hash domain with lowercased email as email_hash_inputpass, att_5d9b296a66cb
v06-ws-derivation-v102ws_ v1 domain; issued_at outsidepass, ws_53071e72cd4a
v07-wn-derivation02wn_ domain with author: kid fixedpass, wn_e45fc1d88617
v08-tr-derivation02tr_ whole-payload domain (gold-demo shape)pass, tr_d83e84e54c94
v09-kb-binding-frozen04did:key derivation and the frozen kb_ payloadpass, kb_b5ed898815ac
v10-family-sig-valid04family signature under its contextpass
v11-family-sig-context-stripped04a context-free signature must not verifyfail
v12-org-countersig-valid03organization countersignature under its contextpass
v13-merkle-roots-frozen05roots for 1, 2, 3, 7, 8, 16 leaves and the empty rootpass with exact hashes
v14-inclusion-valid05leaf 3 of 7 folds to the rootpass
v15-inclusion-wrong-index05same path, wrong indexfail
v16-sth-valid05seven-field signed tree headpass
v17-sth-tampered-tree-size05tampered tree_sizefail
v18-proof-four-steps-valid06artifact hash, leaf hash, inclusion, STH signaturepass
v19-proof-tampered-path06one flipped audit-path elementfail
v20-vc-eddsa-jcs-202207DataIntegrityProof over a JCS-coerced credentialpass
v21-proof-with-family-signature06a real proof carrying issuer_signature: leaf hash, inclusion, tree head, family signature, did:key derivationpass
v22-proof-family-signature-tampered06the same proof with one character of the family signature flippedfail
v23-proof-relabeled-receipt-id06the v18 proof with its top-level receipt_id rewritten to another id; the leaf and head are untouched and still verifyfail
v24-proof-receipt-id-not-a-string06the v18 proof with its top-level receipt_id carried as an array; a label of the wrong type fails the check rather than skipping itfail

v21 and v22 are frozen from the live production proof for tr_8e59bb9641e8 plus the issuer_signature block /api/verify-receipt already serves publicly, so the offline path is pinned against a real receipt rather than a fixture. Neither vector asserts anything about key_established_at: that ordering is advisory (chapter 06, step 4) and never enters a verdict.

v23 pins the label check added on 2026-09-14 after property-based testing of the verifier (chapter 09, section 9.10) showed that a proof's top-level receipt_id was never compared with the id inside the logged leaf: the verifier printed VERIFIED with the relabeled id on the final line. The same check covers tree_size against sth.tree_size. v24 (added the next day, after review) pins that a label of the wrong type fails the check instead of skipping it: the first fix ran the check only for a string receipt_id, so an array, a number, or null in that field bypassed it.

Chapters 01, 08, and 09 have no vectors: they specify structure, plugin interfaces, and controls rather than byte-level algorithms. Frozen values in v09 and v13 are identical to the values pinned by tests/test-family-signing.js and tests/test-merkle-log.js, so the trust gate and this suite cannot drift apart silently.

10.5 Running

sh spec/verifier/run-vectors.sh        # all vectors; non-zero exit on any mismatch
sh spec/verifier/run-vectors.sh -v     # print every step
node spec/verifier/verify-offline.js spec/verifier/vectors/v14-inclusion-valid.json

Output at the time of this draft: vectors: 24/24 matched expected verdicts.

10.6 Adding a vector

  1. State the normative sentence it tests and name the chapter.
  2. Generate expected values from the reference implementation in shared/, never by hand, and never from the verifier under test.
  3. If the vector needs a key, use an ephemeral key and embed only the public half.
  4. Prefer one positive and one negative vector per mechanism; a suite that cannot fail proves nothing.
  5. Never embed a real family's data. Fixtures use the public demo student (Maya Chen) or synthetic values.

10.7 What this does not prove

Twenty-four vectors pin the algorithms. They do not exercise the online endpoints, rate limits, revocation states, tier corroboration, or any legal control; those are covered by the trust gate (npm run test:trust, the trust gate at the time of this draft) and by the operational history in TRUST_REPORT.md.

10.8 The Witness Transcript name

Witness Transcript is a mark of Eformogi, Inc. An implementation whose records pass this conformance suite, in the version of the specification it claims, may call the resulting artifact a Witness Transcript and may use the name in its own prose. An implementation MUST NOT call a record a Witness Transcript unless it passes the suite. The mark MUST NOT be used in the name of a company or a product. This is a trademark policy conditioned on a technical suite, not a certification program: passing it is still not "certified", "official", or "accredited", and nobody, including Eformogi, may describe an implementation that way. The full trademark text is in LICENSING.md.