All four platforms available

elan1 Library · 02

Evidence for auditors: reading an elan1 proof record

A brief for internal and external auditors: what each of the 16 fields tells you, how to walk the chain at L1, how to sample a period, and what verification does not prove.

This paper shows an auditor how to read an elan1 proof record field by field: who asked, which rules ran, who approved, what changed and how the record links to the one before. It explains how to recompute the digest and walk the chain, and what changes from L2, when records are signed.

Document
Brief
Version
v1.0 · 10 Oct 2026
Status
Published. L1 Guarded and L2 Attested are available.
Scope
L1 Guarded and L2 Attested. Mode A and Mode B.
Written for
Internal audit · External auditors and their counterparties · Financial controllers · CA firms
Reading time
15 minutes
Publisher
ELAN1 AGENTIC TECHNOLOGIES PRIVATE LIMITED
Access
Ungated. Free to read, print and share.

Everything this paper describes is available in elan1 Govern, Work, Decide and Run. Each capability carries its assurance level. Every record, identifier and value shown is an illustrative specimen, not customer data.

Abstract

An auditor asked to rely on an AI agent’s change needs three things: who proposed it, under which rules it was checked, and who approved it. This brief shows where each answer sits in an elan1 proof record, and how to test that the record has not changed since it was sealed.

It covers the L1 Guarded checks you can run yourself, the evidence bundle and offline verifier of L2 Attested, and a plain table of what verification proves and what it does not. It is written to be handed to an audit team without a sales conversation.

1. What the record is evidence of

When an AI agent changes a ledger, an invoice or a claim, the audit question is familiar even if the actor is not. Was the change authorised? Was it checked against the rules in force? Is the evidence complete, and has it been altered since? An application log can answer some of this, but rarely all of it, and almost never in a form an auditor can test without trusting the system that wrote it.

An elan1 proof record answers those questions for one kind of event: a consequential write that took the governed write path. Every such write — committed, refused or expired — produces exactly one record of sixteen fields, written synchronously before the caller receives its answer, and chained by hash to the record before it in the same tenant.

It is evidence about the control, not about the transaction. It tells you that a write was proposed, checked against named rules at a named version, decided by a named actor at a named autonomy level, and recorded at a stated time. It does not tell you that the invoice was genuine or that the journal entry was the right one. That distinction runs through every section of this brief.

2. The 16 fields, one question each

Seal v6 fixes the record at sixteen fields: no optional fields, no seventeenth field, no minor versions. Refusals carry zeroes, not omissions, so every record has the same shape. Figure 1 groups the fields by the question they answer; the table below gives each one the question an auditor should put to it.

Figure 1

Sixteen fields, seven questions

