Skip to main content

khive_fold/
lib.rs

1//! khive-fold: Cognitive primitives — Fold, Anchor, Objective, Selector.
2//!
3//! Four cognitive primitives that form the "paper-folding" operation:
4//!
5//! - **Fold**: `entries → derived state` (deterministic reduce)
6//! - **Anchor**: causal graph traversal (provenance chains)
7//! - **Objective**: score candidates and select best
8//! - **Selector**: budget-constrained pack (many → subset)
9//!
10//! Plus deterministic ordering primitives, composition combinators,
11//! and common strategies (Recency, Relevance, Weighted, etc.).
12//!
13//! # Quick Start
14//!
15//! ```
16//! use khive_fold::{fold_fn, Fold, FoldContext};
17//!
18//! let counter = fold_fn(
19//!     |_ctx| 0usize,
20//!     |count, _entry: &i32, _ctx| count + 1,
21//! );
22//!
23//! let entries = [1, 2, 3, 4, 5];
24//! let result = counter.derive(entries.iter(), &FoldContext::new());
25//! assert_eq!(result.state, 5);
26//! ```
27
28// ── Core fold ───────────────────────────────────────────────────────────
29
30mod compose;
31mod context;
32mod error;
33mod fold;
34mod result;
35
36// ── Checkpoint protocol ─────────────────────────────────────────────────
37
38pub mod checkpoint;
39
40pub use compose::{filter, map, DualFold, FilterFold, MapFold, SequentialFold};
41pub use context::{FoldContext, SharedJson};
42pub use error::{FoldError, FoldResult, FoldResult as FoldResultType};
43pub use fold::{
44    fold_fn, AnyFold, BoxedFold, CommonFold, CommonFoldState, CountFold, FilterCountFold, FnFold,
45    Fold, FoldFailure, SumI64Fold, TryFold,
46};
47pub use result::FoldOutcome;
48
49// ── Checkpoint re-exports ────────────────────────────────────────────────
50
51pub use checkpoint::{Checkpoint, CheckpointStore, InMemoryCheckpointStore};
52
53// ── Anchor primitive ────────────────────────────────────────────────────
54
55pub mod anchor;
56
57pub use anchor::{Anchor, AnchorGraph, AnchorRef, BfsAnchor};
58
59// ── Selector primitive ──────────────────────────────────────────────────
60
61pub mod selector;
62
63pub use selector::{GreedySelector, Selector, SelectorInput, SelectorOutput, SelectorWeights};
64
65// ── Objective primitive ─────────────────────────────────────────────────
66
67pub mod objective;
68pub mod ordering;
69
70pub use khive_score::{cmp_asc_then_id, cmp_desc_then_id, DeterministicScore};
71pub use objective::builtin::{
72    FirstMatchObjective, HasImportance, HasTimestamp, ImportanceObjective, MaxScoreObjective,
73    RecencyObjective, RelevanceObjective, ThresholdObjective,
74};
75pub use objective::compose::{
76    ConsensusObjective, NegateObjective, PriorityObjective, ScaleObjective, UnionObjective,
77    WeightedObjective,
78};
79pub use objective::error::{ObjectiveError, ObjectiveResult};
80pub use objective::{objective_fn, DeterministicObjective, Objective, ObjectiveContext, Selection};
81pub use ordering::{
82    canonical_f32, canonical_f64, cmp_asc_score_then_id, cmp_desc_score_then_id, HasId, Ranked,
83    ScoredEntry,
84};
85
86// ── ComposePipeline ─────────────────────────────────────────────────────
87
88/// Pipeline that scores candidates with an objective then packs to budget via a selector.
89pub struct ComposePipeline<T> {
90    pub anchor: Box<dyn Anchor>,
91    pub objective: Box<dyn Objective<T>>,
92    pub selector: Box<dyn Selector<T>>,
93}
94
95impl<T: Clone + Send + Sync + 'static> ComposePipeline<T> {
96    /// Score candidates with the objective, then pack under budget with the selector.
97    pub fn execute(
98        &self,
99        _graph: &AnchorGraph,
100        candidates: Vec<SelectorInput<T>>,
101        budget: usize,
102        weights: &SelectorWeights,
103        context: &ObjectiveContext,
104    ) -> Result<SelectorOutput<T>, FoldError> {
105        let scored = candidates
106            .into_iter()
107            .map(|mut candidate| {
108                candidate.score = self.objective.score(&candidate.content, context) as f32;
109                candidate
110            })
111            .collect();
112        self.selector.select(scored, budget, weights)
113    }
114}