Skip to main content

agentledger

A tamper-evident, hash-chained audit ledger for AI agent actions.

Source · PyPI · Commercial licence

When an AI system does something consequential — calls a tool, spends money, escalates to a person, refuses a request — you need a record that still means something six months later, when someone asks what happened and why. An application log does not survive that question: anyone with file access can edit it, and nothing in the file says whether they did.

agentledger writes each action as a validated, content-addressed record in a SHA-256 hash chain. Editing any stored record, in any field, breaks the chain, and verify_chain() says so.

Install

pip install phb-agentledger

Installed as phb-agentledger, imported as agentledger. One runtime dependency (filelock). Python 3.10+.

Sixty seconds

from agentledger import AuditLedger, make_event

ledger = AuditLedger(path="audit.jsonl")

ledger.append_event(make_event(
    "TOOL_CALL", "ACME-AGENT-001",
    summary="looked up order 1234",
    subject_refs=["order:1234"],
))
ledger.append_event(make_event(
    "POLICY_DECISION", "ACME-GATE-001",
    summary="refund above the auto-approve limit: escalated to a human",
    subject_refs=["order:1234"],
))

ledger.verify_chain()                        # True
ledger.query(subject_refs=["order:1234"])    # an AuditTrace of both events

Run python demo.py to see the same thing end to end, including a hand-edit of the stored file and the chain check catching it.

What it guarantees

  • Order is assigned by the ledger, never by the caller. Sequence numbers and chain hashes are computed on append. A producer cannot claim a position in history.
  • Every record carries its own digest, SHA-256 over JCS-1 canonical JSON with the digest field omitted. A record that does not match its own content is rejected before it is stored.
  • Appends are idempotent on (record_id, event_id). Resubmitting the same record is a no-op; resubmitting different content under the same key is a rejected conflict, not a silent overwrite.
  • Queries never overclaim. A result is explicitly scoped to a ledger cut, so "no matches in this view" is never returned as "this never happened".
  • Concurrent writers are safe. The load → mint → append critical section is held under a cross-process file lock, and a torn tail from a killed process is quarantined rather than silently truncating history.
  • Two refusals are enforced in code, not documentation. The ledger will not store records classified as raw internal model reasoning, and it rejects any event that asserts externally-verified truth without evidence lineage.

What it deliberately does not do

  • It does not verify payloads it never saw. payload_digest is your assertion about content held elsewhere; the ledger stores and chains it, but cannot confirm it.
  • It is not a signing system. Records are tamper-evident against edits to the stored file. They are not signed, so a party who can rewrite the whole file, including recomputing the chain, is out of scope. Signing is the next layer, not this one.
  • It does not make you compliant with anything. It gives you a defensible record. Whether that record satisfies a given regulation is a question for your counsel.
  • SCHEMA_HASH_CATALOG ships with a placeholder hash for AuditEvent 1.0.0 rather than the digest of the shipped schema file. Set it from your deployed schemas at boot if you want that check to be meaningful.

Event shape

make_event() fills the 22-field envelope for you and computes both digests. The fields you supply are the ones that carry meaning:

Argument Meaning
event_type What happened, as a SCREAMING_SNAKE label you choose
actor Who did it, as VENDOR-COMPONENT-NNN (e.g. ACME-AGENT-001)
summary or payload_ref A short line, or a pointer to the payload held elsewhere
subject_refs What it was about (order:1234, user:42)
data_classification Sensitivity label; drives the refusals above
truth_refs Evidence lineage, required for external-truth claims

Hand-built dicts are still accepted — make_event is a convenience, not a bypass. validate_audit_event() judges both the same way.

Tests

pip install -e ".[dev]"
python -m pytest tests -q

43 tests, no network, under a second.

Licence

Source-available. Free for personal, educational, and evaluation use; commercial use requires a paid licence. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phb_agentledger-0.1.1.tar.gz (29.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

phb_agentledger-0.1.1-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file phb_agentledger-0.1.1.tar.gz.

File metadata

  • Download URL: phb_agentledger-0.1.1.tar.gz
  • Upload date:
  • Size: 29.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for phb_agentledger-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bca05348b23271763bff13f2071387ba62c302989c779812fc6a9f5e8edffdbd
MD5 1475c3e1bc05031ec809da13b1b5db26
BLAKE2b-256 86a244507d35953071122297ccb1043dccf48b9e0125f73dc8595a7183949d7b

See more details on using hashes here.

File details

Details for the file phb_agentledger-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for phb_agentledger-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6160c735d0d215f5d8f2836f51dc0224f72ab7627489b54cc59c2446566c2fcf
MD5 d7d7a95641f2563a7724da89094c1558
BLAKE2b-256 afc170da9755776cf2b950c091e892087678179bd1f0ee551d1c59ca14183e06

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page