Chainwhich chain, where in itF01tenant_idF02seqF03prev_digestWritewhich writeF04write_idF05write_typeRulesunder which rulesF06declaration_idF07declaration_versionF08policy_versionActorwho acted, how freelyF09actor_idF10actor_kindF11autonomy_levelRecordwhat changedF12record_idF13record_versionHasheswhat was said, in which wordsF14payload_hashF15lexicon_hashTimewhen, with its offsetF16recorded_atNot a fieldrendered beside itoutcome · approver’s name · refusal code · meter
Seal v6 has sixteen fields and no others. F03 prev_digest, marked, is what links a record to the one before it. The outcome, the approver’s name, the refusal code and the meter are shown beside the record, never inside it.
Each field, and what to ask of it
FieldNameWhat it holdsAsk
F01tenant_idThe tenant this record belongs to. Chains never cross tenants.Is every record in my population from the tenant under review?
F02seqThe record's position in this tenant's chain. It only ever goes up by one.Is the sequence unbroken from the first record to the last?
F03prev_digestThe digest of the record before this one. It is what links the chain.Does it equal the recomputed digest of the record before?
F04write_idThe identifier of the write intent. Every invoice line must carry one.Can I trace this write to its approval request and to the target?
F05write_typeThe kind of write, from the declaration's list of allowed write types.Is this a write type the declaration allows, at that version?
F06declaration_idThe declaration — the process's rules in seven blocks — that was checked.Which process’s rules applied?
F07declaration_versionWhich version of that declaration was in force at the time.Was this version of the declaration in force at F16?
F08policy_versionThe version of the policy rules evaluate() ran. No model, only rules.Which version of the rules did evaluate() run?
F09actor_idWho acted: the named approver, or the agent that proposed the write.Who acted? For a held write, is it the named approver?
F10actor_kindWhether the actor was a human or an agent.Was the actor a person or an agent, as the kernel set it?
F11autonomy_levelThe autonomy level A0–A5 the write ran at; above the ceiling a person decides.Did the autonomy level permit this actor to act alone?
F12record_idThe record in your system of record that changed, or would have.Which record in the system of record changed? Zeroed for a refusal.
F13record_versionThe version of that record after the write.Does the record’s version in the system of record match?
F14payload_hashA hash of the payload, not the payload itself, so personal data stays out of evidence.Does a hash of the payload, canonicalised as declared, match?
F15lexicon_hashA hash of the vocabulary the write was expressed in, so meanings cannot drift.Which vocabulary gave the write its meaning?
F16recorded_atWhen the record was sealed, with the time-zone offset.Is the time inside the period, in order, with its offset?

Three fields that matter most

F07 declaration_version and F08 policy_version let you replay a decision against the rules that were in force, rather than the rules as they are today. Ask for the declaration at that version; every version is retained, and changing a declaration is itself a governed write.

F11 autonomy_level, read with F10 actor_kind, tells you whether the actor was permitted to act alone. An agent at A1 or A2 cannot commit a write without a person; a committed record whose actor is an agent at those levels is an exception.

F14 payload_hash holds a hash of the payload, not the payload. Personal data stays in your system of record, under your retention and erasure rules. To test it, obtain the payload from the system of record and hash it in the canonical form the declaration’s proof_binding block specifies. The canonical form is declared per write type; the exact procedure comes with the verifier.

3. Walking the chain at L1

Each record’s digest is SHA-256 over a preimage: the 19-octet domain string elan1.proof.seal.v6, followed by the sixteen fields in order, each with its length in front. Length-prefixing means there is only one way to read the bytes, so two different records cannot serialise to the same preimage. In the site’s inspector each field is written as a 4-octet big-endian length and its UTF-8 bytes; the normative encoding is the one published with Seal v6.

Figure 2Illustrative specimen. Not customer data.

Walking the chain at L1

seq 1041F01 tnt_specimen_01F02 1041F03 058169bb…964023f8F04–F16 …refused · rung 3SHA-256( domain ‖ 16 fields )= 8e37839e…0ffdeac0seq 1042F01 tnt_specimen_01F02 1042F03 8e37839e…0ffdeac0F04–F16 …committed · rung 7SHA-256( domain ‖ 16 fields )= f2423aa3…5aca2c18seq 1043F01 tnt_specimen_01F02 1043F03 f2423aa3…5aca2c18F04–F16 not shownnext recordCheck 1 · digest of record n equals F03 prev_digest on record n + 1, octet for octet.Check 2 · F02 seq on record n + 1 is exactly one more than on record n, in the same tenant.Domain string: elan1.proof.seal.v6 (19 octets). Each field is length-prefixed.
Recompute each record’s digest from its sixteen fields and compare it with F03 on the next record; check that F02 rises by exactly one. A changed record breaks its link; a missing record leaves a gap. Digests shown are the real SHA-256 values of the specimen records in section 9.
  1. Build the preimage of record n

    The domain string, then the sixteen fields of record n in order, each length-prefixed.

    Check You have one byte string per record; field order follows F01 to F16.

  2. Hash it with SHA-256

    The result is record n’s digest.

    Check A 64-character hexadecimal digest.

  3. Compare with F03 on record n + 1

    The digest must equal F03 prev_digest on the next record, octet for octet.

    Check Identical. Any difference is an exception at that link.

  4. Check F02 on record n + 1

    seq must be exactly one more than on record n, in the same tenant (F01).

    Check No gap, no repeat, no reordering.

  5. Repeat across the population

    Walk the whole chain for the period, from the first record to the last.

    Check Every link holds and the sequence is unbroken.

