Navigation
What We AreThe BrainPortfolioThe Lab's LabBuilt For YouThe WhiteboardServices & Prices
Let's Talk →
← The Whiteboard

What should an AI decision audit trail contain?

Collibra, PwC and ISACA all tell you to keep one, and not one of them names a field. Here is the record, the properties, the law each field answers to, and a schema you can fork.

An AI decision audit trail contains eight fields: the input as received at the trust boundary, the model requested, the model returned, the prompt as a digest of resolved bytes, retrieved context as chunk digests plus a corpus snapshot id, the output committed at generation, the human decision and what that human saw, and a server-assigned sequence number. Payloads belong in a keyed, erasable store. Digests belong in the append-only one.

Ross Jones — Founder, The Hopium Lab. Last modified 22 July 2026.

Twenty-four products across fifteen sectors, seventeen of them live, several carrying evidence layers a third party checks without trusting me. Architecture supports a conformity case and never confers one. Independence is accredited under ISO/IEC 17065 and ISO/IEC 42006, never architectural; my tooling is first-party. Engineering, not legal advice.

Do the governance vendors say what goes in the record?

No. The commercial surface names categories and stops. Collibra's page asks for agent identity and version, the trigger and on whose behalf, every tool call with inputs and outputs, and "the decision trace, the sequence of steps and the context retrieved at each" — no field names, no serialisation, no hash algorithm. PwC's Responsible AI Toolkit reaches interoperable documentation and a metadata strategy; ISACA sells a certification and a control-design toolkit. ISO/IEC 42001 Annex A control A.6.2.8 asks an organisation to determine when to enable event logging across the lifecycle. The control says when to log and why. Never what.

The engineering surface has the inverse problem. MLflow Tracing ships a real object model — inputs, outputs and metadata per step, latency, token usage — and it documents no tamper evidence, no canonical serialisation and no append-only guarantee, because it is an observability tool, which is a different job.

The governance vendors ship integrity language with no schema. The tracing tools ship a schema with no integrity properties. "We have audit trails" survives a procurement call and dies in an audit because nobody ships both halves.

Why not just use the OpenTelemetry GenAI conventions?

Because no stable version of them exists. Verified 22 July 2026: every gen_ai.* attribute in the OpenTelemetry registry is deprecated and relocated to a dedicated GenAI repository that has no releases published and a TODO where its schema URL goes. Defaults diverge too: observability omits prompt content unless opted in, because traces leak. Evidence defaults the other way.

Use the attribute names where they align. Be a superset, not a competitor. gen_ai.request.model and gen_ai.response.model are two attributes for a reason: a family alias resolves to a dated snapshot that changes without notice, so a record holding only the requested identifier cannot establish which weights produced the output. Log both, plus gen_ai.response.id. One caveat with no clean fix — a provider can retire a dated snapshot inside the retention window, leaving an identifier that outlives the artefact it names.

W3C PROV-O has been a Recommendation since 30 April 2013, and its graph model is the wrong shape for an append-only write path. Emit flat sequenced events, derive PROV afterwards.

Which fields do auditors ask for that teams never stored?

Five, and the gap has the same shape every time.

What the auditor asks forWhat the system storedWhat the gap costs
The input exactly as it arrivedInput after normalisation and scrubbingThe scrubber changed in March. The stored input never reached the model.
The prompt that ranprompt_template: "risk_v2"Templates move. Reconstruction yields a confident account of a decision nobody made.
Everything the model could seeThe user's query stringRetrieval is stochastic and indexes drift. The query returns a different set today.
The output as issuedOutput after formatting and redactionReviewed text and recorded text differ, and both look authoritative.
Every attempt, refusals includedSuccessful completions onlyDenials are the contested records, and selective logging is invisible without a count.

Why commit the output instead of regenerating it later?

Because temperature 0 is not determinism. Thinking Machines Lab showed on 10 September 2025 that greedy decoding fails to reproduce: matmul, RMSNorm and attention kernels are not batch-invariant, so output depends on server-side batch size — on unrelated concurrent load from other users. The same prompt run 1,000 times on Qwen3-235B-A22B-Instruct-2507 under vLLM produced 80 unique completions; with batch-invariant kernels enabled, all 1,000 were identical. Determinism is purchasable, priced in throughput, never acquired by accident.

Retrieval carries the same defect plus corpus drift. Store per-chunk digests, a corpus snapshot id and the retrieval parameters, resolvable against a versioned immutable corpus. Retrieval over a regulated corpus has its own failure surface.

