Skip to main content

Crate polyc_eventlog

Crate polyc_eventlog 

Source
Expand description

Append-only conversation event log on a commonware-storage journal.

This crate persists the ordered stream of events that make up a conversation (user messages, planner decisions, tool calls, …) to an append-only log backed by the Commonware storage stack — keeping persistence on the Commonware primitives rather than a relational store.

§Storage primitive

EventLog wraps commonware_storage::journal::contiguous::variable::Journal: a contiguous, position-based, variable-length append-only journal. It is the natural fit here:

  • Append-only. EventLog::append writes one Event and returns the monotonically increasing u64 position the journal assigned it. Positions start at 0 and never reused; pruning earlier entries does not shift later positions.
  • Ordered replay. EventLog::replay returns every event in append order, each paired with its position. Append order is the ordering contract: the caller appends events in conversation order (turn, then sequence within a turn), and replay yields them back in exactly that order. The position therefore is the (turn, seq) ordinal flattened into one strictly increasing sequence — there is no separate sort key to maintain, which is precisely what an append-only log buys us.
  • Variable-length items. Each event’s payload is an opaque, buffa-encoded byte blob of arbitrary size; the variable journal stores variable-length items natively (the contiguous::fixed sibling is for fixed-width records and would not fit).

§Runtime genericity (tokio vs. deterministic)

The journal — and therefore EventLog — is generic over a commonware_storage::Context (the Storage + Clock + Metrics bound every Commonware storage type carries). Production drives it on the commonware_runtime::tokio backend; tests drive it on the commonware_runtime::deterministic backend for seeded, reproducible runs. The two never nest: the Commonware runtime cannot be started from inside a live tokio runtime, so every tokio process that embeds this crate runs it on a dedicated thread. The state plane does so for the conversation journal it alone writes; the control plane does so for the non-conversation logs it keeps of its own. This crate stays runtime-agnostic and leaves that hosting decision to the caller.

§Conversation scoping

One EventLog instance maps to one conversation’s log, identified by the storage partition name passed to EventLog::open (derive it from the conversation id, e.g. format!("conv-{uid}")). Distinct conversations use distinct partitions and so are fully isolated on disk.

§Example

use commonware_runtime::{deterministic, Runner};
use polyc_eventlog::{Event, EventLog, EventLogConfig};

let executor = deterministic::Runner::default();
executor.start(|context| async move {
    let log = EventLog::open(context, EventLogConfig::for_partition("conv-1"))
        .await
        .expect("open log");

    log.append(&Event::new("user_msg", b"hello".to_vec())).await.unwrap();
    log.append(&Event::new("tool_call", b"\x01\x02".to_vec())).await.unwrap();
    log.commit().await.unwrap();

    let events = log.replay().await.unwrap();
    assert_eq!(events.len(), 2);
    assert_eq!(events[0].kind, "user_msg");
});

Re-exports§

pub use checkpoint::EventCountCheckpoint;
pub use error::EventLogError;

Modules§

checkpoint
Durable “expected event count” side-channel (#799 hardening).
error
Errors surfaced by the event log.
integrity
Per-conversation tamper-evidence over the event log (#799).
nav
Storage-agnostic lexical navigation over a conversation’s own history.
taint
Storage-agnostic trust/provenance tags and the “lethal trifecta” detector.

Structs§

BoundedReplay
A replay that may stop before the partition tail at a caller byte budget.
Event
A single conversation event: a kind tag, a TrustTag provenance capability, and an opaque encoded payload.
EventCfg
Decode-time bounds for an Event, supplied as the journal’s codec_config.
EventLog
An append-only, ordered log of conversation Events.
EventLogConfig
Configuration for opening an EventLog.
GrantedCapabilities
Capabilities granted to a turn that cannot yet be derived from the tagged event substrate alone — they require knowledge of the live tool catalog.
QuarantinedItem
One event EventLog::replay_quarantining could not decode, and why.
TrifectaLegs
The three independent capability legs whose simultaneous presence in one conversation forms the “lethal trifecta” data-exfiltration path.

Enums§

IntegrityError
Failures from extending, signing, or verifying a partition’s MMR.
TrustTag
Trust/provenance capability tag attached to every conversation event at ingress.

Constants§

MMR_SIGNED_ROOT_KIND
Event kind naming a persisted SignedRoot marker. Namespaced so it cannot collide with any conversation-content kind (every real kind in polyc-proto’s events.proto is a bare identifier with no __ wrapping).

Functions§

any_untrusted
Whether any event in events carries untrusted (TrustTag::QuarantinedContent) provenance — the durable form of the trifecta’s untrusted-content-in-context leg, read straight from the trust tags.
any_untrusted_excluding
any_untrusted over position-carrying events, excluding the journal positions a verified taint-excision marker covers (#590).
extend_and_sign
Extend log with each of new_events’s (kind, payload) leaves, sign the resulting root with signer, and return the Event to append (kind MMR_SIGNED_ROOT_KIND) — the caller places it in the SAME journal batch as new_events (e.g. right before turn_complete) so the signature is atomic with the content it covers.
init_metrics
Force-register this crate’s Prometheus append-latency histogram.
rebuild_from_events
Reconstruct a partition’s running MMR from a full replay, for a caller that wants to keep extending it (the eventlog host, on first touching a partition after a restart). Root-marker events themselves are not MMR leaves — only real conversation events are — so this filters them out before delegating to VerifiableLog::rebuild.
trifecta_legs
Compute the TrifectaLegs for a conversation from its tagged event log and the capabilities granted to the turn.
verify_extension_with_trust
Verifies events as the CONTINUATION of the partition log already covers, extending log leaf by leaf exactly as a replay of the whole partition would, and checking every MMR_SIGNED_ROOT_KIND marker it meets against the tree at that point.
verify_replay
Verify a full partition replay’s tamper-evidence: rebuild the MMR leaf by leaf in append order, and at every MMR_SIGNED_ROOT_KIND marker check that (a) its signature verifies under expected_signer_pk_hex and (b) the tree’s root and leaf count at that point match what the marker claims. Returns on the FIRST violation found, naming exactly where it occurred.
verify_replay_with_trust
Replays and verifies every root against current and retired role keys.