What a break looks like

The kernel’s own conformance test C9 plants four faults — a flipped octet, a reordered pair, a duplicate and a gap — and requires each to be found. An auditor walking the chain sees the same four signatures:

Four faults, four signatures
FaultWhat you see
A field in a past record was changedThat record’s recomputed digest no longer equals F03 on the next record.
A record was removedF02 seq jumps by more than one, and F03 on the following record matches nothing you hold.
Two records were swappedseq runs out of order, and both affected links fail.
A record was duplicatedseq repeats; one of the two copies fails its link.

4. What L1 proves, and what it does not

A hash chain shows that something changed to anyone who holds an earlier digest. On its own, it does not stop a party with full control of the store from rewriting a stretch of history and recomputing every digest after it. If you have kept digests — in a prior-period working paper, an export, a report — you would see the break. That is the honest scope of L1: tamper-evident to you, the holder of the records.

Evidence rows cannot be updated or deleted, and the kernel is the single writer. Those design facts make tampering harder. They are not something a third party can check without elan1, which is why they are not the claim. At L1 you recompute the chain on records elan1 provides; the provenance of those records rests on elan1.

Verification at L1
ProvesDoes not prove
The record has not changed since it was sealed, relative to digests you holdThe business decision was right
Which rules and which version appliedThe rules were good
Who acted, and at what autonomy levelNothing happened outside elan1 (Mode B)
That a refusal happened, with its code and rungThe transaction itself was genuine
That no record is missing between two sequence numbersWho sealed the record, to someone who does not trust elan1 — that arrives from L2

5. What L2 adds

L2 Attested sits on the same write path, the same sixteen fields and the same packs. It adds exactly four things, so that someone who does not trust elan1 can check a record without us.

  • Signing. From L2, each record’s digest is signed with Ed25519, against the key of the residency domain it was written in — “in” for India.
  • Anchoring. Records are batched into Merkle roots, anchored to two independent RFC 3161 timestamp authorities, one of them in India, within 15 minutes. An anchor shows that a record existed, in that form, by that time. It is not a blockchain.
  • Verifier profiles. A profile binds a regime’s clauses to write types, gates and record fields, by name. Profiles are listed per pack; the ledger1 pack carries one for the MCA audit trail.
  • The evidence bundle. One folder, exportable for a period or a set of records, that needs nothing from elan1.
The evidence bundle, from L2 — file names from the bundle specification; illustrative, not customer data
MemberWhat it carries
manifest.jsonWhat the bundle contains and how it was produced.
seals.jsonlThe records, one per line.
chain.jsonThe chain structure the records belong to.
anchors/The timestamp-authority responses for each Merkle root.
keys.jsonThe public keys to check signatures against. Never private key material.
declarations/The declarations, at the versions the records name.
lexicon/The vocabularies the records’ F15 hashes refer to.
VERIFY.txtHow to run the check, in plain text.

The free offline verifier, elan1-verify --bundle <path> --profile <path>, has no dependencies, needs no network and no account, and is built so anyone can reproduce the build. It reports one of six results: PASS, FAIL_INTEGRITY, FAIL_PROFILE, INCOMPLETE, UNSUPPORTED or USAGE. You or your auditor can run it on an air-gapped machine, without us.

6. Sampling a period

Audit sampling usually starts with an act of faith: that the population you sample from is complete. The chain removes most of it. Because F02 rises by exactly one and every F03 links to the record before, you can show that no record is missing between the first and last sequence numbers of a period before you draw a sample (Figure 3).

Figure 3

Sampling a period of governed writes

