Bellbook 0.8.0 is out. It is the first change to the wire format since 0.3, and it adds three things a receipt could not say before.

What a receipt could not say

A Bellbook receipt is a replayable record of how work evolved: candidates, the evaluations that judged them, the selections that chose among them, and the retractions and taint that follow when a judgment turns out to be wrong. Since 0.3 a receipt could prove that this history is internally consistent under the rules it was committed under. Since 0.7 it could be compared across organizations under a shared baseline.

It still could not say what the work was for. There was no record of what was required. An evaluation named a criterion and an outcome, but not the exact artifact it judged, not who decided, not how. And a receipt could not carry the claim “this conforms to the baseline” in a form a validator would check rather than take on faith.

Each of those gaps is a place where a delivery claim leaks. “The tests passed” is a claim about a requirement nobody wrote down, an artifact nobody bound, and a decider nobody named. Spec epoch 0.4 closes the three gaps as records.

Requirement

A Requirement is an addressable statement of what a Request requires: a key, a description, whether it counts, what evidence would satisfy it, and who asserted it. That last field is the interesting one. Provenance is user_authored or derived, and it is bound to the author’s role by the verifier: a requirement is a person’s because a user-role author wrote it, never because a flag says so. An agent cannot mint a “user-authored” requirement.

Keys are unique among a request’s live requirements. Amendment is retract-and-record, and a retracted requirement taints every evaluation that judged against it, exactly as a retracted evaluation taints the selections that rested on it. The taint mechanism did not change; it now reaches one level further back.

Artifact identity

ArtifactRef is a content-addressed, scheme-tagged identity: git-tree-sha1, git-tree-sha256, manifest-v1, git-archive-tar-v1, oci-image-manifest, sha256-bytes, or an unregistered scheme under a generic digest rule. A digest identifies content, never a recording, so replays converge on the same reference. Candidates and results bind the artifacts they produced; an evaluation binds the artifacts it judged. The field is additive: a 0.3 payload keeps its bytes and its id.

The extended evaluation

bellbook.evaluation.v2 carries the v1 judgment plus a decider binding (evaluator {id, version, procedure_hash, input_hash}: who decided, with what exact procedure, over what input), a declared basis (recomputed from the bound evidence, or checked as declared; never inferred), the evidence it judged, and the requirements it speaks to.

Outcomes are fail-closed. passed, failed, scored, blocked, insufficient, stale, not_run: only passed passes. A decision that could not run to a pass is recorded as exactly what it is. This is the rule that keeps a missing check from reading as a green one.

Declarations a validator re-checks

A receipt can now carry profiles: [{id, version, hash}], the profiles it claims. The claim is never trusted. Every validator evaluates each declared profile itself, unasked, from its own clause table, and reports whether the declaration names the table it applied. A stale hash, a wrong version, an unknown profile, or a plain false claim all exit 3. A receipt that declares nothing is byte-identical to one written before the field existed.

From the CLI

bellbook request add     --author human --objective "ship the bound build"
bellbook requirement add --author human --request REQ --key R1 --description "unit tests pass"
bellbook candidate add   --author agent --git-tree TREE --artifact git-tree-sha1:TREE:src
bellbook eval add        --author evaluator --candidate CAND --criterion unit-tests --passed \
                         --evaluator test-harness --basis recomputed --requirement R1_ID \
                         --artifact git-tree-sha1:TREE
bellbook export          --profile bellbook-core-v1 --out receipt.json
bellbook validate receipt.json

The same story runs from Python alone (Writer.request, Writer.requirement, artifacts= and the extended evaluate keywords, receipt(profiles=...)), and both stories are enforced in CI as the release gate.

What stays valid

The record envelope, canonical form, signing form, and every 0.3 schema are byte-for-byte those of 0.3. A 0.4 validator dispatches on the receipt’s spec version: a 0.3 receipt replays under the 0.3 schema set and reaches the identical decision its own epoch’s validator reached. The 0.3 vectors and corpus are byte-frozen, every stored 0.3 outcome re-derives under the 0.4 validator, and CI replays the 0.3 receipts through the published 0.7.0 binary. The independent Python validator implements the new kinds from scratch and agrees with the reference on every vector of both epochs.

What comes next

delivery-receipt-v1 (v0.9.0) is the grammar of a delivery claim over these records: requirement, evidence, evaluator decision, artifact identity, capability profile, with its own fraud-rejection vectors. The signed tier, bellbook-core-signed-v1, follows at 1.0. The sequence is in RFC-0003.

cargo add bellbook, pip install bellbook. Specification in SPEC.md, sections 2, 12, and 14.