# A Verified Agent Execution Record: One Sealed Sequence, Checked Offline

> Markdown mirror for AI agents, generated 2026-08-13 from the live page.
> Canonical: https://agenticrail.nz/proof/
> Site context: https://agenticrail.nz/llms.txt

# A verified agent execution record, in full

One sealed sequence. Five steps, one of them refused. Every signature and every signed byte published here, so you can check it yourself without an account.

Most claims about agent audit trails are descriptions of a mechanism. This is the artefact. Below is a complete enforcement record for a real sequence, exactly as the verifier returns it, with enough published alongside it that a stranger can confirm the signatures offline and needs to trust neither the operator nor us.

The sequence

`demo-mcp-payment-workflow-001` — sealed 6 August 2026. It was produced by a third party calling the public MCP server, not written by us to look good. It needs no key: the report below is open to anyone.

## What happened

An agent working a payment flow attempted to execute the transfer as its **first** action, before identity had been verified or risk assessed. The gate refused it. Nearly three minutes later the agent returned and ran the steps in order, and the transfer was permitted.

| # | Step | Decision | Time (UTC) |
| 0 | `execute_transfer` | **DENY** — `SEQUENCE_VIOLATION`

"Step submitted out of order" | 23:21:38 |
| 1 | `verify_identity` | ALLOW | 23:24:34 |
| 2 | `assess_risk` | ALLOW | 23:24:44 |
| 3 | `execute_transfer` | ALLOW | 23:24:50 |
| 4 | `audit_ledger` | ALLOW — `sealed: true` | 23:24:55 |

Elapsed from first decision to last: 196.742 seconds. The two-minute-fifty-six gap between the refusal and the retry is the agent responding to the denial.

## The step that did not run

This is the part an ordinary audit log cannot produce. Step 0 was **refused before it executed**, and a signed record of that refusal exists.

A log records what happened. A step that never ran leaves no entry, and absence leaves no trace — so a log has nothing to say about the payment that was attempted out of order. Here the attempt is in the record, signed, with the reason, and it is as verifiable as any of the permitted steps.

The signed bytes for that receipt carry `"decision":"DENY"` and `"executed":false`. The permitted steps carry `"executed":true`. In this schema `executed` means the step was *permitted*, not that its downstream work succeeded — see the limits at the end.

## How the chain holds

Each receipt commits to the exact bytes of the receipt before it, so altering an earlier record changes a hash and is detectable here.

| # | Step | Signature | Chain link |
| 0 | `execute_transfer` | valid | chain start — no prior receipt |
| 1 | `verify_identity` | valid | no prior ALLOW to anchor to — null-anchored |
| 2 | `assess_risk` | valid | links to `4732664cc6510c6e…`, hash-links to `6c7a712da7482378…` |
| 3 | `execute_transfer` | valid | links to `a088783b7876f2b3…`, hash-links to `567b87bcb771279d…` |
| 4 | `audit_ledger` | valid | links to `f5f2ac28deba573d…`, hash-links to `99515775926501e5…` |

Read the hash-chain count carefully

The verifier reports **3 verified, 0 broken, 2 not verifiable**. The two that are not verifiable are receipts 0 and 1, and that is correct rather than a gap: the chain anchors to the last *permitted* receipt, so nothing before the first ALLOW has a predecessor to hash against. A null anchor is legitimate exactly when no ALLOW precedes it. Reading "2 not verifiable" as two unchecked receipts is the misreading this note exists to prevent — their signatures are valid, they simply have nothing behind them.

## One receipt, complete

Receipt 0, the refusal. These are the exact bytes the signature was computed over — 603 bytes of UTF-8, keys sorted, no whitespace variation.

**signed_canonical**

`{"attestation":null,"decision":"DENY","executed":false,"key_id":"k2_2026-06-07_ed25519","meta":{"action_type":"CHECK_STATE","function":"execute_transfer","model_id":"client:demo","policy_map_ids":[],"sequence_id":"demo-mcp-payment-workflow-001","step":"execute_transfer"},"pack_id":"80d4a564ada10a11d759b557391f125334749aebb867d2e9eb71ea79f305dbf2","payload_hash":"21bfad36b9b646a8cc82ccf2c389f587cee0fb1b8819254b8b9633cab5b2c4de","prev_receipt_hash":null,"prev_receipt_id":null,"reasons":["SEQUENCE_VIOLATION"],"sealed":false,"signature_alg":"Ed25519","ts_ms":1786058498833,"version":"slp8_receipt_v2"}`

**signature** (Ed25519, base64)

`TcYRiuYF95py78A/cS7vULbxIN7h+AKfMuDD5LSoRX+3w4fdFUJ/lB03JSWASGwZ4zvwnhGNPEF7VJRSSubAAA==`

