Skip to main content

agentledger

tests

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.2.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.2-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: phb_agentledger-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 4ded6bbddfec50665931d0c2daa55443ba067501550de3f6cd535d410fdbe814
MD5 40389986663af2118c51751bf43b9f61
BLAKE2b-256 4d0f919f45f67b5f02f4ce7a82a256a4e3eb25282e45280f66ef07b0c3138415

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for phb_agentledger-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0f61eb2e9ac37e6a992ca70f26e13d94fdfe5aa7f8d7fcfbb2c609a823e742d6
MD5 0b12501fe75d434a489c77ca374d81ac
BLAKE2b-256 2a4b6bcfee499ca1de88653a1020f71618679059a63fbcf224ab1ec397cb7b5f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

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