split capnp_store.rs into src/store/ module hierarchy

capnp_store.rs (1772 lines) → four focused modules:
  store/types.rs  — types, macros, constants, path helpers
  store/parse.rs  — markdown parsing (MemoryUnit, parse_units)
  store/view.rs   — StoreView trait, MmapView, AnyView
  store/mod.rs    — Store impl methods, re-exports

new_node/new_relation become free functions in types.rs.
All callers updated: capnp_store:: → store::
This commit is contained in:
ProofOfConcept 2026-03-03 12:56:15 -05:00
parent e34c0ccf4c
commit 635da6d3e2
11 changed files with 980 additions and 978 deletions

View file

@ -13,7 +13,7 @@
// Neuroscience-inspired: spaced repetition replay, emotional gating,
// interference detection, schema assimilation, reconsolidation.
mod capnp_store;
mod store;
mod digest;
mod graph;
mod search;
@ -201,14 +201,14 @@ Commands:
}
fn cmd_search(args: &[String]) -> Result<(), String> {
use capnp_store::StoreView;
use store::StoreView;
if args.is_empty() {
return Err("Usage: poc-memory search QUERY [QUERY...]".into());
}
let query = args.join(" ");
let view = capnp_store::AnyView::load()?;
let view = store::AnyView::load()?;
let results = search::search(&query, &view);
if results.is_empty() {
@ -217,7 +217,7 @@ fn cmd_search(args: &[String]) -> Result<(), String> {
}
// Log retrieval to a small append-only file (avoid 6MB state.bin rewrite)
capnp_store::Store::log_retrieval_static(&query,
store::Store::log_retrieval_static(&query,
&results.iter().map(|r| r.key.clone()).collect::<Vec<_>>());
// Show text results
@ -275,7 +275,7 @@ fn cmd_search(args: &[String]) -> Result<(), String> {
}
fn cmd_init() -> Result<(), String> {
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let count = store.init_from_markdown()?;
store.save()?;
println!("Indexed {} memory units", count);
@ -287,7 +287,7 @@ fn cmd_migrate() -> Result<(), String> {
}
fn cmd_health() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = store.build_graph();
let health = graph::health_report(&g, &store);
println!("{}", health);
@ -295,7 +295,7 @@ fn cmd_health() -> Result<(), String> {
}
fn cmd_status() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let node_count = store.nodes.len();
let rel_count = store.relations.len();
let categories = store.category_counts();
@ -316,7 +316,7 @@ fn cmd_status() -> Result<(), String> {
}
fn cmd_graph() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = store.build_graph();
println!("Top nodes by degree:");
query::run_query(&store, &g,
@ -328,7 +328,7 @@ fn cmd_used(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory used KEY".into());
}
let key = args.join(" ");
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let resolved = store.resolve_key(&key)?;
store.mark_used(&resolved);
store.save()?;
@ -342,7 +342,7 @@ fn cmd_wrong(args: &[String]) -> Result<(), String> {
}
let key = &args[0];
let ctx = if args.len() > 1 { Some(args[1..].join(" ")) } else { None };
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let resolved = store.resolve_key(key)?;
store.mark_wrong(&resolved, ctx.as_deref());
store.save()?;
@ -355,7 +355,7 @@ fn cmd_gap(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory gap DESCRIPTION".into());
}
let desc = args.join(" ");
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
store.record_gap(&desc);
store.save()?;
println!("Recorded gap: {}", desc);
@ -368,7 +368,7 @@ fn cmd_categorize(args: &[String]) -> Result<(), String> {
}
let key = &args[0];
let cat = &args[1];
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let resolved = store.resolve_key(key)?;
store.categorize(&resolved, cat)?;
store.save()?;
@ -377,7 +377,7 @@ fn cmd_categorize(args: &[String]) -> Result<(), String> {
}
fn cmd_fix_categories() -> Result<(), String> {
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let before = format!("{:?}", store.category_counts());
let (changed, kept) = store.fix_categories()?;
store.save()?;
@ -392,7 +392,7 @@ fn cmd_link_orphans(args: &[String]) -> Result<(), String> {
let min_deg: usize = args.first().and_then(|s| s.parse().ok()).unwrap_or(2);
let links_per: usize = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(3);
let sim_thresh: f32 = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(0.15);
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let (orphans, links) = neuro::link_orphans(&mut store, min_deg, links_per, sim_thresh);
println!("Linked {} orphans, added {} connections (min_degree={}, links_per={}, sim>{})",
orphans, links, min_deg, links_per, sim_thresh);
@ -401,7 +401,7 @@ fn cmd_link_orphans(args: &[String]) -> Result<(), String> {
fn cmd_cap_degree(args: &[String]) -> Result<(), String> {
let max_deg: usize = args.first().and_then(|s| s.parse().ok()).unwrap_or(50);
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let (hubs, pruned) = store.cap_degree(max_deg)?;
store.save()?;
println!("Capped {} hubs, pruned {} weak Auto edges (max_degree={})", hubs, pruned, max_deg);
@ -409,7 +409,7 @@ fn cmd_cap_degree(args: &[String]) -> Result<(), String> {
}
fn cmd_decay() -> Result<(), String> {
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let (decayed, pruned) = store.decay();
store.save()?;
println!("Decayed {} nodes, pruned {} below threshold", decayed, pruned);
@ -436,7 +436,7 @@ fn cmd_consolidate_batch(args: &[String]) -> Result<(), String> {
}
}
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
if let Some(agent_name) = agent {
// Generate a specific agent prompt
@ -449,7 +449,7 @@ fn cmd_consolidate_batch(args: &[String]) -> Result<(), String> {
}
fn cmd_log() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
for event in store.retrieval_log.iter().rev().take(20) {
println!("[{}] q=\"{}\"{} results",
event.timestamp, event.query, event.results.len());
@ -461,7 +461,7 @@ fn cmd_log() -> Result<(), String> {
}
fn cmd_params() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
println!("decay_factor: {}", store.params.decay_factor);
println!("use_boost: {}", store.params.use_boost);
println!("prune_threshold: {}", store.params.prune_threshold);
@ -476,7 +476,7 @@ fn cmd_link(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory link KEY".into());
}
let key = args.join(" ");
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let resolved = store.resolve_key(&key)?;
let g = store.build_graph();
println!("Neighbors of '{}':", resolved);
@ -496,7 +496,7 @@ fn cmd_replay_queue(args: &[String]) -> Result<(), String> {
_ => { i += 1; }
}
}
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let queue = neuro::replay_queue(&store, count);
println!("Replay queue ({} items):", queue.len());
for (i, item) in queue.iter().enumerate() {
@ -508,14 +508,14 @@ fn cmd_replay_queue(args: &[String]) -> Result<(), String> {
}
fn cmd_consolidate_session() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let plan = neuro::consolidation_plan(&store);
println!("{}", neuro::format_plan(&plan));
Ok(())
}
fn cmd_consolidate_full() -> Result<(), String> {
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
digest::consolidate_full(&mut store)
}
@ -533,14 +533,14 @@ fn cmd_triangle_close(args: &[String]) -> Result<(), String> {
println!("Triangle closure: min_degree={}, sim_threshold={}, max_per_hub={}",
min_degree, sim_threshold, max_per_hub);
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let (hubs, added) = neuro::triangle_close(&mut store, min_degree, sim_threshold, max_per_hub);
println!("\nProcessed {} hubs, added {} lateral links", hubs, added);
Ok(())
}
fn cmd_daily_check() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let report = neuro::daily_check(&store);
print!("{}", report);
Ok(())
@ -550,7 +550,7 @@ fn cmd_link_add(args: &[String]) -> Result<(), String> {
if args.len() < 2 {
return Err("Usage: poc-memory link-add SOURCE TARGET [REASON]".into());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let source = store.resolve_key(&args[0])?;
let target = store.resolve_key(&args[1])?;
let reason = if args.len() > 2 { args[2..].join(" ") } else { String::new() };
@ -577,9 +577,9 @@ fn cmd_link_add(args: &[String]) -> Result<(), String> {
return Ok(());
}
let rel = capnp_store::Store::new_relation(
let rel = store::new_relation(
source_uuid, target_uuid,
capnp_store::RelationType::Auto,
store::RelationType::Auto,
0.5,
&source, &target,
);
@ -596,7 +596,7 @@ fn cmd_link_impact(args: &[String]) -> Result<(), String> {
if args.len() < 2 {
return Err("Usage: poc-memory link-impact SOURCE TARGET".into());
}
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let source = store.resolve_key(&args[0])?;
let target = store.resolve_key(&args[1])?;
let g = store.build_graph();
@ -622,7 +622,7 @@ fn cmd_apply_agent(args: &[String]) -> Result<(), String> {
return Ok(());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let mut applied = 0;
let mut errors = 0;
@ -718,9 +718,9 @@ fn cmd_apply_agent(args: &[String]) -> Result<(), String> {
None => continue,
};
let rel = capnp_store::Store::new_relation(
let rel = store::new_relation(
source_uuid, target_uuid,
capnp_store::RelationType::Link,
store::RelationType::Link,
0.5,
&source_key, &resolved,
);
@ -757,13 +757,13 @@ fn cmd_digest(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory digest daily|weekly|monthly|auto [DATE]".into());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let date_arg = args.get(1).map(|s| s.as_str()).unwrap_or("");
match args[0].as_str() {
"daily" => {
let date = if date_arg.is_empty() {
capnp_store::format_date(capnp_store::now_epoch())
store::format_date(store::now_epoch())
} else {
date_arg.to_string()
};
@ -771,7 +771,7 @@ fn cmd_digest(args: &[String]) -> Result<(), String> {
}
"weekly" => {
let date = if date_arg.is_empty() {
capnp_store::format_date(capnp_store::now_epoch())
store::format_date(store::now_epoch())
} else {
date_arg.to_string()
};
@ -803,7 +803,7 @@ fn cmd_digest_links(args: &[String]) -> Result<(), String> {
return Ok(());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let (applied, skipped, fallbacks) = digest::apply_digest_links(&mut store, &links);
println!("\nApplied: {} ({} file-level fallbacks) Skipped: {}", applied, fallbacks, skipped);
Ok(())
@ -823,7 +823,7 @@ fn cmd_journal_enrich(args: &[String]) -> Result<(), String> {
return Err(format!("JSONL not found: {}", jsonl_path));
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
digest::journal_enrich(&mut store, jsonl_path, entry_text, grep_line)
}
@ -839,7 +839,7 @@ fn cmd_experience_mine(args: &[String]) -> Result<(), String> {
return Err(format!("JSONL not found: {}", jsonl_path));
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let count = digest::experience_mine(&mut store, &jsonl_path)?;
println!("Done: {} new entries mined.", count);
Ok(())
@ -851,7 +851,7 @@ fn cmd_apply_consolidation(args: &[String]) -> Result<(), String> {
.find(|w| w[0] == "--report")
.map(|w| w[1].as_str());
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
digest::apply_consolidation(&mut store, do_apply, report_file)
}
@ -861,7 +861,7 @@ fn cmd_differentiate(args: &[String]) -> Result<(), String> {
.find(|a| !a.starts_with("--"))
.map(|s| s.as_str());
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
if let Some(key) = key_arg {
// Differentiate a specific hub
@ -918,7 +918,7 @@ fn cmd_differentiate(args: &[String]) -> Result<(), String> {
fn cmd_link_audit(args: &[String]) -> Result<(), String> {
let apply = args.iter().any(|a| a == "--apply");
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let stats = digest::link_audit(&mut store, apply)?;
println!("\n{}", "=".repeat(60));
println!("Link audit complete:");
@ -933,7 +933,7 @@ fn cmd_trace(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory trace KEY".into());
}
let key = args.join(" ");
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let resolved = store.resolve_key(&key)?;
let g = store.build_graph();
@ -968,13 +968,13 @@ fn cmd_trace(args: &[String]) -> Result<(), String> {
if let Some(nnode) = store.nodes.get(n.as_str()) {
let entry = (n.as_str(), *strength, nnode);
match nnode.node_type {
capnp_store::NodeType::EpisodicSession =>
store::NodeType::EpisodicSession =>
episodic_session.push(entry),
capnp_store::NodeType::EpisodicDaily =>
store::NodeType::EpisodicDaily =>
episodic_daily.push(entry),
capnp_store::NodeType::EpisodicWeekly =>
store::NodeType::EpisodicWeekly =>
episodic_weekly.push(entry),
capnp_store::NodeType::Semantic =>
store::NodeType::Semantic =>
semantic.push(entry),
}
}
@ -1029,7 +1029,7 @@ fn cmd_spectral(args: &[String]) -> Result<(), String> {
let k: usize = args.first()
.and_then(|s| s.parse().ok())
.unwrap_or(30);
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = graph::build_graph(&store);
let result = spectral::decompose(&g, k);
spectral::print_summary(&result, &g);
@ -1040,7 +1040,7 @@ fn cmd_spectral_save(args: &[String]) -> Result<(), String> {
let k: usize = args.first()
.and_then(|s| s.parse().ok())
.unwrap_or(20);
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = graph::build_graph(&store);
let result = spectral::decompose(&g, k);
let emb = spectral::to_embedding(&result);
@ -1080,7 +1080,7 @@ fn cmd_spectral_positions(args: &[String]) -> Result<(), String> {
.and_then(|s| s.parse().ok())
.unwrap_or(30);
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let emb = spectral::load_embedding()?;
// Build communities fresh from graph (don't rely on cached node fields)
@ -1135,7 +1135,7 @@ fn cmd_spectral_suggest(args: &[String]) -> Result<(), String> {
.and_then(|s| s.parse().ok())
.unwrap_or(20);
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let emb = spectral::load_embedding()?;
let g = store.build_graph();
let communities = g.communities();
@ -1186,13 +1186,13 @@ fn cmd_spectral_suggest(args: &[String]) -> Result<(), String> {
}
fn cmd_list_keys() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = store.build_graph();
query::run_query(&store, &g, "* | sort key asc")
}
fn cmd_list_edges() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
for rel in &store.relations {
println!("{}\t{}\t{:.2}\t{:?}",
rel.source_key, rel.target_key, rel.strength, rel.rel_type);
@ -1201,7 +1201,7 @@ fn cmd_list_edges() -> Result<(), String> {
}
fn cmd_dump_json() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let json = serde_json::to_string_pretty(&store)
.map_err(|e| format!("serialize: {}", e))?;
println!("{}", json);
@ -1213,7 +1213,7 @@ fn cmd_node_delete(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory node-delete KEY".into());
}
let key = args.join(" ");
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let resolved = store.resolve_key(&key)?;
store.delete_node(&resolved)?;
store.save()?;
@ -1222,8 +1222,8 @@ fn cmd_node_delete(args: &[String]) -> Result<(), String> {
}
fn cmd_load_context() -> Result<(), String> {
let store = capnp_store::Store::load()?;
let now = capnp_store::now_epoch();
let store = store::Store::load()?;
let now = store::now_epoch();
let seven_days = 7.0 * 24.0 * 3600.0;
println!("=== FULL MEMORY LOAD (session start) ===");
@ -1268,7 +1268,7 @@ fn cmd_load_context() -> Result<(), String> {
// Parse date from key: journal.md#j-2026-02-21-17-45-...
// Cutoff = today minus 7 days as YYYY-MM-DD string for lexicographic compare
let cutoff_secs = now - seven_days;
let cutoff_date = capnp_store::format_date(cutoff_secs);
let cutoff_date = store::format_date(cutoff_secs);
let date_re = regex::Regex::new(r"^journal\.md#j-(\d{4}-\d{2}-\d{2})").unwrap();
let mut journal_nodes: Vec<_> = store.nodes.values()
@ -1306,7 +1306,7 @@ fn cmd_render(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory render KEY".into());
}
let key = args.join(" ");
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let resolved = store.resolve_key(&key)?;
let node = store.nodes.get(&resolved)
@ -1330,7 +1330,7 @@ fn cmd_write(args: &[String]) -> Result<(), String> {
return Err("No content on stdin".into());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let result = store.upsert(&key, &content)?;
match result {
"unchanged" => println!("No change: '{}'", key),
@ -1348,7 +1348,7 @@ fn cmd_import(args: &[String]) -> Result<(), String> {
return Err("Usage: poc-memory import FILE [FILE...]".into());
}
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let mut total_new = 0;
let mut total_updated = 0;
@ -1357,7 +1357,7 @@ fn cmd_import(args: &[String]) -> Result<(), String> {
let resolved = if path.exists() {
path
} else {
let mem_path = capnp_store::memory_dir().join(arg);
let mem_path = store::memory_dir().join(arg);
if !mem_path.exists() {
eprintln!("File not found: {}", arg);
continue;
@ -1377,7 +1377,7 @@ fn cmd_import(args: &[String]) -> Result<(), String> {
}
fn cmd_export(args: &[String]) -> Result<(), String> {
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let export_all = args.iter().any(|a| a == "--all");
let targets: Vec<String> = if export_all {
@ -1401,7 +1401,7 @@ fn cmd_export(args: &[String]) -> Result<(), String> {
}).collect()
};
let mem_dir = capnp_store::memory_dir();
let mem_dir = store::memory_dir();
for file_key in &targets {
match store.export_to_markdown(file_key) {
@ -1426,7 +1426,7 @@ fn cmd_journal_write(args: &[String]) -> Result<(), String> {
let text = args.join(" ");
// Generate timestamp and slug
let timestamp = capnp_store::format_datetime(capnp_store::now_epoch());
let timestamp = store::format_datetime(store::now_epoch());
// Slug: lowercase first ~6 words, hyphenated, truncated
let slug: String = text.split_whitespace()
@ -1446,11 +1446,11 @@ fn cmd_journal_write(args: &[String]) -> Result<(), String> {
// Find source ref (most recently modified .jsonl transcript)
let source_ref = find_current_transcript();
let mut store = capnp_store::Store::load()?;
let mut store = store::Store::load()?;
let mut node = capnp_store::Store::new_node(&key, &content);
node.node_type = capnp_store::NodeType::EpisodicSession;
node.provenance = capnp_store::Provenance::Journal;
let mut node = store::new_node(&key, &content);
node.node_type = store::NodeType::EpisodicSession;
node.provenance = store::Provenance::Journal;
if let Some(src) = source_ref {
node.source_ref = src;
}
@ -1475,7 +1475,7 @@ fn cmd_journal_tail(args: &[String]) -> Result<(), String> {
}
}
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
// Collect journal nodes, sorted by date extracted from content or key
let date_re = regex::Regex::new(r"(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2})").unwrap();
@ -1493,7 +1493,7 @@ fn cmd_journal_tail(args: &[String]) -> Result<(), String> {
s
}
};
let extract_sort_key = |node: &capnp_store::Node| -> String {
let extract_sort_key = |node: &store::Node| -> String {
// Try key first (journal.md#j-2026-02-28t23-11-...)
if let Some(caps) = key_date_re.captures(&node.key) {
return normalize_date(&caps[1]);
@ -1565,7 +1565,7 @@ fn cmd_interference(args: &[String]) -> Result<(), String> {
_ => { i += 1; }
}
}
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let g = store.build_graph();
let pairs = neuro::detect_interference(&store, &g, threshold);
@ -1597,7 +1597,7 @@ Pipe stages:\n \
}
let query_str = args.join(" ");
let store = capnp_store::Store::load()?;
let store = store::Store::load()?;
let graph = store.build_graph();
query::run_query(&store, &graph, &query_str)
}