Public documentation
PATRON records every interaction with a model in a SHA-256 hash chain and builds a Merkle tree over that chain. A firm can prove its AI history was not altered after the fact, without access to our servers and without disclosing the contents of a case file.
SHA-256 · Merkle tree per RFC 6962 · offline verification · AGPL-3.0
Applies to PATRON 1.3.0. Published 23 August 2026, last updated 24 August 2026.
An audit trail in an AI system is an event record that lets you reconstruct who asked a question, when, which model answered it, which sources the answer rested on and who approved it. Chat history is not that. Chat history can be edited and deleted without leaving a mark, and an audit trail exists to catch exactly that kind of change.
The difference shows up under pressure. When compliance or a court asks how an answer came about, a firm with chat history has a screenshot. A firm with an audit trail has evidence that verifies mechanically and whose correctness does not rest on the vendor's goodwill.
The ledger covers work with the model, administrative access to the ledger itself, and operations on personal data. The list of event types is closed and enforced by a CHECK constraint in the database, so a new type cannot appear without a migration visible in the code history.
RecordedUser question and assistant answer, model routing decision, prompt-injection defence pipeline runs, human approval of a change, source control in tabular review, cost cap events.
Meta-auditOpening the audit viewer, exporting an evidence pack, forcing a Merkle root computation, viewing metrics. The intent to take evidence outside is written down before the evidence leaves the system.
RecordedGDPR erasure and export requests, consent to cloud processing for a given matter, enabling and disabling a legal-source connector, document edits.
Design constraint: the event payload holds numbers, identifiers and enumerated values. Document contents and personal data are not in there. That is the condition that lets an evidence pack leave the building without the client's file leaving with it.
The ledger is append-only. Every record stores the digest of the previous record in prev_hash and its own hash, computed from prev_hash joined with the canonical JSON form of the remaining event fields: timestamp, event type, and the identifiers of person, matter, document and payload.
The first record in the system carries a prev_hash of sixty-four zeros. Serialisation is deterministic and independent of key order in the JSON, so the same data always yields the same digest, including after the database moves to another machine.
Delete or alter a record in the middle and the links break. You cannot swap one event without recomputing every event after it, and that leaves a mark in the Merkle roots already sealed.
We chose a hash chain over a ledger signed with a private key because signing means key management and key rotation on the firm's side. What that decision costs is set out below, under limits.
The chain alone detects change. Checking it, though, means walking the whole ledger from the start. A Merkle tree solves that: it proves one event belongs to a sealed block without revealing the other events in that block.
InputThe leaves are the event digests already in the chain. We do not recompute them, so the Merkle layer never modifies the ledger and is read-only with respect to it.
RuleAn internal node is the SHA-256 of the left and right child digests joined together. With an odd count at a level the last one is duplicated, following the RFC 6962 convention used in Certificate Transparency.
OutputWe store the root with the block range, the event count, the time and who computed it. Computation runs on an administrator's command or on an automatic trigger once an event count or a time interval is exceeded.
The algorithm is deterministic: the same block of events always produces the same root. The layer pattern comes from microsoft/agent-governance-toolkit (MIT licence), the algorithm itself from RFC 6962.
Each path gives a different reach of proof at a different cost. Which one you take depends on whether the auditor is examining a single event, the whole history, or evidence carried outside the firm.
Run npm run audit:verify on the firm's side. It walks the ledger and recomputes every link. A record deleted from the middle, reordered or altered after the fact gets flagged. Cost grows linearly with the number of events; that follows from the algorithm, and it is all we can state without a measurement.
A Merkle proof returns the sibling digests from the event up to the block root, in a format that follows RFC 6962. The auditor recomputes it and compares against the stored root. The rest of the block stays covered. Under professional secrecy that is sometimes the only condition on which an audit can happen.
An evidence pack is a self-contained file. You run the verifier with python verify.py. It uses nothing but the Python 3.8 standard library, makes no network calls and needs no access to the firm's database.
The pack verifier works in three stages: checksums of each part against the manifest, then link continuity in the ledger excerpt, then a digest over the whole. It returns exit code 0 for an intact pack, 1 for a tampered one and 2 on a read error, so you can wire it into a script rather than run it by hand.
Article 12 of Regulation (EU) 2024/1689 requires high-risk systems to record events automatically across the system lifecycle. Below, the requirement set against what the ledger actually writes.
| Requirement in article 12 | What PATRON records |
|---|---|
| Recording of events during operation | Every question and answer as a separate timestamped event, appended and never edited |
| Identification of persons exercising oversight | A person identifier on every event, plus a distinct event type for human approval of a change |
| Input data leading to the output | Model routing decision, the sources an answer cited, and the source-control verdict in three classes |
| System version and configuration | Application and connector versions in the evidence pack, together with a fingerprint of the prompts used |
| Ability to demonstrate compliance to an authority | Export of a pack verifiable outside the system; the export itself is written to the ledger |
A MateMatic reading of the AI Act and GDPR, not a position of any bar association. For a formal compliance assessment use the consolidated text on EUR-Lex, CELEX 32024R1689. Whether a specific deployment counts as high-risk depends on how the firm uses it, not on the tool alone.
A hash chain detects a change to a record. That is not the same as proving who produced the record. Without a cryptographic signature a firm can deny that a given pack came from it, and a digest alone will not settle the argument.
An Ed25519 signature with an RFC 3161 timestamp is reserved here as a separate architectural decision and is not implemented. We say so plainly, because in a dispute the gap between detecting change and non-repudiation is often the point.
We also impose no retention policy. The ledger grows for as long as the firm keeps it, and how long to keep it stays the firm's decision, to be reconciled with GDPR and with professional secrecy.
Each of these limits is checkable in the code: no signing in the module that builds the pack, no purge rule in the database schema.
How is an audit trail different from chat history?
Chat history can be changed and nobody will notice. An audit trail binds records with digests, so deleting or swapping an entry breaks the continuity and shows. Chat history answers the question "what". An audit trail answers the question "did this really happen that way".
How do I check the audit trail in a law firm's AI system?
Ask the vendor for the algorithm, a verifier that runs without contacting their server, and a sample evidence pack. If verification requires logging into the vendor's system, that is not an audit but a guided tour: you are checking their claim with their tool. The answer "we have a full audit log" means nothing until you see what checks it.
Does the auditor need access to client files?
No. Nothing an auditor receives contains the text of a document, and the server masks personal data before the pack leaves the system. A Merkle proof confirms a single event without uncovering the rest of the block.
Why RFC 6962 specifically?
It is the Certificate Transparency specification, proven in public auditing of certificates across the internet. Its tree construction and proof format are written down, so an auditor can build their own verifier instead of trusting ours. We reached for an existing standard rather than inventing one, which is also why an auditor can check our implementation against a published specification instead of against our word.
Who can export an evidence pack?
It depends which package you mean. An administrator on a list of addresses the firm maintains exports the archive of a single ledger event. The author of a document downloads the evidence pack for that document, because the boundary is the case, not a role. The ledger records the intent to take evidence out in both cases, before the evidence exists.
Does open source make the ledger easier to tamper with?
The security here does not rest on keeping the algorithm secret, it rests on the properties of the hash function. Open code lets a firm and its auditor confirm that we record what we claim to record. A closed product would ask them to take that claim on trust.
PATRON runs on the firm's hardware. The ledger, the verifier and the code are there from the first launch.