01Fix the periodfirst and last seq,bounded by F16 recorded_at02Prove completenessno gap in F02 seq;every F03 link holds03Reconcilerecords ↔ system of recordrecords ↔ meter events04Stratifywrite type, outcome,autonomy, actor kind05Test each itemrules in force, approver,payload hash, target record06Concludeexceptions, Mode B scope,what L1 cannot show
The chain lets you prove the population is complete before you sample from it. That step, marked, is the one an ordinary application log cannot give you. Sample sizes follow your own methodology; nothing in the record changes that.

Establishing the population

Fix the period by F16 recorded_at, then take the first and last seq inside it. Walk the chain between them as in section 3. Then reconcile in both directions. The kernel itself reconciles meter events, proof records and the target system (conformance test C10); the auditor’s version of that test is simpler:

  • Records to the system of record. Every committed record should match a change in the target: F12 record_id at F13 record_version.
  • System of record to records. Every change to a governed record type in the target should have a committed record. In Mode A, a change with no record is a significant exception. In Mode B, it is expected to be possible, and is the main limit of the evidence (section 8).
  • Records to the meter. Committed records should equal governed actions on the invoice; each refusal appears as 0.4 of a governed action.

Stratifying

A useful stratification follows the fields: by F05 write_type, by outcome, by F11 autonomy level, and by F10 actor kind. Writes committed by agents acting alone (A3 to A5) and writes committed by a person after an escalation are different control populations and deserve separate samples. Include refusals and expiries in the frame; they are evidence too (section 7). How many items to select is a matter for your own methodology.

Testing a sampled item

  1. Obtain the declaration at F06/F07 and confirm it was in force at F16.
  2. Confirm F05 is on that declaration’s list of write types.
  3. Confirm F11 permitted the F10 actor kind to act as it did; for an approved write, confirm the approver was named in the declaration and was not the proposer. The approval request is linked by F04 write_id.
  4. Trace F12 and F13 to the system of record; recompute F14 from the payload there.
  5. For a refusal, confirm that no corresponding change exists in the target.

7. Refusals as evidence

A control that has never said no is hard to distinguish from a control that cannot. Refusals are how the record shows that a rule was applied, not only written. For that reason a refused write leaves the same sixteen-field record as a committed one, sealed into the same chain.

A refusal record is recognisable by its zeroes: F12 record_id is zeroed and F13 record_version is 0, because nothing changed. Beside the record, the rendering strip shows the refusal code from a closed register and the rung where the write stopped. The meter shows 0.4 of a governed action, always less than an allowed write, so a refusal never costs more than letting the same write through.

Refusals an auditor will meet
RefusalWhere it stopsWhat it shows
A pre-gate failsRung 3A declared check on your own data ran before anything was written. All nine gates still ran and recorded.
The rules refuseRung 4evaluate() applied the declared rules at the recorded policy version.
The blast radius is too largeRung 5The write asked to change more than its declared limit.
The approver refusesRung 6A named person who was not the asker saw the change and said no.
The approval expiresRung 6Nobody answered in time. Expiry is a refusal, never a quiet allow.
The sandbox disagreesRung 7The gates were run again on the sandbox result and failed.

Two points of reading. First, a write that is held for approval has no record yet; exactly one is sealed when it resolves — committed, refused or expired. A period-end cut-off may therefore show writes that are still pending; ask for the held queue at the cut-off date. Second, refusal codes shown on this site, such as GATE.PRECONDITION_FAILED, are illustrative; the closed register is part of KernelPort v1 and is shared with customers.

8. Mode A and Mode B: what the evidence covers

The mode decides the coverage of the evidence, and it is the first thing to establish for any system under review.

In Mode A, elan1 holds the write credential through a single writer with a single-use credential that lasts 10 minutes. No write reaches the system of record without a gate decision and a proof record. Only in Mode A do we say “enforced”. A change to a governed record type with no matching record is therefore a significant finding: it means a write took a path the architecture says does not exist.

