Skip to main content

Module fold

Module fold 

Source
Expand description

The deterministic fold: fold(ops) → materialized state.

The proposal’s convergence contract, verbatim: “each daemon folds the full op-set into local state deterministically. Because the fold is commutative, associative, and idempotent over the op-set (CRDT properties), two laptops writing simultaneously converge the moment they exchange ops.”

Fold rules per surface tier (the proposal’s table):

  • Grow-only (conversations, knowledge, skills, trajectories, runs, routing observations): union by crate::oplog::OpRecord::fold_key — the stable entity key for logical-entity surfaces, the op_id for event-stream surfaces (routing), which fold as a MULTISET: the proposal replays “the merged multiset of observations”, so two byte-identical observations are two events and both survive. Entities are immutable in this tier (a change is a new op — e.g. a Supersedes fact), so on a key collision with different content the earliest (hlc, op_id) writer wins, deterministically.
  • Registry (declagents, the file registries): LWW-register per record keyed by id, ordered by HLC — not per file. Latest (hlc, op_id) wins; concurrent edits to different records both survive.
  • Routing: the fold materializes the hlc-ordered observation stream; the EMA replay is the caller-injected SyncState::replay (“sync the observations, not the result” — same observations + same canonical order ⇒ bit-identical result on every device).
  • Leased (Intent, B5): LWW-per-run_id (monotone status) with per-agent epoch fencing — a stale-epoch intent from a failed-over lease holder loses at the fold, order-independently. See crate::lease and the fold_onto FoldTier::Leased arm.

Determinism discipline: all state is BTreeMap-backed and nothing here reads a clock — the proposal calls out “a non-determinism leak (wall-clock or HashMap iteration order sneaking into a fold)” as the bug class state_hash exists to catch.

Re-exports§

pub use crate::oplog::FoldTier;

Structs§

FoldedRecord
One folded entity: the winning op’s payload plus the stamp/id it won with.
IntentAgent
One agent’s leased execution-intent ledger — the FoldTier::Leased tier’s per-agent folded state (B5).
SyncState
The materialized read model a full op-set folds to. On-disk files (conversations/*.jsonl, declagents.json, …) are projections of this (the proposal’s “files are projections” reframe); B4’s checkpoint is a serialized SyncState at a frontier.

Functions§

fold
Fold an op-set into its materialized state. Order-independent (per-key winner selection under a total order), idempotent (ops dedup on op_id first), and pure.
fold_onto
Fold additional ops onto an already-folded base state — the B4 checkpoint-consumption primitive: a truncated device reconstructs fold(full log) as fold_onto(checkpoint.state, retained tail).
hlc_version
Encode an Hlc as a single u64 version that preserves the (wall_ms, counter) order — the bridge onto car_state::crdt’s (version, replica) total order. 44 bits of wall-clock milliseconds (good past year 2500) and 20 bits of counter; a counter ≥ 2^20 within one millisecond is outside the HLC’s operating range (B3’s clock guarantees far less) and would break the order-preservation, so it is debug-asserted.
registry_as_lww
Project a folded registry surface onto the shipped car_state::crdt::LwwMap, so the oplog fold composes with (and is testably equivalent to) crdt_merge/crdt_export where the domains overlap: fold(union of ops)merge_maps(per-device exports).
state_hash
Deterministic content hash of a folded state — the proposal’s built-in divergence invariant: “Same frontier ⇒ same snapshot hash, deterministically. A mismatch is a fold bug or a non-determinism leak.” B4’s checkpoint hash is this value at a frontier.