Skip to main content

bellbook (Python)

Python bindings for Bellbook: validate tamper-evident, replay-verifiable records of agent activity offline, from Python.

This is a thin PyO3 wrapper over the Rust bellbook crate, which stays the single source of truth for canonicalization, verification, and the conformance vectors. It is not a reimplementation. (The independent from-scratch validator under conformance/python/ in the repository is a separate thing: a deliberate second implementation that exists to cross-check the specification.)

Status

Validation, reading, and writing (issue #13).

Validate

validate(bytes) -> Report reaches the same Clean / Tainted / Invalid decision as the bellbook validate CLI, over the same core.

import bellbook

report = bellbook.validate(open("receipt.json", "rb").read())

print(report.status)          # "clean" | "tainted" | "invalid"
print(report.spec_version)    # "0.3"
print(report.record_count)
print(report.head_hash)       # lowercase hex; compare against an anchored head
print(report.rules_hash)      # compare against rules you trust
print(report.retracted, report.tainted)
print(report.standing)        # {"compromised": [...], "unsound": [...], "restorations": {...}}
print(report)                 # the full human-readable report (same as the CLI)

Validation never raises for a bad receipt: an unparseable or failing receipt returns a Report with status == "invalid" and a problem or reason set. As with the CLI, Clean is relative to the rules embedded in the receipt - compare rules_hash against a rule set you trust.

Read

read(bytes) -> Receipt parses a receipt for inspection. Reading does not verify - call validate for the decision.

import json

receipt = bellbook.read(open("receipt.json", "rb").read())

print(receipt.spec_version, len(receipt))
for r in receipt.records:
    print(r.kind, r.time, r.author_id, r.author_type, r.evidence)
    for ref in r.refs:
        print("  ", ref["type"], "->", ref["target"])
    payload = json.loads(r.payload_json)

A Record exposes id, kind, time, author_id, author_type, signed, evidence, schema, refs, and payload_json. The enum-valued fields (kind, author_type, evidence, and each ref's type) are the record's Rust variant names, e.g. "Candidate", "Provider", "Reported", "Use". read raises ValueError on bytes that are not a parseable receipt.

Write

Writer(log_dir, rules) records evolution to a persistent, single-writer log. It holds the same exclusive lock and runs the same replay-on-commit the Rust LogWriter does. rules is a JSON string: the verifier rules the log is committed under, the same object a receipt embeds under rules.

default_rules(authors, max_context=200) builds that string for you - the Python counterpart to bellbook rules init - so you never hand-author a rules object. authors maps an actor id to a role (user, provider, system, executor, or verifier, case-insensitive):

import bellbook

rules_json = bellbook.default_rules({"agent": "provider", "evaluator": "provider"})
w = bellbook.Writer("./mylog", rules_json)

c0 = w.candidate(author="agent", git_tree="a1b2...")            # a Root candidate
e0 = w.evaluate(author="agent", candidate=c0.id, criterion="builds", passed=True)
s0 = w.select(author="agent", objective="ship it",
              consider=[c0.id], choose=[c0.id], uses_eval=[e0.id])

print(c0.id, c0.accepted, c0.reason)   # each commit returns a Commit

# Export and verify in the same process:
report = bellbook.validate(w.receipt())
assert report.status == "clean"

Each of candidate, evaluate, and select commits one record and returns a Commit (id, accepted, result, reason). A record is durably committed whether accepted or rejected - a rejected record is evidence a proposal was refused - so accepted may be False without an exception. Statically-knowable payload violations (an unregistered author, a score scale above 12, an upgrade whose tree differs from its target) raise ValueError before anything is written.

  • candidate(author, git_tree, *, git_commit=None, algo="sha1", note=None, continues=None, parent=None, derives_from=None, upgrades=None, manifest=None)
    • basis is exactly one of continues (with parent), derives_from, or upgrades; omit all three for a Root. manifest (a directory path) binds the source by a canonical manifest hash instead of a reported tree.
  • evaluate(author, candidate, criterion, *, passed=False, failed=False, score=None, scale=None, procedure=None, uses=None) - exactly one of passed, failed, or a score (with scale, a decimal exponent 0-12).
  • select(author, objective, consider, *, choose=None, uses_eval=None, none=False, replaces=None, rationale=None) - exactly one of choose (with uses_eval) or none=True; replaces reaffirms a prior selection.

The writer is deliberately single-writer (SPEC 5.1): it holds an exclusive lock for the log directory, so a second Writer on the same directory raises. Other useful members: w.head (current head, hex), w.records (the committed records, as Records), len(w), and w.receipt() (portable receipt bytes).

Build from source

pip install maturin
maturin develop            # build and install into the current venv
pytest bindings/python/tests

Prebuilt wheels (Linux, macOS, Windows) are published to PyPI, so pip install bellbook needs no Rust toolchain; the steps above are for local development against the working tree.

Licensed under MIT OR Apache-2.0.

Download files

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

Source Distribution

bellbook-0.4.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distributions

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

bellbook-0.4.0-cp39-abi3-win_amd64.whl (709.6 kB view details)

Uploaded CPython 3.9+Windows x86-64

bellbook-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (885.6 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

bellbook-0.4.0-cp39-abi3-macosx_11_0_arm64.whl (783.3 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file bellbook-0.4.0.tar.gz.

File metadata

  • Download URL: bellbook-0.4.0.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bellbook-0.4.0.tar.gz
Algorithm Hash digest
SHA256 579e2a6c48bb529f6ddce64545cc2bd9819f0328d8b03687999dd7a3d0903b7a
MD5 e6ff0e312b85725264087a669e20f07c
BLAKE2b-256 9da7940298f046e1db479c1ea64e13fa276932e8cdadaabe2e84983a47cda842

See more details on using hashes here.

Provenance

The following attestation bundles were made for bellbook-0.4.0.tar.gz:

Publisher: publish-pypi.yml on bellbook-ai/bellbook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bellbook-0.4.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: bellbook-0.4.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 709.6 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bellbook-0.4.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7690bb574f2a8514438b8820d6fa6f36526c71ce03b9e8cf302f94817bb69938
MD5 56aef4b998b7d6b761193c3884d44eb3
BLAKE2b-256 9398b1fd4cd192a1d1247f88e29401feb45cfb92d34cc88a660fafdda2a2d2c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for bellbook-0.4.0-cp39-abi3-win_amd64.whl:

Publisher: publish-pypi.yml on bellbook-ai/bellbook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bellbook-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for bellbook-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bc78b0ae232afc7850099de656ee9072169a06fd88cd7810fe9d4047a468a730
MD5 3a657aa700c3a2548d56b1fbf3164ca1
BLAKE2b-256 602ad1f111c2cc7c5a5e5ed042851b8b2be858bb6db564a4d3ea894709beecbb

See more details on using hashes here.

Provenance

The following attestation bundles were made for bellbook-0.4.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on bellbook-ai/bellbook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bellbook-0.4.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bellbook-0.4.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a561f14de392c7f1850166c15a4a8ed7066a517cd3c76f3c48af80161bcfe00d
MD5 b60de4bbf785d2de4f07d9c791d77e4a
BLAKE2b-256 a0e3314a8be666c850fb8d19009ef9885a3049533b735c30c1e1b2f460739f78

See more details on using hashes here.

Provenance

The following attestation bundles were made for bellbook-0.4.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on bellbook-ai/bellbook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page