In Mode B, elan1 is reached over MCP or HTTP and does not hold the credential. Every write intent the caller sends is evaluated and recorded, and the caller makes the write itself. A Mode B record shows what elan1 was asked and what it decided. It cannot show that the caller asked every time, or that it honoured a refusal.

Ask the system owner which consumers connect in which mode. Hosted elan1 Work on ERPNext runs in Mode A. elan1 Work Attach, elan1 Decide and elan1 Run tooling run in Mode B. Third-party agents run in Mode B, or Mode A by agreement after conformance tests C1–C14 pass.

9. A worked review of two illustrative records

Two consecutive records, all sixteen fields
FieldRecord 1041Record 1042
F01 tenant_idtnt_specimen_01tnt_specimen_01
F02 seq10411042
F03 prev_digestsha256:058169bb8da3e9f6b1b8511193b43b0636ffe1ecc6e4c46ce8a8a905964023f8sha256:8e37839e9548dfa9a4a8948b723c1517afb532a7eaceb617a7db6eff0ffdeac0
F04 write_idwr_specimen_7c1wr_specimen_7c2
F05 write_typepurchase_invoice.postjournal_entry.post
F06 declaration_iddecl_ap_purchasedecl_month_end_close
F07 declaration_version47
F08 policy_version2027.06.12027.06.1
F09 actor_idagt_specimen_ap01usr_specimen_approver
F10 actor_kindagenthuman
F11 autonomy_levelA1A2
F12 record_id00000000-0000-0000-0000-000000000000je_specimen_5531
F13 record_version02
F14 payload_hashsha256:5f105d2d818bc7fe36a7c1b7e367196610df5ee6e8d4c5296c9d8cc4b28428d8sha256:e1eb0d8f0a7399695abf290e8fd2b6abc738ffd2fbdb8297f9ae44eb1a32ab6a
F15 lexicon_hashsha256:1d967c9d1c583efd0a3135e57aa1035ebdd5ab4766f0572f10304feae7516d53sha256:fd8e4d0b12b24bf22a591e735f211d8d7bb2bdf480058fdf89bb9d44666b2633
F16 recorded_at2027-07-14T10:39:12+05:302027-07-14T10:42:07+05:30

Reading record 1041: a refusal

An agent, agt_specimen_ap01 at autonomy A1, proposed purchase_invoice.post under declaration decl_ap_purchase version 4 and policy 2027.06.1. F12 is zeroed and F13 is 0: nothing changed. The rendering strip shows the outcome “refused at rung 3” with the illustrative code GATE.PRECONDITION_FAILED from G9, and 0.4 of a governed action on the meter. No approver is shown, because the write stopped before approval.

Tests: confirm declaration 4 was in force at 10:39:12 +05:30; confirm no purchase invoice was posted for wr_specimen_7c1; note the refusal in the population of refusals.

Reading record 1042: an approved commit

A person, usr_specimen_approver, committed journal entry je_specimen_5531 at version 2 under decl_month_end_close version 7, at autonomy A2 — where a person approves before the write. The record was sealed at 10:42:07 +05:30, after record 1041, as seq order requires.

Tests: confirm the approver is named in declaration 7 and, through F04 wr_specimen_7c2, that the approval request’s proposer was someone else; trace je_specimen_5531 version 2 in the ledger; recompute F14 from the posted entry.

Walking the link

Record 1041 recomputes to sha256:8e37839e…0ffdeac0. F03 on record 1042 holds the same value in full, and F02 rises from 1041 to 1042. The link holds. Record 1042 recomputes to sha256:f2423aa3…5aca2c18, which is what record 1043 carries in F03.

Results for the two-record specimen
Test10411042
Tenant matches population (F01)PassPass
Sequence continuous (F02)PassPass
Link to previous record (F03)Outside samplePass
Write type allowed at declaration version (F05–F07)To obtain declaration v4To obtain declaration v7
Actor and autonomy consistent (F09–F11)Pass: agent at A1 did not commitPass: person at A2 committed
Target record traced (F12–F13)Pass: nothing to traceTo trace in ledger
Payload hash recomputed (F14)Not applicableTo recompute from ledger

