Skip to main content

Conformance runs: wai conform

wai conform <kind> --suite <suite> --impl <command or URL> runs one of WAI’s conformance corpora against an implementation, yours or anyone’s, and writes the outcome as a signed record. Every case’s expected answer is the corpus’s own: a verdict, a digest or a reason the corpus states, set from the specification’s text.

wai conform --list                                                    # every kind and suite
wai conform verifier --suite claim --impl "my-verifier verdicts {corpus}"
wai conform decoder --suite score --impl "my-renderer {in} {out}"
wai conform origin --suite http --impl http://127.0.0.1:8380/
wai verify claim.wai-conform.json                                     # the signed result, checked

It runs in a checkout of the standard, which holds the corpora; --root <checkout>/wai names one elsewhere.

Kinds and suites

KindSuiteCorpusA case isIt passes when
verifierclaimclaim-conformance/One vectorThe verdict is the one declared: accept link_hash=<hex>, accept ancestor=<hex> or reject step=<n> reason=<label> (jwp-receipts §3.1)
verifierjwpjwp-conformance/One vectorThe verdict is the one declared (jwp-receipts §2–§6)
verifiersignersigner-conformance/One vectorThe verdict is the one declared (jwp-receipts §7)
verifierconform-resultconform-result-conformance/One recordThe outcome is the one declared: accept conformant=<true or false> or reject step=<n> reason=<code> (conformance-results §4)
decoderscorescore-conformance/A WSCR scoreThe rendered i16le PCM has the declared SHA-256
packagerpolicypack-conformance/A packaging policyIt is admitted with the declared digest (ok <digest>), or refused with the declared reason (packaging §3, §12)
originhttphttp-conformance/objects/An objectIt is served as http-delivery §5.3 and §6.2 require: its bytes, ETag, cache and cross-origin headers, a byte range, HEAD, its head proof and the preflight

Each verifier corpus’s README states its verdict lines.

Adapters

A command. --impl is a command line, run by the system shell, with these placeholders replaced by paths:

PlaceholderReplaced by
{corpus}The corpus file whole: the command answers every case at once, one name<TAB>verdict line each (the verifier suites)
{case}A file holding one case, as the corpus writes it
{in}The case’s input file
{out}A file to write the output to

Without {corpus}, {case} or {in}, the case or input is given on standard input; without {out}, a decoder’s output is read from standard output. The first line a command prints is its verdict; a decoder that refuses exits non-zero. A command is stopped after --timeout seconds (60 unless given).

HTTP. --impl is an http:// URL. Each case is a POST to it: a verifier’s case as JSON, a decoder’s or packager’s input as bytes. The answer is the response’s first line, or the member verdict of a JSON response; a decoder answers 200 with the output, or another status with its refusal. For an origin, the URL is where it serves the corpus’s objects: <url>/<cid>.wai and <url>/<cid>.wai.hp.

The result record

Each run writes a record, <suite>.wai-conform.json; --out names another file, and a file that exists is replaced only with --yes. The record, conform-result/1, is specified in conformance-results: its members and corpus digest (§2), its signature (§3), what a verifier checks and in what order (§4), and the codes it refuses with (§5). Its corpus, conform-result-conformance/, holds accepted and refused records with their outcomes, and wai conform verifier --suite conform-result runs a verifier of these records against it.

{ "wai": "conform-result/1", "kind": "verifier", "suite": "claim",
  "standard": "v0.4.0", "toolchain": { "name": "wai", "version": "0.3.0" },
  "corpus": { "dir": "claim-conformance", "files": 1, "digest": "sha256:…" },
  "implementation": { "adapter": "command", "impl": "my-verifier verdicts {corpus}",
                      "name": null, "version": null, "files": [{ "path": "…", "sha256": "…" }] },
  "started_at": "2026-10-27T12:00:00Z",
  "cases": [{ "name": "…", "pass": true, "expected": "…", "got": "…" }],
  "summary": { "cases": 1, "passed": 1, "failed": 0 }, "conformant": true,
  "key": "ephemeral", "signer_pubkey": "…", "sig": "…" }

wai verify <path> checks every record under a path, in the order of conformance-results §4: that it reads, its version, its members, its signature, and that its summary and conformant are what its cases say. A record changed after it was signed is refused.

Exit status and JSON

ExitMeaning
0Every case passed
1A case failed
2A usage error
4The record would replace a file, and --yes was not given
5The kind, suite, corpus or program is not found
6The implementation’s URL does not answer; safe to retry
7An internal error

--dry-run lists the cases and what would run, and writes nothing. With --json it prints one JSON envelope ("op": "conformance.run"), its data the counts, the failures and the record’s path; without --json the output is text, on a terminal or not.

WAI’s continuous integration runs the corpora’s independent verifiers, second implementations written from the specification’s text and sharing no code with the reference, through wai conform, as it would run any other implementation.