Skip to content

Verifying a Genomarker Receipt

Every Genomarker certified analysis receipt is content-addressed by a SHA-256 hash of its RFC 8785 canonical JSON form, with the integrity block stripped before hashing. Verifying that hash proves the JSON has not been altered since issuance.

What this proves

  • Byte-equivalence: the receipt JSON you hold matches the one Genomarker issued.
  • Integrity of metadata: parameters, software environment, dataset fingerprint, and result hashes are unmodified.

What this does not prove

  • Bit-replay: the receipt does not by itself let a third party re-run the analysis. Replay requires the Replay Sandbox CLI (planned in a future release).
  • Identity: there is no cryptographic signature in the 1.x schema — the hash anchor + URL trust suffices today; future receipts may add signing.

Reference verifier — Python

shell
pip install rfc8785

verify_receipt.py
import hashlib
import json
import sys

import rfc8785

with open("receipt.json", "rb") as f:
    payload = json.loads(f.read())

expected = payload.get("integrity", {}).get("canonical_json_hash")
subject = {k: v for k, v in payload.items() if k != "integrity"}
recomputed = "sha256:" + hashlib.sha256(rfc8785.dumps(subject)).hexdigest()

print("PASS" if expected == recomputed else "FAIL")
print(f"expected={expected}")
print(f"recomputed={recomputed}")
sys.exit(0 if expected == recomputed else 1)

Reference verifier — Node

shell
npm install canonicalize

verify-receipt.mjs
import { readFileSync } from "node:fs";
import { createHash } from "node:crypto";
import canonicalize from "canonicalize";

const payload = JSON.parse(readFileSync("receipt.json", "utf8"));
const expected = payload.integrity?.canonical_json_hash;

const subject = { ...payload };
delete subject.integrity;
const recomputed = "sha256:" + createHash("sha256").update(canonicalize(subject)).digest("hex");

console.log(expected === recomputed ? "PASS" : "FAIL");
console.log("expected=" + expected);
console.log("recomputed=" + recomputed);
process.exit(expected === recomputed ? 0 : 1);

JSON Schema

The full schema for the receipt 1.x family (1.0.0, 1.1.0, 1.2.0, 1.3.0, 1.4.0, 1.5.0, 1.6.0, 1.7.0, 1.8.0, 1.9.0, 1.10.0, and 1.11.0) is published at https://genomarker.com/schemas/receipt-1.0.0.json. Minor bumps add optional fields only and keep this URL — 1.1.0 adds the optional method.handler_specific keys calibration_metrics, decision_curve_analysis, and subgroup_performance (emitted by model-training receipts). 1.2.0 adds the optional method.handler_specific.data_quality confounder pre-flight block (emitted by differential-expression receipts). 1.3.0 adds the optional method.handler_specific.analysis_classification field (one of "pre-specified", "post-hoc", or "exploratory") and the optional method.handler_specific.sap provenance block ({id, payload_sha256, zenodo_doi, locked_at, amendment_chain_depth}) — pre-registered SAP support added in Phase 3 (2B.7.7). 1.4.0 adds the optional method.handler_specific.reporting_checklists block (TRIPOD+AI / REMARK / STARD-AI auto-emission emitted by every inferential handler with applicable checklists; Phase 4 / 2B.7.8) and the optional method.handler_specific.reporting_supplements block (frozen prose snapshot at publish-time). 1.5.0 adds the optional method.handler_specific.repro_score block (Reproducibility Score emission — REPRO-10 / Phase 5 / 2B.7.9; composite 0-100 + letter A/B/C/D/F + 12 per-axis grades + evidence- link map). 1.6.0 adds the optional method.handler_specific.ingest_quality block (Robust Ingest Layer — INGEST-01..04 / Phase 1 v3.0; upload-time gene-ID harmonization + Excel repair + PHI screen + colData alignment + TPM rejection, with the tiered verdict hard-refuse / block-with-override / warn / ok). 1.7.0 adds the optional method.handler_specific.gate block (Tiered Gate + Signed Record — GATE-01 / Phase 2 v3.0; the composite severity-tiered gate verdict across confounder / colData / PHI / high-unmappable / ML-leakage / SAP-amendment surfaces, plus the signed-override attribution when a block-with-override was waived). 1.8.0 fills the previously-reserved integrity.signing slot (RO-Crate / PROV emission — REPRO-12 / Phase 4 v3.0; a detached ES256 JWS over the count-only rigor verdict, verdict_status "origin-signed-replay-pending" — PHI-free and offline-verifiable; null on legacy receipts). 1.9.0 adds the optional method.handler_specific.methods_parse block (Methods-Diff v1 — REPRO-11 / Phase 8 / 2B.7.10; the reproducibility-relevant metadata of the Claude Sonnet 4.6 LLM call that parsed external paper Methods prose into a typed MethodsCandidate — source + prose/system-prompt/parsed-candidate SHA-256s + parser provider/model/version + target handler type + user-confirm timestamp + token counts; emitted only by the methods_parse handler). 1.10.0 adds the optional method.handler_specific.sc_aggregation block (PHI-safe counts-only pseudobulk reduction, emitted by the sc_pseudobulk handler) and the optional method.handler_specific.mast block (MAST mixed-model method, emitted by the sc_mast handler) — Single-Cell DE, STAT-05 / Phase 9. 1.11.0 adds the optional method.handler_specific.evidence_sources_used block (version-only evidence provenance — bundle_version + per-source {version, license} + bundle sha256, no gene list; embedded only at export time when a gene-evidence reference is included) — Gene Evidence Card, GENE-EVID-02/03 / Phase 10. The schema URL is forever-stable; future major versions get new URLs.

Scope notes

The stdlib-only verifiers shipped inside receipt.zip use a hand-rolled canonicalization that is correct for typical payloads but does not cover every RFC 8785 edge case (exotic floats, surrogate-pair keys, U+2028/U+2029). For production verification or audit, prefer the reference snippets above.