enruta-verify
v0.3.0
Published
Offline verifier for Enruta Evidence Records (payment and linked records, schema enruta/0, enruta/0.2 and enruta/0.3). One file, no dependencies, no network, no account.
Maintainers
Readme
enruta-verify
Offline verifier for Enruta Evidence Records. One file, no dependencies, no network, no account.
npx enruta-verify rec_01J9….json # one record, bundle found alongside
npx enruta-verify ./export-2026-11/ # a whole export, chain checked end to end
npx enruta-verify rec_01J9….json --json # machine-readable reportExit 0 on PASS, 1 on FAIL, 2 when it cannot verify (missing bundle, unreadable input).
What it verifies
Two kinds of record share one chain per principal, and the verifier treats them alike:
- Payment records (
kind: payment, or nokindonenruta/0): one per payment attempt. Schemaenruta/0is checked with the v0 rules;enruta/0.2adds the login id, the three intent layers, anobserveresult with itsshadow_result, the signed risk assessment, the mandate account, deviations, snapshot hashes and a failure class;enruta/0.3adds the trust model:request.intent(the user's words, the slots, the coverage and the clarifying questions with their answers), aclarifyresult,decision.judgement(the rules in order and the model consulted),agent.identity(the assurance level A0–A3 and the anchors it rests on),payee.identity(the merchant as the agent side checked it),economics_ref, andchain.relation: occurrence_offor a payment under a recurrence. - Linked records (
kind: reversal | dispute_packet | dispute_outcome | settlement_record | reconciliation_line | reconciliation_report | consent_record | kya_attestation | agent_pause | agent_order | recurrence): one per supporting object, pointing back withchain.relationandchain.of(andof_hash, the seal hash of the record it follows from). The header line prints the kind and the chain:# rec_… org_halvern #4 reversal reversal_of rec_…; a payment with an identity prints its level:# rec_… org_halvern #3 occurrence_of rec_… assurance A3.
What it checks
- Canonical form. The bytes are the RFC 8785 canonical form of their JSON, and the record matches its schema (
schema/evidence-record.schema.json, aoneOfof the payment and the linked shape). The detail names the schema it found. - Seal. SHA-256 over the canonical bytes (with
seal.hashremoved) equalsseal.hash, and the bundle names this record. - Chain.
seal.previs the previous record's hash when that record is in the same export; otherwise the gap is reported. Linked records are chain members like any other; when a record'schain.ofis also in the export, itsof_hashis compared with that record's sealed hash. - Attestations. Every RFC 3161 token in the bundle verifies under the snapshotted authority certificate and stamps this record's hash; a seal-time stamp more than a day after
created_atmeans the record was back-dated. The daily-root inclusion proof leads to the checkpoint root, the checkpoint signature verifies, and the checkpoint date is the record's date. - Keys. On
enruta/0.3, every raw identity evidence object in the bundle (artifacts.identity[]) names an anchor of the record and hashes (JCS, SHA-256) to itsevidence_hash, the assurance level is never above what the anchors support, and the model judgement's input and output (artifacts.judgement_io) hash toinput_hashandoutput_hash. Every key the record references is in the bundle with a provenance tag. The seal signature, the policy signature, the approval (a WebAuthn assertion or a signed link event), the mandate, the merchant's authorization on the protocol object, the receipt signature and, onenruta/0.2, the platform's signature over the risk assessment all verify under those keys. On a linked record the approval is challenged with the digest the subject declares (its own hash, theroot_hashit carries, orsubject.binds), and the subject's evidence is checked: a merchant's detached signature over the subject (or over the signed source object the subject binds bysource_digest), the rail's own object, or the organization's signature over the subject hash. - Strength. The record's own labels are reported and never allowed above what the evidence supports: for a linked record's
subject,third_party_signedneeds the merchant's signature or the rail's object,customer_attestedthe organization's signature.
vectors/ holds a valid enruta/0 chain, a tampered record, a back-dated record, a chain with a gap, a valid enruta/0.2 chain (payment, reversal, settlement record, reconciliation line), a tampered reversal, a valid enruta/0.3 chain (recurrence, legal-entity attestation, a clarified, model-judged A3 payment) and that payment with edited identity evidence; vectors/README.md says what each must produce.
Apache-2.0.
