Bellbookv0.11

Rust · append-only · content-addressed

A tamper-evident, replay-verifiable record of captured agent activity.

An embeddable Rust library with one primitive: a typed Record in an append-only, hash-chained log. Write down what was requested, done, approved, and refused. It also records the candidate source states an agent proposes, the evaluations that judge them, and the selections between them, so a chosen line of work carries verifiable lineage. Nothing can be altered after the fact without breaking the chain, and anyone can replay the whole log to prove it.

cargo add bellbook

What it does not claim

Consistency, not completeness.

Bellbook proves captured history is intact, rule-conforming, and honestly graded. Whether everything the agent did was captured depends on how the host instruments its runtime.

Integrity, not confidentiality.

Records and receipts carry full payloads in the clear. A receipt inherits the sensitivity of everything committed, so never put credentials in records and treat sharing a receipt as disclosure.

Tamper-evident, not tamper-proof.

Replay detects any edit to committed history, but the log’s owner can replace it wholesale from genesis. Key-pinned signatures and an external head attestation anchor against that.

How it works

Content-addressed

A record’s id is the SHA-256 of its RFC 8785 canonical form. Records reference earlier records by that hash, forming a DAG. Any edit breaks every id and reference that depends on it.

Every record is judged

Committing runs a deterministic verifier and appends an Accept or Reject verdict. Rejected records stay in the log, so it records what was attempted, not only what was allowed.

The whole log replays

verify_log walks from genesis, recomputes every id, enforces gap-free logical time, and re-derives every verdict to compare with what is stored. A forged verdict is caught, not trusted.

Governance in-band

Capabilities, approvals, refusals, and expiries are records too. “Was this action allowed at the time?” is answered by the log itself. Pin an actor’s keys and it cannot author its own approval.

Portable receipts

bellbook export bundles a log into a self-contained receipt, and anyone verifies it offline with bellbook validate: ids, chain, every verdict re-derived, signatures, evidence, taint. The whole record to receipt to check loop runs from the CLI, no Rust required.

The record answers questions

Seven named, deterministic queries - descent, descendants, siblings, frontier, standing, evidence, selected - answer “why did this win” and “what does this line rest on” from the log itself, over a live log or a receipt, in Rust, Python, or bellbook query. Only over verified history, nothing ranked, nothing silently filtered.

Comparable across organizations

A Clean receipt is Clean under its own rules. bellbook-core-v1 is the baseline two parties name so their receipts compare: six clauses over the rule shape, content-addressed and published with vectors. A receipt can declare the profiles it claims, and every validator re-checks the claim unasked, reporting whether the declaration names the table it applied. A report alongside the verdict, never a change to it.

Binds what was required to what was judged

A Requirement is an addressable statement of what a request requires, with provenance bound to who wrote it. Candidates bind the exact artifacts they produced; an evaluation names who decided, with what procedure, over what input, which artifacts it judged, and which requirements it speaks to. Outcomes are fail-closed: blocked, insufficient, stale, or not run are recorded as exactly that, never as a pass. Retract a requirement and every judgment against it is tainted.

Says when work was delivered, and proves it

delivery-receipt-v1 reads a delivery claim off the record: an accepted selection whose evaluations bind to the requirements of one request. Eight fail-closed clauses check that every required requirement was judged passed by an evaluator distinct from the producer, over evidence the record itself carries, with the procedure and input named. A claim over a check that failed, or a passing check reattached to another candidate, validates as honest history and is rejected as a delivery. The skeptic needs nothing but the receipt.

Binds every claim to a key

bellbook-core-signed-v1 is the tier above the baseline for parties who do not share a trust boundary. Every candidate, evaluation, selection, retraction, and requirement carries an Ed25519 signature; every author of one is pinned to a public key in the rules; every evaluation a selection rests on is attested under that key. A record without its signature, or signed with a key the rules do not pin for its author, is rejected on replay, not trusted. The same receipt, with signatures and one schema switch; no payload changes shape. What 1.0 will promise about all of this is written down in STABILITY.md.

Records how software evolves

Candidate, Evaluation, and Selection records track how work evolves. When an evaluation is retracted - a benchmark found broken - replay marks every candidate that rested on it compromised, at any depth; one reaffirming selection on surviving evidence restores the line, with the whole episode permanently on the record.

Where it fits

Identity

Systems that establish who an agent is and what access it holds.

Policy

Engines that decide whether an action may execute.

Evidence

Bellbook preserves what happened, as a portable receipt another party can verify independently.

An evidence layer. Not a logger, not a database, not a runtime.

Get started

cargo add bellbook          # Rust
pip install bellbook        # Python, same core, prebuilt wheels

# start a rules file, record what was required and what was judged
bellbook rules init --author human:user --author agent:provider --out rules.json
bellbook request add --log ./mylog --rules rules.json --author human --objective "ship"
bellbook requirement add --log ./mylog --rules rules.json --author human \
    --request REQ --key R1 --description "unit tests pass"
bellbook eval add --log ./mylog --rules rules.json --author agent --candidate CAND \
    --criterion unit-tests --passed --evaluator harness --basis recomputed --requirement R1_ID

# or start signed: pin each actor's Ed25519 key, then --sign-key FILE on every record
bellbook rules init --author human:user --author agent:provider --signed \
    --author-key human:$(bellbook key public --secret human.hex) --out rules.json

# bundle the log into a receipt that declares the profiles it claims
bellbook export --log ./mylog --rules rules.json \
    --profile bellbook-core-v1 delivery-receipt-v1 bellbook-core-signed-v1 --out receipt.json

# validate a receipt offline, no Rust knowledge needed; declared profiles are checked unasked
# exit 0 clean · 1 invalid · 2 valid-but-tainted · 3 profile not met
bellbook validate receipt.json

# ask the record: what won, on what evidence, what is still open
bellbook query selected "best-of-n" --receipt receipt.json
bellbook query frontier --receipt receipt.json