nodedb_crdt/lib.rs
1//! # nodedb-crdt
2//!
3//! CRDT engine with SQL constraint validation for NodeDB.
4//!
5//! ## The CRDT / SQL Paradox
6//!
7//! CRDTs are AP (Available + Partition-tolerant): agents compute optimistic
8//! deltas offline and sync later. SQL constraints are CP (Consistent +
9//! Partition-tolerant): UNIQUE indexes, foreign keys, etc. must hold globally.
10//!
11//! This crate bridges the gap:
12//!
13//! 1. **Optimistic local writes** — agents apply deltas to their local `LoroDoc`
14//! without constraint checks (AP behavior for availability).
15//! 2. **Constraint validation at commit** — when deltas sync to the leader,
16//! constraints are validated against the committed state.
17//! 3. **Dead-letter queue** — rejected deltas are routed to a DLQ with
18//! compensation hints so the application can recover gracefully.
19//! 4. **Pre-validation** — optional fast-reject against the leader's state
20//! before the full Raft round-trip, reducing wasted consensus bandwidth.
21
22/// Authentication context threaded through CRDT validation.
23///
24/// Carries the identity of who submitted the delta so the DLQ and deferred
25/// queue can attribute entries to the correct user/tenant.
26#[derive(Debug, Clone, Copy, Default)]
27pub struct CrdtAuthContext {
28 /// Authenticated user_id (0 = unauthenticated/legacy).
29 pub user_id: u64,
30 /// Tenant this operation belongs to.
31 pub tenant_id: u32,
32 /// Unix timestamp (milliseconds) when this auth session expires.
33 /// 0 = no expiry (trust mode / legacy).
34 /// Agents accumulating deltas offline must re-authenticate before
35 /// syncing if their auth context has expired.
36 pub auth_expires_at: u64,
37 /// HMAC signature over delta bytes (optional delta signing).
38 /// Empty = unsigned. When set, the validator verifies this before accepting.
39 pub delta_signature: [u8; 32],
40}
41
42pub mod constraint;
43pub mod constraint_checks;
44pub mod dead_letter;
45pub mod deferred;
46pub mod error;
47pub mod list_ops;
48pub mod policy;
49pub mod pre_validate;
50pub mod signing;
51pub mod state;
52pub mod validator;
53
54pub use constraint::{Constraint, ConstraintKind, ConstraintSet};
55pub use dead_letter::{CompensationHint, DeadLetterQueue};
56pub use deferred::DeferredQueue;
57pub use error::{CrdtError, Result};
58pub use policy::{
59 CollectionPolicy, ConflictPolicy, PolicyRegistry, PolicyResolution, ResolvedAction,
60};
61pub use signing::DeltaSigner;
62pub use state::CrdtState;
63pub use validator::{ValidationOutcome, Validator};