The record is the evidence. A system promising to regenerate the answer at audit time has promised something the inference stack cannot deliver, and the promise comes due in front of someone with subpoena powers.

Storage cost is the honest objection: verbatim context multiplies record size and copies personal data into the audit store. The Decision Event Schema in arXiv:2604.09296 (10 April 2026) answers with tiered evidence — lightweight, sampled, full — matched to decision risk. Tiering is right for payloads and wrong the moment it touches record identity: risk-tier what you capture, never the sequence.

What does the human-decision field have to prove?

Engagement, not identity. EU AI Act Article 26(2) requires deployers to assign oversight to natural persons with the necessary competence, training and authority, and an approver id evidences none of the three. CJEU Case C-203/22, decided 27 February 2025, requires a controller to explain the procedure and principles actually applied to produce a specific result, intelligibly, with trade-secret claims routed to a supervisory authority rather than defeating the right. CFPB Circular 2023-03 holds that algorithmic complexity excuses nobody from naming the principal reason for an adverse action.

Make the field an object: actor id, decided at, evidence digest, seconds on screen, divergence from the model, rationale digest. Divergence rate shows whether oversight is real. A queue at zero divergence has automated the decision and hired a witness.

Recording who approved a decision without recording what they were shown specifies exactly the field a rubber stamp fills in fastest.

Which properties does the record actually need?

Four: append-only, canonically serialised, externally witnessed, retained to purpose.

Append-only is regulatory doctrine rather than cryptographic taste. The SEC's amendments to Rule 17a-4(f), adopted 12 October 2022 with broker-dealer compliance from 3 May 2023, accept an audit trail as an alternative to write-once storage, provided it preserves every modification and deletion, the time of each operator action, and who took it.

Canonically serialised means RFC 8785 — Informational, Independent Submission, June 2020, not an IETF standard whatever your architect claims. Constraints most teams break on day one: I-JSON input, no duplicate property names, IEEE 754 doubles with larger numbers carried as strings, Unicode preserved as-is. A money amount or unnormalised user text hashes two ways for one record. Deterministic CBOR is the alternative; protobuf is not canonical across implementations.

Externally witnessed is the property the word "verifiable" smuggles past review. RFC 9162 — Experimental, December 2021, obsoleting RFC 6962 on paper while deployed transparency logs largely still run v1 — concedes that a misbehaving log can show inconsistent views to different clients. A hash chain operated by the party under audit proves nothing against that party. Publish periodic tree heads to a witness outside the perimeter, co-sign, or take an RFC 3161 token from an authority you do not operate. Mechanism sits in the tamper-evident note and the domain-separation note.

Retained to purpose is quoted regulation rather than a principle I invented. Article 19(1) binds providers, Article 26(6) binds deployers, both to a period appropriate to the intended purpose and at least six months. Six months is a floor, and the Article 12 mechanics sit separately.

A sequence number buys gap detection and ordering, never tamper evidence, because an operator can renumber, and a global counter implies a single writer or a coordination service. Per-stream sequences plus a periodic global Merkle head is the shape that ships.

How does an append-only record survive the right to erasure?

By never chaining the payload. EDPB Guidelines 01/2025 on pseudonymisation, adopted 16 January 2025, confirm pseudonymised data remains personal data, so hashing an identifier at the boundary keeps the record inside GDPR retention, access and erasure obligations. Split the stores: digests and structure in the append-only log, payloads encrypted per subject in a keyed one. Destroy the subject key and the personal data becomes inaccessible while every proof still verifies, because only the commitment was ever chained. Crypto-shredding is defensible rather than settled, and no stronger than the key management underneath.

A digest is not an explanation either. C-203/22 demands intelligibility and a SHA-256 string is intelligible to nobody: digest in the chain, preimage retrievable from an access-controlled store for the full retention period. One sentence governs every field above — can you rebuild the answer without calling the model? If not, you don't have a system. You have a demo with a try/except around it. The replay test turns the question into a pass or fail.

How does an AI decision record fail?

