#![warn(missing_docs)]
#![warn(clippy::all)]
#![allow(clippy::module_inception)]
pub mod arena;
pub mod dynamics;
pub mod graph;
pub mod setun;
#[cfg(feature = "server")]
pub mod persistence;
#[cfg(feature = "server")]
pub mod protocol;
pub mod ffi;
pub use arena::{Engram, Lineage, LineageId, PsycheArena, StrataArena};
pub use dynamics::{DecayConfig, DecayEngine};
pub use graph::{Bond, BondGraph, BondId};
pub use setun::{Cortex, Octet, Quantizer, RetentionBuffer, Trit};
pub const DEFAULT_MAX_LINEAGES: usize = 1 << 20;
pub const DEFAULT_MAX_BONDS: usize = 1 << 22;
pub const DEFAULT_STRATA_DEPTH: usize = 64;
pub struct MindFry {
pub psyche: PsycheArena,
pub strata: StrataArena,
pub bonds: BondGraph,
pub decay: DecayEngine,
pub cortex: Cortex,
pub synapse: dynamics::SynapseEngine,
#[cfg(feature = "server")]
pub store: Option<std::sync::Arc<persistence::AkashicStore>>,
}
impl MindFry {
pub fn new() -> Self {
Self::with_config(MindFryConfig::default())
}
pub fn with_config(config: MindFryConfig) -> Self {
use setun::{dimension, Octet, Trit};
let psyche = PsycheArena::with_capacity(config.max_lineages);
let strata = StrataArena::with_capacity(config.max_lineages, config.strata_depth);
let bonds = BondGraph::with_capacity(config.max_lineages, config.max_bonds);
let decay = DecayEngine::new(config.decay);
let mut personality = Octet::neutral();
personality.set(dimension::CURIOSITY, Trit::True);
personality.set(dimension::PRESERVATION, Trit::True);
let cortex = Cortex::new(personality);
Self {
psyche,
strata,
bonds,
decay,
cortex,
synapse: dynamics::SynapseEngine::new(),
#[cfg(feature = "server")]
store: None,
}
}
#[cfg(feature = "server")]
pub fn with_store(mut self, store: std::sync::Arc<persistence::AkashicStore>) -> Self {
self.store = Some(store);
self
}
#[cfg(feature = "server")]
pub fn resurrect(&mut self) -> Result<bool, persistence::AkashicError> {
let store = match &self.store {
Some(s) => s,
None => return Ok(false),
};
let snapshot = match store.latest_snapshot()? {
Some(s) => s,
None => return Ok(false),
};
tracing::info!(
"🔄 Restoring from snapshot '{}'...",
snapshot.meta.name.as_deref().unwrap_or("unnamed")
);
let (psyche, strata, bonds, _physics) = store.restore_snapshot(
&snapshot,
self.psyche.capacity(),
self.bonds.capacity(),
64, )?;
self.psyche = psyche;
self.strata = strata;
self.bonds = bonds;
if let Some(ref cortex_data) = snapshot.cortex_data {
match bincode::deserialize::<Cortex>(cortex_data) {
Ok(restored_cortex) => {
tracing::info!("🧠 Cortex restored (mood: {:.2})", restored_cortex.mood());
self.cortex = restored_cortex;
}
Err(e) => {
tracing::warn!("⚠️ Failed to restore Cortex: {}, using default", e);
}
}
}
tracing::info!(
"📇 Index rebuild deferred (lineages: {})",
self.psyche.len()
);
tracing::info!(
"✅ Resurrection complete: {} lineages, {} bonds",
self.psyche.len(),
self.bonds.len()
);
Ok(true)
}
#[cfg(feature = "server")]
pub fn sync_index_insert(&self, key: &str, id: LineageId) {
if let Some(ref store) = self.store {
if let Err(e) = store.indexer().insert(key, id) {
tracing::warn!("Failed to index lineage '{}': {}", key, e);
}
}
}
#[cfg(feature = "server")]
pub fn sync_index_remove(&self, key: &str) {
if let Some(ref store) = self.store {
if let Err(e) = store.indexer().remove(key) {
tracing::warn!("Failed to remove lineage '{}' from index: {}", key, e);
}
}
}
}
impl Default for MindFry {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct MindFryConfig {
pub max_lineages: usize,
pub max_bonds: usize,
pub strata_depth: usize,
pub decay: DecayConfig,
}
impl Default for MindFryConfig {
fn default() -> Self {
Self {
max_lineages: DEFAULT_MAX_LINEAGES,
max_bonds: DEFAULT_MAX_BONDS,
strata_depth: DEFAULT_STRATA_DEPTH,
decay: DecayConfig::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_mindfry() {
let db = MindFry::new();
assert_eq!(db.psyche.len(), 0);
assert_eq!(db.bonds.len(), 0);
}
}