oss.sarwagya.wtf

Verifying

Three layers of verification. v0.2 ships two of them; the third is next-release work.

verifyFHIR produces a report with three claim axes.

Layer 1 — Receipt integrity

Runs the base receipt verifier — Merkle root, per-event commitment recomputation, signature verification. Answers did the committed record change? Zero network. Handled by the same code that ships in @0xsarwagya/clinical-receipt/verify.

Failure surfaces in report.integrity.

Layer 2 — FHIR commitment integrity

Walks the FHIR events and, for any resource the caller supplies, checks that the FHIR JSON they hold matches the receipt's commitment. Zero network. Answers do the resources I already hold match the digests the receipt pinned?

import { verifyFHIR } from "@0xsarwagya/clinical-receipt/verify";
 
const patient = await hospitalArchive.load("Patient/123");
const report = await verifyFHIR(receipt, {
  resources: {
    "Patient/123": patient,
  },
});
console.log(report.fhir.commitments); // "valid" | "invalid" | "not-applicable"

References the caller does not supply are reported as no-content-supplied — not as failures. A partial answer is still an answer.

Layer 3 — Live FHIR store comparison

Not shipped in v0.2. A follow-up release adds a live-comparison mode that fetches the receipt's referenced resources from the FHIR server today, canonicalizes them under fhir-json-r4@1, and compares against the pinned digests. Answers does the FHIR store still return what the receipt says it returned?

The design keeps live comparison on a separate call surface so it never happens implicitly and never breaks the offline guarantee.

Report shape

type FhirVerificationReport = {
  ...VerificationReport,
  fhir: {
    commitments: "valid" | "invalid" | "not-applicable",
    understood: boolean,
    resources: Array<{
      reference: string,
      eventId: string,
      commitment: "match" | "mismatch" | "no-content-supplied"
                | "unsupported-algorithm",
    }>,
    trace: FhirTrace, // reads, searches, writes, transactions, errors,
                     // lineage — the projection inspectFHIR returns
  },
};

The base report already reports which extensions this verifier understood — a receipt containing FHIR events verified by a FHIR-unaware verifier still verifies for integrity; the extensions.unknown list shows the semantic gap.

What a FHIR receipt still does not claim

Integrity is not truth. verifyFHIR proves:

  • The receipt's Merkle root and per-event commitments are stable.
  • The FHIR resources the caller supplied match what the receipt says the workflow observed at record time.

verifyFHIR does not prove:

  • The workflow's AI output was correct.
  • The FHIR server was truthful about meta.versionId.
  • The workflow saw every relevant FHIR resource — only what came through the instrumentation boundary.
  • A resource with matching digest is medically appropriate.

Every clinical claim is layered on top of that boundary. The receipt is the substrate.