Skip to main content

waggle_core/
lib.rs

1//! # waggle-core — the sans-I/O domain
2//!
3//! The core performs **no I/O, owns no clock, and generates no entropy**
4//! (design doc `03 §1`). Every effect is a parameter:
5//!
6//! - randomness arrives through [`Entropy`] (blanket-implemented for
7//!   closures — function passing, not global state),
8//! - time arrives as a [`Timestamp`] value in every signature that needs
9//!   one,
10//! - storage never appears here at all (see `waggle-store`).
11//!
12//! This is what lets the identical code run in the native daemon, in
13//! Cloudflare Workers wasm, and under deterministic tests.
14//!
15//! CP-0 shipped the foundation trio: [`Token`], [`Timestamp`], [`Entropy`].
16//! CP-1 adds the domain model: slugs ([`Sharer`], [`Channel`], [`Stage`]),
17//! targets ([`CanonicalUrl`], [`TargetMeta`], [`MediaRef`]), the
18//! three-zone [`AttributionManifest`] with variants, and [`mint`] — a pure
19//! function of `(spec, options, entropy, now)`. The sealed variant matcher
20//! and folds land in CP-2/CP-3 (design docs `02`–`04`).
21//!
22//! ```
23//! use waggle_core::{Entropy, Token};
24//!
25//! // A deterministic entropy source: fine for tests, never for production.
26//! let mut counter = 0u8;
27//! let mut entropy = |buf: &mut [u8]| {
28//!     for b in buf.iter_mut() {
29//!         counter = counter.wrapping_add(41);
30//!         *b = counter;
31//!     }
32//!     Ok(())
33//! };
34//! let token = Token::generate(8, &mut entropy).expect("entropy never fails here");
35//! assert_eq!(token.as_str().len(), 8);
36//! ```
37
38mod context;
39mod entropy;
40mod event;
41mod fold;
42mod log;
43mod manifest;
44mod matcher;
45mod mint;
46mod reconstruct;
47mod resolve;
48mod slug;
49mod soa;
50mod target;
51mod time;
52mod token;
53
54pub use context::{negotiate, ConsumerHint, ConsumerKind, ResolverContext};
55pub use entropy::{Entropy, EntropyError};
56pub use event::{ActorClass, Event, FamilyClass, HarnessClass, Seq};
57pub use fold::{replay, Fold, FunnelFold, LineageFold, ManifestFold};
58pub use log::{Change, LogRecord};
59pub use manifest::{
60    apply_change, AttributionManifest, Constraint, Disposition, MatchExpr, ModalitySet, Posture,
61    Variant, VariantBody, MANIFEST_SCHEMA_VERSION,
62};
63pub use matcher::{select_variant, Selected};
64pub use mint::{mint, MintError, MintOptions, MintSpec};
65pub use reconstruct::{apply_suffix, reconstruct, WorldState};
66pub use resolve::{resolve, Resolution, DEFAULT_REVALIDATE_MS};
67pub use slug::{Channel, Sharer, SlugError, Stage};
68pub use soa::{EventLog, InternTables, StageId, TokenId};
69pub use target::{
70    CanonicalUrl, MediaRef, Sha256Error, Sha256Hex, TargetError, TargetMeta,
71    INLINE_THRESHOLD_BYTES, MANIFEST_SIZE_CAP_BYTES,
72};
73pub use time::Timestamp;
74pub use token::{Token, TokenError, TOKEN_ALPHABET};