diff --git a/crates/bft-json-crdt/benches/speed.rs b/crates/bft-json-crdt/benches/speed.rs index 5f3abb92..14f547c1 100644 --- a/crates/bft-json-crdt/benches/speed.rs +++ b/crates/bft-json-crdt/benches/speed.rs @@ -1,3 +1,4 @@ +//! Benchmarks for BFT JSON CRDT operation throughput. use bft_json_crdt::{ json_crdt::JsonValue, keypair::make_author, list_crdt::ListCrdt, op::Op, op::ROOT_ID, }; diff --git a/crates/bft-json-crdt/bft-crdt-derive/src/lib.rs b/crates/bft-json-crdt/bft-crdt-derive/src/lib.rs index 3810be5a..7ad51c79 100644 --- a/crates/bft-json-crdt/bft-crdt-derive/src/lib.rs +++ b/crates/bft-json-crdt/bft-crdt-derive/src/lib.rs @@ -1,3 +1,9 @@ +//! Procedural macros for the BFT JSON CRDT library. +//! +//! Provides `#[add_crdt_fields]` to inject `path` and `id` fields into a struct, +//! and `#[derive(CrdtNode)]` to auto-implement the [`CrdtNode`] trait for structs +//! whose fields are themselves [`CrdtNode`]s. + use proc_macro::TokenStream as OgTokenStream; use proc_macro2::{Ident, Span, TokenStream}; use proc_macro_crate::{crate_name, FoundCrate}; diff --git a/crates/bft-json-crdt/src/debug.rs b/crates/bft-json-crdt/src/debug.rs index 94e0546d..ae1c244e 100644 --- a/crates/bft-json-crdt/src/debug.rs +++ b/crates/bft-json-crdt/src/debug.rs @@ -1,3 +1,9 @@ +//! Debug helpers and the [`DebugView`] trait for rendering CRDT internals. +//! +//! Most items in this module are no-ops in release builds. They are activated by +//! the `logging-base`, `logging-json`, and `logging-list` Cargo features so that +//! debug output can be toggled without changing production code. + use crate::{ json_crdt::{BaseCrdt, CrdtNode, SignedOp}, keypair::SignedDigest, @@ -37,6 +43,7 @@ fn display_op_id(op: &Op) -> String { ) } +/// Log a type-mismatch warning when deserialising a JSON value into a CRDT node fails. pub fn debug_type_mismatch(_msg: String) { #[cfg(feature = "logging-base")] { @@ -44,6 +51,7 @@ pub fn debug_type_mismatch(_msg: String) { } } +/// Log a path-mismatch warning when an operation's path does not match the CRDT's path. pub fn debug_path_mismatch(_our_path: Vec, _op_path: Vec) { #[cfg(feature = "logging-base")] { @@ -56,6 +64,7 @@ pub fn debug_path_mismatch(_our_path: Vec, _op_path: Vec) { #[cfg(feature = "logging-base")] { @@ -79,16 +88,20 @@ fn display_author(author: AuthorId) -> String { .to_string() } +/// Render CRDT state as an indented human-readable string for debugging. pub trait DebugView { + /// Return a multi-line debug string for this CRDT node, indented by `indent` spaces. fn debug_view(&self, indent: usize) -> String; } impl BaseCrdt { + /// Print the current document state as an indented debug tree (no-op in release builds). pub fn debug_view(&self) { #[cfg(feature = "logging-json")] println!("document is now:\n{}", self.doc.debug_view(0)); } + /// Log an attempt to apply `op` before the result is known (no-op in release builds). pub fn log_try_apply(&self, _op: &SignedOp) { #[cfg(feature = "logging-json")] println!( @@ -99,6 +112,7 @@ impl BaseCrdt { ); } + /// Log a signature-digest verification failure for `op` (no-op in release builds). pub fn debug_digest_failure(&self, _op: SignedOp) { #[cfg(feature = "logging-json")] println!( @@ -108,6 +122,7 @@ impl BaseCrdt { ); } + /// Log that a causal dependency identified by `missing` has not yet been received. pub fn log_missing_causal_dep(&self, _missing: &SignedDigest) { #[cfg(feature = "logging-json")] println!( @@ -117,6 +132,7 @@ impl BaseCrdt { ); } + /// Log that `op` is about to be integrated into the document (no-op in release builds). pub fn log_actually_apply(&self, _op: &SignedOp) { #[cfg(feature = "logging-json")] { @@ -133,6 +149,7 @@ impl Op where T: CrdtNode, { + /// Log an operation hash verification failure showing expected and computed IDs. pub fn debug_hash_failure(&self) { #[cfg(feature = "logging-base")] { @@ -191,6 +208,7 @@ impl ListCrdt where T: CrdtNode, { + /// Print the full operation log as a tree, optionally highlighting one operation (no-op in release builds). pub fn log_ops(&self, _highlight: Option) { #[cfg(feature = "logging-list")] { @@ -289,6 +307,7 @@ where } } + /// Log the insert or delete being performed for `op` (no-op in release builds). pub fn log_apply(&self, _op: &Op) { #[cfg(feature = "logging-list")] { diff --git a/crates/bft-json-crdt/src/keypair.rs b/crates/bft-json-crdt/src/keypair.rs index 56499e01..9713d3aa 100644 --- a/crates/bft-json-crdt/src/keypair.rs +++ b/crates/bft-json-crdt/src/keypair.rs @@ -1,3 +1,9 @@ +//! Ed25519 keypair utilities and type aliases for node identity and signing. +//! +//! Provides the [`AuthorId`] and [`SignedDigest`] type aliases, a SHA-256 helper, +//! and convenience wrappers around the `fastcrypto` Ed25519 primitives used +//! throughout the CRDT codebase. + use fastcrypto::traits::VerifyingKey; pub use fastcrypto::{ ed25519::{ diff --git a/crates/bft-json-crdt/src/lib.rs b/crates/bft-json-crdt/src/lib.rs index 00691d23..4c43acfe 100644 --- a/crates/bft-json-crdt/src/lib.rs +++ b/crates/bft-json-crdt/src/lib.rs @@ -1,8 +1,21 @@ +//! BFT JSON CRDT library — a Byzantine Fault-Tolerant replicated JSON document +//! built on an RGA list CRDT, an LWW register CRDT, and a signed-op substrate. +//! +//! Each document is identified by an Ed25519 keypair. Operations are signed and +//! carry causal dependencies so that every node converges to the same value +//! regardless of message delivery order. + +/// Debug helpers and the [`DebugView`] trait for rendering CRDT internals. pub mod debug; +/// JSON CRDT public interface: core traits, types, and signed-op substrate. pub mod json_crdt; +/// Ed25519 keypair utilities and primitive type aliases used throughout the crate. pub mod keypair; +/// RGA-style list CRDT that can store any [`CrdtNode`] as its element type. pub mod list_crdt; +/// Last-writer-wins (LWW) register CRDT for single-value fields. pub mod lww_crdt; +/// Core operation types: [`Op`], [`PathSegment`], and hashing helpers. pub mod op; extern crate self as bft_json_crdt; diff --git a/crates/bft-json-crdt/src/list_crdt.rs b/crates/bft-json-crdt/src/list_crdt.rs index e56cbfd1..7efbf6a4 100644 --- a/crates/bft-json-crdt/src/list_crdt.rs +++ b/crates/bft-json-crdt/src/list_crdt.rs @@ -1,3 +1,9 @@ +//! RGA-style list CRDT that stores any [`CrdtNode`] as its element type. +//! +//! Implements the Replicated Growable Array (RGA) algorithm with causal ordering. +//! Concurrent inserts at the same position are resolved by sequence number then +//! by author public key so that all replicas converge to the same sequence. + use crate::{ debug::debug_path_mismatch, json_crdt::{CrdtNode, JsonValue, OpState}, diff --git a/crates/bft-json-crdt/src/lww_crdt.rs b/crates/bft-json-crdt/src/lww_crdt.rs index 6d4e30ba..c93e0001 100644 --- a/crates/bft-json-crdt/src/lww_crdt.rs +++ b/crates/bft-json-crdt/src/lww_crdt.rs @@ -1,3 +1,9 @@ +//! Last-writer-wins (LWW) register CRDT. +//! +//! Implements a delete-wins LWW register for primitive values inside a nested +//! JSON CRDT. Concurrent writes are resolved by sequence number; ties are broken +//! by author public key so every node converges to the same value. + use crate::debug::DebugView; use crate::json_crdt::{CrdtNode, JsonValue, OpState}; use crate::op::{join_path, print_path, Op, PathSegment, SequenceNumber}; diff --git a/crates/bft-json-crdt/src/op.rs b/crates/bft-json-crdt/src/op.rs index aaa6f024..58f82283 100644 --- a/crates/bft-json-crdt/src/op.rs +++ b/crates/bft-json-crdt/src/op.rs @@ -1,3 +1,9 @@ +//! Core operation types for the BFT JSON CRDT. +//! +//! Defines [`Op`] (the fundamental unit of change), [`PathSegment`] (for +//! addressing nested CRDTs), and [`SequenceNumber`] / [`OpId`] type aliases. +//! Also provides hashing utilities used when computing operation identifiers. + use crate::debug::{debug_path_mismatch, debug_type_mismatch}; use crate::json_crdt::{CrdtNode, CrdtNodeFromValue, IntoCrdtNode, JsonValue, SignedOp}; use crate::keypair::{sha256, AuthorId}; @@ -113,6 +119,7 @@ where /// Conversion from Op -> Op given that T is a CRDT that can be created from a JSON value impl Op { + /// Convert this `Op` into an `Op` by deserialising the content via `T::node_from`. pub fn into(self) -> Op { let content = if let Some(inner_content) = self.content { match inner_content.into_node(self.id, self.path.clone()) { @@ -141,10 +148,12 @@ impl Op where T: CrdtNode, { + /// Sign this operation with `keypair`, producing a [`SignedOp`] with no causal dependencies. pub fn sign(self, keypair: &Ed25519KeyPair) -> SignedOp { SignedOp::from_op(self, keypair, vec![]) } + /// Sign this operation and attach explicit causal `dependencies`. pub fn sign_with_dependencies( self, keypair: &Ed25519KeyPair, @@ -160,14 +169,17 @@ where ) } + /// Return the [`AuthorId`] (Ed25519 public key) of the node that created this operation. pub fn author(&self) -> AuthorId { self.author } + /// Return the Lamport sequence number carried by this operation. pub fn sequence_num(&self) -> SequenceNumber { self.seq } + /// Construct a new operation, computing its [`OpId`] hash from the supplied fields. pub fn new( origin: OpId, author: AuthorId, diff --git a/crates/bft-json-crdt/tests/byzantine.rs b/crates/bft-json-crdt/tests/byzantine.rs index d2044ec1..f28fde51 100644 --- a/crates/bft-json-crdt/tests/byzantine.rs +++ b/crates/bft-json-crdt/tests/byzantine.rs @@ -1,3 +1,4 @@ +//! Integration tests verifying Byzantine fault tolerance of the CRDT. use bft_json_crdt::{ json_crdt::{add_crdt_fields, BaseCrdt, CrdtNode, IntoCrdtNode, OpState}, keypair::make_keypair, diff --git a/crates/bft-json-crdt/tests/commutative.rs b/crates/bft-json-crdt/tests/commutative.rs index ddda95cb..9abc4fb9 100644 --- a/crates/bft-json-crdt/tests/commutative.rs +++ b/crates/bft-json-crdt/tests/commutative.rs @@ -1,3 +1,4 @@ +//! Integration tests verifying commutativity of CRDT operations. use bft_json_crdt::{ json_crdt::{CrdtNode, JsonValue}, keypair::make_author, diff --git a/server/src/agents/merge/squash/tests_advanced.rs b/server/src/agents/merge/squash/tests_advanced.rs index c0695ee1..87d7ab92 100644 --- a/server/src/agents/merge/squash/tests_advanced.rs +++ b/server/src/agents/merge/squash/tests_advanced.rs @@ -1,3 +1,4 @@ +//! Tests for squash-merge orchestration — advanced and regression cases. use super::*; use std::process::Command; diff --git a/server/src/agents/merge/squash/tests_basic.rs b/server/src/agents/merge/squash/tests_basic.rs index 87e0665d..2466fbf7 100644 --- a/server/src/agents/merge/squash/tests_basic.rs +++ b/server/src/agents/merge/squash/tests_basic.rs @@ -1,3 +1,4 @@ +//! Tests for squash-merge orchestration — basic cases. use super::*; use std::process::Command; diff --git a/server/src/agents/pool/pipeline/completion/tests.rs b/server/src/agents/pool/pipeline/completion/tests.rs index 47045c9f..0d560737 100644 --- a/server/src/agents/pool/pipeline/completion/tests.rs +++ b/server/src/agents/pool/pipeline/completion/tests.rs @@ -1,3 +1,4 @@ +//! Tests for agent pipeline completion handling. use super::super::super::AgentPool; use super::*; use crate::agents::{AgentEvent, AgentStatus, CompletionReport}; diff --git a/server/src/config/tests.rs b/server/src/config/tests.rs index 68395abb..e6ea9802 100644 --- a/server/src/config/tests.rs +++ b/server/src/config/tests.rs @@ -1,3 +1,4 @@ +//! Tests for project configuration parsing and validation. use super::*; use std::fs; diff --git a/server/src/crdt_snapshot/tests.rs b/server/src/crdt_snapshot/tests.rs index 3c7cf63e..4ce553d3 100644 --- a/server/src/crdt_snapshot/tests.rs +++ b/server/src/crdt_snapshot/tests.rs @@ -1,3 +1,4 @@ +//! Tests for CRDT snapshot compaction and cross-node coordination. use super::*; use bft_json_crdt::json_crdt::{BaseCrdt, JsonValue, SignedOp}; use bft_json_crdt::keypair::make_keypair; diff --git a/server/src/http/agents/tests.rs b/server/src/http/agents/tests.rs index 051b8569..30e0d0ca 100644 --- a/server/src/http/agents/tests.rs +++ b/server/src/http/agents/tests.rs @@ -1,3 +1,4 @@ +//! Tests for the HTTP agent endpoints. use super::*; use crate::agents::AgentStatus; use std::path; diff --git a/server/src/io/watcher/tests.rs b/server/src/io/watcher/tests.rs index 9dd9b83a..fcaa4856 100644 --- a/server/src/io/watcher/tests.rs +++ b/server/src/io/watcher/tests.rs @@ -1,3 +1,4 @@ +//! Tests for the filesystem config watcher. use super::*; // ── is_config_file ──────────────────────────────────────────────────────── diff --git a/server/src/pipeline_state/tests.rs b/server/src/pipeline_state/tests.rs index f476bb09..aa2456f5 100644 --- a/server/src/pipeline_state/tests.rs +++ b/server/src/pipeline_state/tests.rs @@ -1,3 +1,4 @@ +//! Tests for the typed pipeline state machine. use super::*; use std::num::NonZeroU32;