**public key** — `k2_2026-06-07_ed25519`, SPKI, base64. Published inline here on purpose, so verification needs no fetch of any kind.

`MCowBQYDK2VwAyEA1ejM0xb/nkaPO8NhNWtXHOpqR1BgYqAOLWqig02FZdI=`

## Verify it yourself, offline

The whole check is one line of intent: `ed25519_verify(public_key[key_id], utf8_bytes(signed_canonical), base64_decode(signature))`. Nothing below touches the network.

**Python** — `pip install cryptography`

```
import base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

SPKI_B64 = "MCowBQYDK2VwAyEA1ejM0xb/nkaPO8NhNWtXHOpqR1BgYqAOLWqig02FZdI="
SIGNATURE = "TcYRiuYF95py78A/cS7vULbxIN7h+AKfMuDD5LSoRX+3w4fdFUJ/lB03JSWASGwZ4zvwnhGNPEF7VJRSSubAAA=="
CANONICAL = r'''PASTE THE signed_canonical LINE ABOVE, EXACTLY'''

raw_pub = base64.b64decode(SPKI_B64)[-32:] # last 32 bytes of the DER are the key
Ed25519PublicKey.from_public_bytes(raw_pub).verify(
 base64.b64decode(SIGNATURE), CANONICAL.encode("utf-8"))
print("signature valid")
```

**JavaScript** — WebCrypto, no dependencies

```
const b64 = s => Uint8Array.from(atob(s), c => c.charCodeAt(0));

const key = await crypto.subtle.importKey(
 "spki", b64("MCowBQYDK2VwAyEA1ejM0xb/nkaPO8NhNWtXHOpqR1BgYqAOLWqig02FZdI="),
 { name: "Ed25519" }, false, ["verify"]);

const ok = await crypto.subtle.verify("Ed25519", key,
 b64("TcYRiuYF95py78A/cS7vULbxIN7h+AKfMuDD5LSoRX+3w4fdFUJ/lB03JSWASGwZ4zvwnhGNPEF7VJRSSubAAA=="),
 new TextEncoder().encode(CANONICAL));

console.log(ok ? "signature valid" : "signature INVALID");
```

Change one character of the canonical string and it fails. That is the whole property.

## The verifier's own verdict

| Field | Value |
| verification_status | **VERIFIED_INTACT** |
| seal_status | **SEALED** — no further step can be added |
| signatures | 5 valid · 0 invalid · 5 third-party verifiable |
| hash chain | 3 verified · 0 broken · 2 not verifiable (see the note above) |
| independent archive | **match** — copy received 2026-08-06T23:24:56.79Z |

That last row is a separately credentialled write-once store holding its own copy of each sealed receipt. It is compared at every verification, which is what makes a wholesale rewrite by a key holder detectable rather than silent.

## What this establishes, and what it does not

- **It establishes the order.** Which steps were permitted, in what sequence, and that the record has not changed since it was written.
- **It does not establish that permitted work succeeded.** An ALLOW means the step was permitted. The executor's outcome is reported separately and is not signed into the receipt.
- **Timestamps are asserted, not attested.** `ts_ms` is generated by AgenticRail and covered by the signature, so it cannot be altered afterwards without breaking verification. That is a record of when, not proof of when.
- **AgenticRail holds the signing keys.** The gate is independent of the agent, which can neither instruct it nor edit its output. It is not independent of us. The archive comparison above is what narrows that gap; it does not erase it.
- **Offline-verifiability is per-receipt.** Every receipt here is Ed25519 with `third_party_verifiable: true`. Legacy HMAC receipts elsewhere are confirmed server-side only. Check the field; do not assume it holds for a whole chain.

## Now do it with your own

The same report is generated on demand for any sequence. The [browser demo](https://agenticrail.nz/demo/) runs a real sequence against the live gate on the public demonstration key, then opens the signed report for that run in one click — keyless, nothing to copy. The [documentation](https://agenticrail.nz/docs/) has the same thing as a copy-paste request if you would rather use a terminal, and the [verifier](https://report.agenticrail.nz/report) takes a sequence identifier directly if you already have one.

Anything placed in `attestation` on a demonstration sequence is world-readable, because its report needs no key. Treat the demo lane accordingly.

[What AgenticRail is, and what it is used for](https://agenticrail.nz/product/) — the enforcement gate that produced this record.

[The Completeness Specification](https://agenticrail.nz/spec/completeness/) — the eight requirements that separate an evidence-grade record from an ordinary log, and the criteria an auditor tests against.

[The Enforcement Specification](https://agenticrail.nz/spec/) — decision architecture, receipt fields, signing and the sealed chain.

[Tamper-evident, and the two words that overstate it](https://agenticrail.nz/blog/ai-agent-audit-log-best-practices/) — of the three terms in common use for audit-log integrity, only one describes something achievable.

He toi whakairo, he mana tangata
