use mentedb::MenteDb;
use mentedb::agent_file::{AgentFileIngestOptions, plan_agent_file};
use mentedb_embedding::hash_provider::HashEmbeddingProvider;
const CLAUDE_MD: &str = include_str!("../../../CLAUDE.md");
fn open(dir: &std::path::Path) -> MenteDb {
MenteDb::open_with_embedder(dir, Box::new(HashEmbeddingProvider::new(256))).expect("open")
}
#[test]
fn ingests_the_real_claude_md() {
let dir = tempfile::tempdir().unwrap();
let db = open(dir.path());
let opts = AgentFileIngestOptions::default();
let report = db.ingest_agent_file(CLAUDE_MD, &opts).unwrap();
assert!(
report.candidates >= 25,
"the real file must segment into atomic memories, got {}",
report.candidates
);
assert_eq!(
report.stored, report.candidates,
"first ingest into an empty store keeps everything"
);
assert!(
report.sections >= 4,
"section paths must nest: {}",
report.sections
);
assert_eq!(report.trigger_tagged, 0, "no false triggers under hash");
assert!(report.procedural > 0 && report.semantic > 0);
assert!(
report.file_token_estimate > report.avg_memory_token_estimate * 4,
"atoms must be much smaller than the file"
);
}
#[test]
fn no_false_triggers_under_a_non_semantic_embedder() {
let dir = tempfile::tempdir().unwrap();
let db = open(dir.path());
db.ingest_agent_file(CLAUDE_MD, &AgentFileIngestOptions::default())
.unwrap();
for action in ["git-commit", "pr-create", "git-push", "deploy"] {
let rules = db.recall_for_action(action, None, None, 8).unwrap();
assert!(
rules.is_empty(),
"hash embedder must never assign triggers, {action} fired: {:?}",
rules.iter().map(|r| &r.content).collect::<Vec<_>>()
);
}
}
#[test]
fn nothing_is_pinned_always() {
let atoms = plan_agent_file(CLAUDE_MD, &AgentFileIngestOptions::default());
assert!(!atoms.is_empty());
assert!(
atoms
.iter()
.all(|a| !a.tags.iter().any(|t| t == "scope:always")),
"agent file ingest must never pin to every turn"
);
}
#[test]
fn reingest_deduplicates_instead_of_duplicating() {
let dir = tempfile::tempdir().unwrap();
let db = open(dir.path());
let opts = AgentFileIngestOptions::default();
let first = db.ingest_agent_file(CLAUDE_MD, &opts).unwrap();
let second = db.ingest_agent_file(CLAUDE_MD, &opts).unwrap();
assert!(
second.stored < first.stored / 2,
"re ingesting the identical file must dedup, first {} second {}",
first.stored,
second.stored
);
assert_eq!(
second.deduplicated,
second.candidates - second.stored,
"report must account for every candidate"
);
}
#[test]
fn large_file_mechanics_hold() {
let mut big = String::from("# Playbook\n\n");
for section in 0..90 {
big.push_str(&format!("## Area {section}\n\n"));
big.push_str(
"The team reviews the dashboard each morning before standup and notes anything unusual. \
Long running migrations are announced in the channel a day ahead so nobody is surprised. \
Rollbacks are practiced monthly and the runbook stays in the repository next to the code. \
When an incident closes, the writeup lands within two days while details are fresh.\n\n",
);
for b in 0..6 {
big.push_str(&format!(
"- Area {section} guideline {b}: keep the change small and reviewed before it ships\n"
));
}
big.push('\n');
}
assert!(big.len() > 60_000, "fixture must be a genuinely large file");
let dir = tempfile::tempdir().unwrap();
let db = open(dir.path());
let opts = AgentFileIngestOptions::default();
let report = db.ingest_agent_file(&big, &opts).unwrap();
assert!(
report.candidates > 500,
"a large file must atomize widely, got {}",
report.candidates
);
assert!(report.sections >= 90);
let atoms = plan_agent_file(&big, &opts);
assert!(
atoms
.iter()
.all(|a| a.content.len() <= opts.max_content_chars),
"atom caps must hold"
);
assert_eq!(report.stored + report.deduplicated, report.candidates);
}