Skip to content

API: Proofs and receipts

Capability state: shape-only. Receipts are present and structurally enforced but not yet cryptographically verifiable end-to-end. Proof issuance is in closed_runtime_boundary (see 022 gap report items 5, 17).

The receipt and proof operations let a relying party verify the shape of a receipt and request entitlement-scoped proof bundles. See concepts: receipts and proofs.

Verify a receipt’s shape (locally or via cloud).

POST /v1/receipts/verify
state: shape-only
runtime_owner: verifier
sdk_role: local or cloud verification
request_record: CloudReceiptVerifyRequest
responses: verification_result
interface ReceiptVerifyRequest {
receipt: MembraneReceipt;
}
{
"operation": "receipt.verify",
"outcome": "verified",
"body": { "verified": true, "fixture": true }
}

Today this checks the receipt shape (ref present, outcome in known enum). It does not verify a cryptographic signature against a runtime signer. That capability is roadmapped.

const result = await client.verifyReceipt(receipt);

The TS SDK also exports a standalone shape verifier:

import { verifyFixtureReceipt } from "@gestalt/sdk";
const result = verifyFixtureReceipt(receipt);
// { verified: true, fixture: true, reasons: ["receipt shape accepted"] }

Request scoped disclosure.

POST /v1/proofs/request
state: shape-only
sdk_role: request scoped disclosure
request_record: CloudProofRequest
responses: proof_bundle | refusal | receipt
interface ProofRequest {
tenant: GestaltRef;
subjectCompany: GestaltRef;
scope: "self_audit" | "advisor_review" | "external_counterparty";
fields: string[];
purpose: string;
fixture?: boolean;
}

Refused (no entitlement):

{
"operation": "proof.request",
"outcome": "refused",
"body": { "failedGate": "missing_entitlement" },
"receipt": {...}
}

This refusal is deliberate. There is no path to a “give me everything” proof. Disclosure is always entitlement-scoped.

const proof = await client.requestProof({
tenant: "tenant_node:rheinwerk_calibration",
subjectCompany: "company_geist:rheinwerk_calibration",
scope: "advisor_review",
fields: ["invoice", "payment_observation", "advisor_opinion"],
purpose: "Q1 2026 Steuerberater review of receivable settlement",
});

Request entitled M6 proof bundle.

POST /v1/proofs/bundle
state: staging-durable
sdk_role: request entitled M6 proof bundle with independent-verifier canonical bytes
request_record: CloudProofBundleRequest
responses: proof_bundle | independent_verifier | refusal | receipt
interface ProofBundleRequest {
tenant?: GestaltRef;
entitlement?: GestaltRef;
}
{
"operation": "proof.bundle",
"outcome": "verified",
"body": {
"bundle": {
"id": "proof_bundle:m6_cross_domain_cloud_authority_worldline",
"productionAdmission": false
}
},
"receipt": {...}
}

Today returns a staging-durable fixture manifest. The manifest includes an audit-kernel canonical state commitment, receipt graph, signature graph, and redaction flags that can be verified locally with gestalt-proof or SDK helpers. Production issuance remains gated.

const bundle = await client.requestProofBundle({
tenant: "tenant_node:rheinwerk_calibration",
entitlement: "entitlement:fixture_proof_bundle",
});

Verify a durable proof bundle manifest commitment through the membrane.

POST /v1/proofs/verify
state: staging-durable, local-verifier-compatible
sdk_role: verify durable proof bundle manifest without raw database access
request_record: CloudProofBundleVerifyRequest
responses: verification_result | independent_verifier_compatibility | refusal | receipt

The same exported JSON can be checked without Gestalt database credentials:

Terminal window
cargo run -q -p gestalt-proof -- verify \
--proof-json proof.json \
--manifest-commitment sha256:...

The TypeScript SDK exposes verifyExportedProofBundle(exported, expected); the Rust SDK exposes verify_exported_proof_bundle(exported, expected).

When proof issuance lands, a bundle will carry:

  • the receipts for the relevant atoms,
  • the capability atoms they cited (with authority sources),
  • the authority package versions in force at admission time,
  • the evidence bundles referenced,
  • the signer provenance chain (which runtime signer produced the receipts, which key version),
  • the lens / entitlement under which the bundle was disclosed,
  • the disclosure scope (what fields the relying party may display, retain, forward),
  • the validity window,
  • the revocation path.

Relying parties will be able to verify a bundle entirely offline against the published runtime signer key and the published authority package hashes. No need to call back to Gestalt.

The forbidden surface explicitly includes unscoped_proof_bundle_disclosure. There is no path through any SDK or any tool to a “give me everything” bundle. By design.

missing_entitlement
proof_entitlement_missing
proof_disclosure_scope_unauthorized