Verification receipts
CrossGuard, UCPIntegration, and the built-in OpenResponsesIntegration tools create receipts automatically. Custom Open Responses tools get a receipt only if their verification_fn creates one. Direct calls to the other guards (for example ComplianceGuard.verify_aml_flag) return a result object without a receipt; create one yourself with ReceiptGenerator when you need an audit record:
Receipt fields
Every field below is part of the signed payload.Cryptographic signature
Since v3.0.0, signatures are keyed HMAC-SHA256 over the full canonical receipt: every field in the table above, as sorted compact JSON. The verifier holds the key; there is no default key. The earlier unkeyedget_signature() (no argument) was removed in v3.0.0.
computed_value, violations,
status, proof_steps, anything in the table) produces a different
signature. This is tamper evidence for holders of the key: it does not
establish issuer identity, third-party verifiability, or
non-repudiation. Public-key attestation (ES256) is planned separately;
see qwed-finance#37.
Audit log
Collect receipts in one place.AuditLog keeps them in memory; export them to store them with your other audit records:
Query failed verifications
Rules and records
These are the rules the checks implement and the records QWED Finance can give you. Using QWED Finance does not make a system compliant with any of them: that is for your own compliance review.Adversarial defense
The test suite includes adversarial inputs written to get past the guards:Test suites
For compliance officers
When a regulator asks: “How do you verify AI decisions?” Show them:- Input hash: the SHA-256 of the model output that was checked
- Timestamp: when the check ran
- Engine: which engine checked it (for example Z3 or SymPy)
- Proof steps: the steps the guard computed to reach its result
- Receipt signature: HMAC tamper evidence, for holders of the key
signature field; get_signature(signing_key)
computes it on demand from the full receipt. Export both artifacts under
unique paths, one pair per receipt, so no export overwrites an earlier
audit record:
receipt-abc-123.json contains the full receipt:
get_signature(signing_key) does and compare it with the stored
signature. Every receipt name found in the directory is checked, a
.json or .sig file without its partner counts as a failure, and one
failure never stops the rest.
The auditor needs the verifier’s HMAC key. It is never stored with the
receipts, so provision it to the auditor through a secret store or an
environment variable:
Related pages
- Previous: The 11 guards: each guard with examples
- Next: QWED UCP: transaction verification for AI commerce: connect finance checks to commerce flows
- See also: QWED Open Responses: verified tool calls for AI agents: check agent tool calls before they run
Source code and adversarial tests: github.com/QWED-AI/qwed-finance