use mentedb::CognitiveConfig;
use mentedb::MenteDb;
use mentedb::injection::InjectionQuery;
use mentedb::prelude::*;
use mentedb::process_turn::ProcessTurnInput;
use mentedb_context::DeltaTracker;
use uuid::Uuid;
fn open_db() -> (MenteDb, tempfile::TempDir) {
let dir = tempfile::tempdir().unwrap();
let db = MenteDb::open_with_config(dir.path(), CognitiveConfig::default()).unwrap();
(db, dir)
}
fn vec_for(axis: usize) -> Vec<f32> {
let mut v = vec![0.1_f32; 8];
v[axis] = 1.0;
v
}
fn store_owned(db: &MenteDb, agent: AgentId, content: &str, topic: usize) -> MemoryId {
let node = MemoryNode::new(
agent,
MemoryType::Semantic,
content.to_string(),
vec_for(topic),
);
let id = node.id;
db.store(node).unwrap();
id
}
fn now_us() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_micros() as u64
}
#[test]
fn scoped_recall_isolates_agents() {
let (db, _dir) = open_db();
let coder = AgentId::new();
let researcher = AgentId::new();
let coder_mem = store_owned(&db, coder, "the payment service uses rust and axum", 0);
let researcher_mem = store_owned(
&db,
researcher,
"the survey paper covers rust memory models",
1,
);
let shared = store_owned(
&db,
AgentId::nil(),
"the team standup about rust happens at nine",
2,
);
let query = vec_for(0);
let hits = db
.recall_hybrid_scoped_at_mode(
&query,
Some("rust"),
10,
now_us(),
None,
false,
None,
Some(coder),
)
.unwrap();
let ids: Vec<MemoryId> = hits.iter().map(|(id, _)| *id).collect();
assert!(ids.contains(&coder_mem), "agent must see its own memory");
assert!(
ids.contains(&shared),
"agent must see shared nil owned memory"
);
assert!(
!ids.contains(&researcher_mem),
"agent must not see another agent's memory"
);
let hits = db
.recall_hybrid_scoped_at_mode(&query, Some("rust"), 10, now_us(), None, false, None, None)
.unwrap();
let ids: Vec<MemoryId> = hits.iter().map(|(id, _)| *id).collect();
assert!(ids.contains(&coder_mem));
assert!(ids.contains(&researcher_mem));
assert!(ids.contains(&shared));
}
#[test]
fn process_turn_context_is_agent_scoped() {
let (db, _dir) = open_db();
let mut delta = DeltaTracker::new();
let coder = Uuid::new_v4();
let researcher = Uuid::new_v4();
let input = ProcessTurnInput {
user_message: "our deployment pipeline uses blue green releases".to_string(),
assistant_response: Some("noted, blue green it is".to_string()),
turn_id: 0,
project_context: None,
agent_id: Some(coder),
session_id: None,
};
db.process_turn(&input, &mut delta).unwrap();
let input = ProcessTurnInput {
user_message: "what do we know about deployment pipelines".to_string(),
assistant_response: None,
turn_id: 1,
project_context: None,
agent_id: Some(researcher),
session_id: None,
};
let result = db.process_turn(&input, &mut delta).unwrap();
assert!(
result
.context
.iter()
.all(|c| !c.memory.content.contains("blue green")),
"another agent's turns must not leak into context"
);
let input = ProcessTurnInput {
user_message: "what do we know about deployment pipelines".to_string(),
assistant_response: None,
turn_id: 2,
project_context: None,
agent_id: None,
session_id: None,
};
let result = db.process_turn(&input, &mut delta).unwrap();
assert!(
result
.context
.iter()
.any(|c| c.memory.content.contains("blue green")),
"unscoped turns keep global visibility"
);
}
#[test]
fn injection_respects_agent_scope() {
let (db, _dir) = open_db();
let coder = AgentId::new();
let researcher = AgentId::new();
let emb = vec_for(3);
let mut theirs = MemoryNode::new(
researcher,
MemoryType::Procedural,
"researcher only: cite every claim".to_string(),
emb.clone(),
);
theirs.tags = vec!["scope:always".to_string()];
db.store(theirs).unwrap();
let mut shared = MemoryNode::new(
AgentId::nil(),
MemoryType::Procedural,
"everyone: never commit secrets".to_string(),
emb,
);
shared.tags = vec!["scope:always".to_string()];
db.store(shared).unwrap();
let query_emb = vec_for(3);
let selected = db
.recall_for_injection(&InjectionQuery {
embedding: &query_emb,
query_text: Some("what are the rules"),
session_id: None,
exclude_ids: &[],
max_items: 6,
max_episodic: 2,
agent_id: Some(coder),
})
.unwrap();
let contents: Vec<&str> = selected.iter().map(|c| c.node.content.as_str()).collect();
assert!(
contents.iter().any(|c| c.contains("never commit secrets")),
"shared pinned memories inject for every agent"
);
assert!(
!contents.iter().any(|c| c.contains("researcher only")),
"another agent's pinned memories must not inject"
);
}
#[test]
fn ghost_memories_never_inject() {
let (db, _dir) = open_db();
let mut ghost = MemoryNode::new(
AgentId::nil(),
MemoryType::Semantic,
"Unconfirmed: maybe we should rewrite everything in zig".to_string(),
vec_for(4),
);
ghost.tags = vec!["ghost-memory".to_string(), "unconfirmed".to_string()];
db.store(ghost).unwrap();
let real = store_owned(&db, AgentId::nil(), "the api uses axum", 4);
let selected = db
.recall_for_injection(&InjectionQuery {
embedding: &vec_for(4),
query_text: Some("what about the architecture"),
session_id: None,
exclude_ids: &[],
max_items: 6,
max_episodic: 2,
agent_id: None,
})
.unwrap();
let contents: Vec<&str> = selected.iter().map(|c| c.node.content.as_str()).collect();
assert!(
!contents.iter().any(|c| c.starts_with("Unconfirmed:")),
"speculative ghosts must not inject as knowledge"
);
assert!(
selected.iter().any(|c| c.node.id == real),
"real memories still inject"
);
}