In seven named ways, none of them cryptographic.

  • Category logging. The field is called prompt and holds a template name. Diablo, my seventeen-category readiness auditor, has a rule for it because it recurs in every audit that touches an LLM.
  • Marking your own homework. The verifier reads entries and the expected root from one store, so a single write credential rewrites both and verification passes green.
  • Digest without artefact. Hash retained, bytes deleted, nothing to hand anyone.
  • Re-fetch replay. Retrieval rebuilt at audit time against a reindexed corpus — yesterday's decision, today's evidence.
  • Payload in the ledger. Personal data in write-once storage, unerasable, turning an integrity control into a permanent data-protection incident.
  • Drop-on-backpressure. A bounded async queue discards under load, and the discarded events are the incident. Failing to log must fail the operation.
  • Stale status citation. RFC 8785 called an IETF standard, RFC 9162 called the CT standard, C2PA cited at 2.2 when the line is 2.4, Article 19 attributed to deployers. Each is checkable in thirty seconds by whoever decides whether to believe the rest.

What does the record schema look like?

Twenty-three fields, two stores, and what each one answers to. The eight above are load-bearing; the rest is the plumbing that makes them provable. A nine-field competitor already ranks — the AI Judgment Trail spec, OpenTelemetry-aligned, asking which model ran under what policy and whether a human intervened. The integrity half below is what neither that spec nor the Decision Event Schema leads with.

AI DECISION RECORD — v1.0 (22 July 2026)
The Hopium Lab. Supports a conformity case. Confers none. Not legal advice.

APPEND-ONLY STORE — canonicalised (RFC 8785), appended, then hashed
  record_id        uuidv7          server-generated, sortable
  seq              uint64          per-stream, gapless, server-assigned
  stream_id        string          the shard the sequence belongs to
  phase            enum            attempt | success | deny | error
  parent_record_id uuidv7 | null   the attempt being closed
  ts_server        RFC 3339+offset server clock
  ts_caller        RFC 3339 | null caller-asserted, never trusted
  system_id        URI             which capability decided
  system_version   semver          deployed build, not repo tag
  model_requested  string          gen_ai.request.model
  model_returned   string          gen_ai.response.model — load-bearing
  provider_call_id string | null   gen_ai.response.id
  decode_params    object          temperature, top_p, seed, max_tokens
  input_digest     sha-256         over the bytes as received,
                                   pre-normalisation
  prompt_digest    sha-256         of the RESOLVED bytes, post-interpolation
  retrieval        object          see below
  output_digest    sha-256         committed at generation
  tool_calls[]     array           name, args_digest, result_digest,
                                   idempotency_key, outcome
  policy_version   string          the rules that gated the decision
  human            object | null   see below
  payload_ref      URI             pointer into the keyed store
  prev_hash        sha-256         null at genesis, domain-separated
  record_hash      sha-256         over the canonical form above

  retrieval = { corpus_snapshot_id, index_build_id, k, ef_search,
                filters, chunk_digests[] }
  human     = { actor_id, decided_at, evidence_digest, seconds_shown,
                diverged_from_model: bool, rationale_digest }

KEYED PAYLOAD STORE — encrypted per subject, erasable, access-controlled
  input_raw · prompt_resolved · retrieved_chunks · output_raw ·
  human_evidence
  Redaction is itself an event: store the raw bytes encrypted. If policy
  forbids that, log a redaction_policy_version and digest BOTH forms.
  A digest whose preimage was never retained proves nothing.
  Erase by destroying the subject key: digests stay, proofs verify,
  the absence is visible and dated.

WITNESS
  Periodic Merkle head -> RFC 3161 token from an authority you do not
  operate, and/or co-signature by a party outside your perimeter.
  Self-witnessed heads are decoration.

ANSWERS TO
  AI Act Art. 26(2) oversight ..... human.actor_id + evidence_digest
  AI Act Art. 19(1) / 26(6) ....... retention policy on both stores
  GDPR Art. 15(1)(h), C-203/22 .... prompt_digest + retrievable preimage
  GDPR Art. 17 erasure ............ subject-key destruction
  SEC 17a-4(f) audit trail ........ seq + prev_hash + record_hash + actor
  ISO/IEC 42001 A.6.2.8 ........... coverage policy: which calls log at all

NIGHTLY
  For attempts opened before T-15min:
    count(attempt) == count(success) + count(deny) + count(error)
  Anything unresolved past the timeout is an orphan, not a rounding error.
  Alert on orphan count, never on the raw difference.

Fork it, cut what your risk tier does not need, argue with the rest. Every field is a column and every digest is one library call, so cost was never the reason nobody has one. Build the evidence layer before the first regulated decision ships and the work is a fortnight. Retrofit it into a log never designed to hold evidence and the bill arrives the day somebody asks about a decision from March.

Ross Jones, Founder, The Hopium Lab. Last modified 22 July 2026. Engineering guidance, not legal advice.