The review raises no exception on what the records alone can show, and leaves four items that need evidence from outside the record: two declarations, one ledger entry and one payload. That is the normal shape of a proof-record review. The record tells you exactly what to ask for; it does not replace asking.

10. An auditor’s checklist

A checklist for one period of governed writes in one tenant. It assumes L1; items marked “from L2” apply once L2 Attested is available.

Checklist for a period of governed writes
#CheckEvidence
1Establish the mode of every consumer that writes to the systems in scope.Consumer list; Mode A or Mode B for each
2Fix the period and its first and last seq.Export of records for the period
3Walk the chain: every digest equals the next F03; seq has no gap.Recompute; your own record of last period’s closing digest
4Reconcile records to the system of record, both ways.Change log of governed record types
5Reconcile committed records to governed actions on the meter; refusals at 0.4 each.Meter statement
6Obtain every declaration version the sample names, and confirm each was in force.Declaration history
7Test approver separation: no approval by the proposer or by an agent.Approval requests linked by write_id
8Test autonomy: no agent committed alone below its permitted level.F10 and F11 on committed records
9Sample refusals and expiries; confirm nothing changed in the target.Refusal records; target change log
10Ask for writes held at the cut-off.Held queue at period end
11Record the closing seq and digest in your working papers.Your own anchor for next period
12From L2: run the offline verifier on the bundle with the relevant profile.Verifier output: PASS or the failure code

Readers who want a vendor-neutral version of these questions, to put to any supplier whose agents write to their records, will find it in the RFP question set.

References

Every reference is a page on this site. Where a page and this paper differ, the page is newer: tell us and we will correct the paper.

  1. [1]The proof record/platform/proof-recordThe sixteen fields, the chain and the in-browser inspector used in section 9.
  2. [2]Verify a proof record/trust/verifyWhat you can check at L1, and the five L2 steps.
  3. [3]Specimens/resources/specimensAn allowed write, a refused write and a write held for approval, field by field.
  4. [4]Specimen: a refused write/resources/specimens/refused-write
  5. [5]Specimen: a write held for approval/resources/specimens/held-for-approval
  6. [6]Assurance levels and modes/platform/assurance-levelsL1, L2 and L3, in Mode A and Mode B.
  7. [7]L1 Guarded on elan1 Govern/platform/govern/l1
  8. [8]L2 Attested on elan1 Govern/platform/govern/l2Signing, anchoring, verifier profiles and the bundle.
  9. [9]Field note: What tamper-evident means at L1/blog/what-tamper-evident-means-at-l1
  10. [10]Field note: Designing the 16-field proof record/blog/designing-the-16-field-proof-record
  11. [11]Field note: Why a refusal costs 40% of a governed action/blog/why-refusals-are-free
  12. [12]The governed write path: an architecture paper/resources/library/write-path-architectureThe companion paper on how the record is produced.
  13. [13]What we claim, and what we don’t/trust/claims
  14. [14]Glossary/resources/glossaryProof record, seal, refusal, autonomy level and related terms.

About this document

Evidence for auditors: reading an elan1 proof record. v1.0. Published by ELAN1 AGENTIC TECHNOLOGIES PRIVATE LIMITED in the elan1 Library. Written by the author, checked for technical truth by the product owner, and reviewed by counsel wherever it touches regulation or pricing.

Words we use, and words we don't

At L1 the record is tamper-evident to you. “Signed” and “checkable offline” apply from L2. “Enforced” applies only in Mode A. L3 is reached when an outside auditor accepts an L2 bundle in writing. The full register is at What we claim, and what we don't.

Corrections

If something here is wrong or out of date, tell us. Corrections are made in the next version and noted on this page.

// TALK IT THROUGH

Want to go through it with us?

Design partners and their auditors can walk through any paper with the people who wrote it.