Skip to main content

Crate bellbook

Crate bellbook 

Source
Expand description

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

Bellbook is a small embeddable library with one durable primitive: a typed Record in an append-only log. Records are content-addressed (the id is the SHA-256 of the record’s canonical form) and linked by typed refs, so modifying hash-covered records or their committed sequence is detectable. Detecting complete replacement from genesis requires external anchoring. A deterministic verifier (verify_log) replays the whole log and confirms it followed the rules: every record is immediately judged by a Verdict, ids recompute, logical time has no gaps, and every verdict itself re-derives.

Not a logger, not a database, not a runtime - an evidence kernel a host process embeds to turn “the agent says it did X” into replay-verifiable evidence of the agent activity that was recorded. Bellbook proves consistency of captured history, not capture completeness (see SPEC.md, Known limitations).

§Example

use bellbook::*;

let dir = tempfile::tempdir()?;
let space = default_space();
// Bind actor identities to roles: the declared author type on a
// record is never trusted by itself.
let rules = VerifierRules::new(space, 200).with_author_role("human", AuthorType::User);

let mut writer = LogWriter::open(dir.path(), &rules)?;
let mut state = State::default();

let proposal = Proposal {
    space,
    thread: sha256_utf8("demo-thread"),
    author: Author { id: "human".into(), type_: AuthorType::User, signature: None },
    kind: Kind::Request,
    schema: schema_id(SCHEMA_REQUEST),
    data: encode(&RequestData {
        objective: "summarize the report".into(),
        scope: sha256_utf8("demo-scope"),
        attachments: vec![],
        parent_request_id: None,
    })?,
    refs: vec![],
};

let (_id, verdict) = writer.commit(proposal, &rules, &mut state)?;
assert_eq!(verdict.result, VerdictResult::Accept);

// Replay-verify the entire log: ids, times, and every verdict recompute.
let report = verify_log(writer.records(), &rules, None);
assert_eq!(report.result, VerdictResult::Accept);

Re-exports§

pub use base::canonical::canonical_json;
pub use base::canonical::canonical_json_string;
pub use base::hash::hex_decode;
pub use base::hash::hex_encode;
pub use base::hash::sha256;
pub use base::hash::sha256_canonical;
pub use base::hash::sha256_concat_ids;
pub use base::hash::sha256_utf8;
pub use base::hash::Hash256;
pub use base::schema::default_space;
pub use base::schema::schema_id;
pub use base::schema::schema_name_for_id;
pub use base::schema::SchemaId;
pub use base::schema::DEFAULT_SPACE_NAME;
pub use base::schema::SCHEMA_ACTION;
pub use base::schema::SCHEMA_APPROVAL;
pub use base::schema::SCHEMA_CAPABILITY;
pub use base::schema::SCHEMA_PLAN;
pub use base::schema::SCHEMA_REFUSAL;
pub use base::schema::SCHEMA_REQUEST;
pub use base::schema::SCHEMA_RESPONSE;
pub use base::schema::SCHEMA_RESULT;
pub use base::schema::SCHEMA_RESULT_EFFECT_CONFIRMATION;
pub use base::schema::SCHEMA_RESULT_EXTERNAL;
pub use base::schema::SCHEMA_RETRACTION;
pub use base::schema::SCHEMA_SUMMARY;
pub use base::schema::SCHEMA_USAGE;
pub use base::schema::SCHEMA_VERDICT;
pub use base::schema::SPEC_VERSION;
pub use base::time::Time;
pub use base::time::TimeSource;
pub use record::author::ActorId;
pub use record::author::Author;
pub use record::author::Signature;
pub use record::evidence::base_evidence;
pub use record::evidence::derive_evidence;
pub use record::evidence::weakest;
pub use record::evidence::Evidence;
pub use record::kind::AuthorType;
pub use record::kind::CapabilityMode;
pub use record::kind::ExecMode;
pub use record::kind::Kind;
pub use record::kind::ReasonCode;
pub use record::kind::RefType;
pub use record::kind::RefusalTarget;
pub use record::kind::ResultStatus;
pub use record::kind::SummaryType;
pub use record::kind::UsageOutcome;
pub use record::kind::VerdictResult;
pub use record::payloads::ActionData;
pub use record::payloads::ApprovalData;
pub use record::payloads::Attachment;
pub use record::payloads::CapabilityData;
pub use record::payloads::FailurePolicy;
pub use record::payloads::PlanData;
pub use record::payloads::PlanStatus;
pub use record::payloads::PlanTask;
pub use record::payloads::PlanTaskKind;
pub use record::payloads::RefusalData;
pub use record::payloads::RequestData;
pub use record::payloads::ResponseData;
pub use record::payloads::ResultData;
pub use record::payloads::RetractionData;
pub use record::payloads::SummaryData;
pub use record::payloads::TaskDoneWhen;
pub use record::payloads::TaskStatus;
pub use record::payloads::UsageData;
pub use record::payloads::UsageOutcomeCounts;
pub use record::payloads::VerdictData;
pub use record::record::decode;
pub use record::record::encode;
pub use record::record::Proposal;
pub use record::record::Record;
pub use record::record::ScopeId;
pub use record::record::SpaceId;
pub use record::record::ThreadId;
pub use record::record::RECORD_SIGNATURE_DOMAIN;
pub use record::refs::sort_and_dedup_refs;
pub use record::refs::RecordId;
pub use record::refs::Ref;
pub use record::sign::signature_verifies;
pub use record::sign::verified_key;
pub use record::sign::Ed25519Signer;
pub use record::sign::PublicKeyBytes;
pub use checkpoint::create_checkpoint;
pub use checkpoint::head_attestation;
pub use checkpoint::CanonicalUtcTimestamp;
pub use checkpoint::Checkpoint;
pub use checkpoint::HeadAttestation;
pub use checkpoint::InvalidTimestamp;
pub use checkpoint::TrustedCheckpoint;
pub use log::writer::BatchAppend;
pub use log::writer::LogWriter;
pub use log::writer::DEFAULT_MAX_LOG_BYTES;
pub use log::writer::EMPTY_HEAD;
pub use receipt::validate;
pub use receipt::validate_with_limits;
pub use receipt::Receipt;
pub use receipt::Report;
pub use receipt::ValidationLimits;
pub use receipt::ValidationStatus;
pub use verify::rules::VerifierRules;
pub use verify::verifier::verify_log;
pub use verify::verifier::verify_record;
pub use verify::verifier::LogVerdict;
pub use state::build::build_state_unchecked;
pub use state::build::verify_and_build_state;
pub use state::incremental::apply_record;
pub use state::incremental::find_replace_ref;
pub use state::state::State;
pub use context::context::build_context;
pub use context::context::build_context_with;
pub use context::context::Context;
pub use context::context::ContextPolicy;
pub use propose::proposer::Proposer;

Modules§

base
Foundations: canonical JSON, SHA-256 hashing, frozen schema ids, and the logical time source.
checkpoint
Checkpoint creation and verification from SPEC.md.
context
Deterministic selection of the per-thread working set shown to an untrusted proposer.
log
Persistent log implementation (append-only file + writer). Requires feature persist.
propose
The untrusted Proposer interface - emits proposals, holds no append authority.
receipt
Portable receipts: export a log as a self-contained bundle and validate it offline. Portable receipts: export a log as a self-contained bundle and validate it offline (SPEC §12).
record
The Record primitive: kinds, payloads, refs, authors, and evidence.
state
Derived State: a pure fold over accepted (record, verdict) pairs.
verify
The deterministic verifier: per-record rules and full log replay.

Enums§

LogError
Error type for the bellbook crate.