Skip to content

Evidence packet

Every event on a loan (intake and each document received, each pipeline stage, each reconciliation run and finding, each finding action, assignment, approval or rejection, boarding step, wire step, funding, sealing) is a row in evidence_events with a sequence number, the actor, a JSON payload, the payload’s SHA-256, the previous link’s hash and the chain hash. The application’s database user can insert rows but cannot update or delete them.

GET /v1/loans/{ref}/evidence/verify re-hashes the chain and reports intact, the length, and the first broken sequence number if any. A nightly job (02:00 UTC) does this for every loan and records the result in evidence.last_verification; a break is logged as an error (event 5120) and shows on the Diagnostics page. Payloads are hashed in a canonical form (sorted keys, compact, normalized numbers) so the database’s own JSON normalization cannot break a valid chain, but a single changed value in a stored payload does.

Every export re-verifies the chain and includes the result, and Seal refuses to run on a chain that does not verify.

  • GET /v1/loans/{ref}/evidence/export?format=pdf: the human-readable packet, downloaded as evidence_{ref}.pdf. Page one carries the verification result, then the loan, every document with its type, page count and SHA-256, the findings ledger of the latest run (rule, severity, status, detail), the approvals and decisions, and the full chain (sequence, event, actor, time, hash).
  • GET /v1/loans/{ref}/evidence/export?format=json (the default): the machine-readable bundle with the loan, documents and hashes, the latest run’s findings, the approval events and every evidence event with its full payload (who acted, reason codes, justifications and notes), plus the verification result. The same bundle is available as export_evidence over MCP.

Both are available from the loan page’s Evidence & closing section (Download packet (PDF) and Download bundle (JSON)). The packet contains what the bank already holds; nothing is fetched from outside.

The Evidence section of a loan lists the events in sequence order, each with its type, actor, time and the start of its chain hash; click a row to expand its payload. The verification badge in Evidence & closing shows the chain as intact with its length, or broken at the first bad sequence number. Auditors (auditor_readonly) can read all of this but cannot change anything.

The evidence list on a loan page: each event with its actor, time and hash.The evidence list on a loan page: each event with its actor, time and hash.
The evidence chain on the loan page: one row per event, each hashed over the previous.

A nightly sweep (04:00 UTC) deletes the stored PDFs and page images of loans that have been sealed for longer than documents.retention_days (default 2555 days, about seven years). The database record stays: metadata, SHA-256 hashes, extracted values, findings and the evidence chain, so packets still verify and still name every document by hash. Files shared with a loan that is still inside the policy are kept. The result of the last sweep is in documents.last_retention.