2026-04-09 20:07:05 -04:00
|
|
|
// daemon.rs — graph health metrics
|
2026-03-05 13:18:00 -05:00
|
|
|
//
|
2026-04-09 20:07:05 -04:00
|
|
|
// Compute graph health statistics for the TUI (F4 hippocampus screen).
|
|
|
|
|
// The background daemon and RPC infrastructure have been removed;
|
|
|
|
|
// graph maintenance agents now run within the consciousness binary.
|
2026-03-21 11:33:36 -04:00
|
|
|
|
2026-04-09 20:07:05 -04:00
|
|
|
/// Graph health snapshot for the hippocampus TUI screen.
|
|
|
|
|
#[derive(Clone, Default, serde::Serialize, serde::Deserialize)]
|
|
|
|
|
pub struct GraphHealth {
|
|
|
|
|
pub nodes: usize,
|
|
|
|
|
pub edges: usize,
|
|
|
|
|
pub communities: usize,
|
|
|
|
|
pub alpha: f32, // power-law exponent (target ≥2.5)
|
|
|
|
|
pub gini: f32, // degree inequality (target ≤0.4)
|
|
|
|
|
pub avg_cc: f32, // clustering coefficient (target ≥0.2)
|
|
|
|
|
pub sigma: f32, // small-world sigma
|
|
|
|
|
pub episodic_ratio: f32, // episodic/total nodes (target <0.4)
|
|
|
|
|
pub interference: usize, // interfering pairs (target <50)
|
|
|
|
|
// Consolidation work estimate from plan
|
2026-03-21 11:33:36 -04:00
|
|
|
#[serde(default)]
|
2026-04-09 20:07:05 -04:00
|
|
|
pub plan_counts: std::collections::HashMap<String, usize>,
|
|
|
|
|
pub plan_rationale: Vec<String>,
|
|
|
|
|
pub computed_at: String,
|
2026-03-05 13:18:00 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-09 00:45:26 -04:00
|
|
|
pub fn compute_graph_health(store: &crate::store::Store) -> GraphHealth {
|
2026-03-09 17:02:01 -04:00
|
|
|
let graph = store.build_graph();
|
|
|
|
|
let snap = crate::graph::current_metrics(&graph);
|
|
|
|
|
|
|
|
|
|
let episodic_count = store.nodes.iter()
|
|
|
|
|
.filter(|(_, n)| matches!(n.node_type, crate::store::NodeType::EpisodicSession))
|
|
|
|
|
.count();
|
|
|
|
|
let episodic_ratio = if store.nodes.is_empty() { 0.0 }
|
|
|
|
|
else { episodic_count as f32 / store.nodes.len() as f32 };
|
|
|
|
|
|
2026-03-10 17:55:08 -04:00
|
|
|
// Use the same planning logic as consolidation (skip O(n²) interference)
|
|
|
|
|
let plan = crate::neuro::consolidation_plan_quick(store);
|
2026-03-09 17:02:01 -04:00
|
|
|
|
|
|
|
|
GraphHealth {
|
|
|
|
|
nodes: snap.nodes,
|
|
|
|
|
edges: snap.edges,
|
|
|
|
|
communities: snap.communities,
|
|
|
|
|
alpha: snap.alpha,
|
|
|
|
|
gini: snap.gini,
|
|
|
|
|
avg_cc: snap.avg_cc,
|
|
|
|
|
sigma: snap.sigma,
|
|
|
|
|
episodic_ratio,
|
2026-03-10 17:55:08 -04:00
|
|
|
interference: 0,
|
consolidation: data-driven agent plan, drop transfer/connector/replay
Replace per-field ConsolidationPlan struct with HashMap<String, usize>
counts map. Agent types are no longer hardcoded in the struct — add
agents by adding entries to the map.
Active agents: linker, organize, distill, separator, split.
Removed: transfer (redundant with distill), connector (rethink later),
replay (not needed for current graph work).
Elo-based budget allocation now iterates the map instead of indexing
a fixed array. Status display and TUI adapted to show dynamic agent
lists.
memory-instructions-core v13: added protected nodes section — agents
must not rewrite core-personality, core-personality-detail, or
memory-instructions-core. They may add links but not modify content.
High-value neighbors should be treated with care.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:02:28 -04:00
|
|
|
plan_counts: plan.counts,
|
2026-03-10 17:55:08 -04:00
|
|
|
plan_rationale: plan.rationale,
|
2026-03-09 17:02:01 -04:00
|
|
|
computed_at: crate::store::format_datetime_space(crate::store::now_epoch()),
|
|
|
|
|
}
|
|
|
|
|
}
|