experimental@0xsarwagya/clinical-receipt
Your clinical AI produced an answer. Can you prove how?
I refuse to put a blockchain behind a clinical decision because an auditor needs to know how it happened.
Modern clinical AI systems produce answers. Six months later, the organization has fragments of that story in seven systems — the FHIR input in the EHR, the retrieval logs in the vector store, the prompt in the LLM gateway, the guardrail decision in the policy engine, the review in the audit trail, the final output in the record.
clinical-receipt writes one story for one run.
Capture, commit, sign, disclose, verify
The recorder turns a workflow into a signed, hash-linked event graph — inputs, evidence, prompts, models, tools, guardrails, human decisions, outputs. Every event carries a cryptographic commitment; every commit threads a Merkle root; the root is signed by whoever ran the workflow.
pnpm add @0xsarwagya/clinical-receipt# or: npm install @0xsarwagya/clinical-receiptimport { createReceipt, createEd25519Signer } from "@0xsarwagya/clinical-receipt";
const run = await createReceipt({
workflow: { id: "discharge-review", version: "2.1.0" },
});
await run.input.observed({ value: patientBundle });
await run.model.responded({ value: modelOutput });
await run.output.committed({ value: finalOutput });
const receipt = await run.finalize({
signer: await createEd25519Signer({ generate: true }),
});Verify anywhere — offline, no service, no trust in the original app:
import { verifyReceipt, importVerificationKey } from "@0xsarwagya/clinical-receipt/verify";
const report = await verifyReceipt(receipt, {
keys: [await importVerificationKey(publicJwk)],
});What CI proves, on every commit
| Runtime | SHA-256 | Ed25519 | ECDSA P-256 | JCS |
|---|---|---|---|---|
| Node ≥ 20 | ✓ | ✓ | ✓ | ✓ RFC 8785 |
| Modern browsers | ✓ | ✓ Chromium 137+ · Firefox 129+ · Safari 17+ | ✓ | ✓ RFC 8785 |
| Ed25519 signatures may be hedged by the engine; vectors pin the verify direction only. | ||||
| Edge runtimes | ✓ | ✓ where WebCrypto Ed25519 is enabled | ✓ | ✓ RFC 8785 |
| No Node built-ins — recorder and verifier run anywhere WebCrypto does. | ||||
The three things a receipt can prove
- Integrity. The record has not changed since finalize.
- Selective disclosure. Any subset of events can be revealed with cryptographic proof they belong to the original receipt.
- Signature. Someone possessing a specific private key endorsed the root — nothing about identity, nothing about truth.
Everything else is honest silence. That is the correct posture for clinical software.
Know exactly which clinical state your AI saw
Since v0.2, wrap your FHIR access and reads, searches, and writes become part of the receipt. A resource reference tells you where the data is. A receipt tells you which version actually participated.
import { instrumentFHIR } from "@0xsarwagya/clinical-receipt/fhir";
const fhir = instrumentFHIR({
run,
client,
});
const context = await fhir.search("Observation", { patient: patientId });
const answer = await model.generate(context);
await fhir.create("ClinicalImpression", answer);Observation/a/_history/4
Observation/b/_history/2
↓
AI run
↓
ClinicalImpression/789/_history/1