src/mimir_lens/room_feed/graph_first_tests.rs
//! **Graph first, embeddings beside it** — every vector lens answers from the
//! compiled graph on its own (complete, no embeddings table needed), and the
//! embedding index, when it has vectors, ADDS its pairs beside the graph's.
//! Every finding says which index found it: `graph`, `embedding` or `both`.
//!
//! Per lens, three facts over the fixtures:
//! 1. with NO embeddings the lens is `complete` and finds the structural clone
//! from the graph (`source: "graph"`), and the note says the embedding
//! index added nothing;
//! 2. with vectors, a candidate only the embedding index finds is added
//! (`source: "embedding"`, with its cosine);
//! 3. a pair both indexes find is marked `both`.
use serde_json::{Value, json};
use super::fixture::{self, clones as cx, vectors as vx};
fn state(v: &Value) -> &str {
v["lens_meta"]["state"].as_str().unwrap_or_else(|| panic!("no lens_meta.state: {v}"))
}
fn note(v: &Value) -> &str {
v["evidence_note"].as_str().unwrap_or("")
}
/// Every function id one finding names.
fn ids(item: &Value) -> Vec<String> {
fn walk(v: &Value, out: &mut Vec<String>) {
match v {
Value::Object(m) => {
if let Some(Value::String(id)) = m.get("id") {
out.push(id.clone());
}
m.values().for_each(|x| walk(x, out));
}
Value::Array(a) => a.iter().for_each(|x| walk(x, out)),
_ => {}
}
}
let mut out = Vec::new();
walk(item, &mut out);
out
}
/// The findings of `v` (its `worst` list) that name every id of `want`.
fn naming<'a>(v: &'a Value, want: &[String]) -> Vec<&'a Value> {
v["worst"].as_array().unwrap_or_else(|| panic!("no worst: {v}")).iter().filter(|f| want.iter().all(|w| ids(f).iter().any(|i| i == w))).collect()
}
/// The stable id of a `clo` fixture function.
fn clo(name: &str) -> String {
mimir_schema::moniker::stable(&cx::clo(&format!("{name}()."))).into_owned()
}
fn clo2(a: &str, b: &str) -> Vec<String> {
vec![clo(a), clo(b)]
}
/// The three copies of `parse_header` (two repos, three crates), by the ids
/// `similar_code` answers with (its v1 cluster members keep the full moniker).
fn parse_headers() -> Vec<String> {
vec![vx::alpha("parse_header()."), vx::beta("http/parse_header()."), vx::gamma("parse_header().")]
}
fn sources(v: &Value) -> Vec<String> {
v["worst"].as_array().map(|w| w.iter().map(|f| f["source"].as_str().unwrap_or("?").to_string()).collect()).unwrap_or_default()
}
/// The answer says how many findings each index holds.
fn assert_index_counts(lens: &str, v: &Value) {
let ix = &v["indexes"];
assert!(ix["graph"].is_u64() && ix["embedding"].is_u64() && ix["both"].is_u64(), "{lens}: no per-index count: {v}");
let feeds = v["feeds"].to_string();
assert!(feeds.contains("graph index") && feeds.contains("embedding index"), "{lens}: the basis names both indexes: {feeds}");
}
/// The graph answered alone: complete, nothing missing, the note says so.
fn assert_graph_alone(lens: &str, v: &Value) {
assert!(matches!(state(v), "complete" | "empty_fact"), "{lens}: the graph alone is a complete answer: {v}");
assert!(note(v).contains("the embedding index added nothing"), "{lens}: the note says the embedding index added nothing: {}", note(v));
assert!(!note(v).contains("MISSING"), "{lens}: no embedding is not a gap: {}", note(v));
for s in sources(v) {
assert_eq!(s, "graph", "{lens}: with no vectors every finding is the graph's: {v}");
}
assert_eq!(v["indexes"]["embedding"], 0, "{lens}: {v}");
assert_eq!(v["indexes"]["both"], 0, "{lens}: {v}");
}
// ── similar_code ────────────────────────────────────────────────────────────
#[test]
fn similar_code_answers_from_the_graph_with_no_embeddings() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = vx::build();
let v = f.ws.ask("similar_code", json!({}));
assert_graph_alone("similar_code", &v);
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("similar_code", &v);
let hit = naming(&v, &parse_headers());
assert_eq!(hit.len(), 1, "the copy in three crates is found from the graph: {v}");
assert_eq!(hit[0]["source"], "graph", "{}", hit[0]);
assert!(hit[0].get("avg_cosine").is_none(), "a graph-only finding carries no cosine: {}", hit[0]);
assert!(hit[0]["graph_score"].as_f64().is_some_and(|s| s >= 0.5), "{}", hit[0]);
// the shared lines (one source compiled into two crates) stay refused
assert!(!v["worst"].to_string().contains("clamp"), "{v}");
assert_eq!(v["vectors"]["with_vector"], 0, "{}", v["vectors"]);
}
#[test]
fn similar_code_adds_the_embedding_pairs_beside_the_graph_and_marks_both() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = vx::build();
let bag = vx::Bag::default();
f.embed(vx::MONO, &bag);
f.embed(vx::OTHER, &bag);
let v = f.ws.ask("similar_code", json!({ "keep_trait_impls": true }));
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("similar_code", &v);
let hit = naming(&v, &parse_headers());
assert_eq!(hit.len(), 1, "{v}");
assert_eq!(hit[0]["source"], "both", "both indexes find the parse_header copies: {}", hit[0]);
assert!(hit[0]["avg_cosine"].as_f64().unwrap() > 0.999, "{}", hit[0]);
// `<Reader as Default>::default` / `<Writer as Default>::default`: one
// feature each (`call new`) — too little structure for the graph, the
// same text for the model
let defaults = vec![vx::alpha("impl#[Reader][Default]default()."), vx::beta("impl#[Writer][Default]default().")];
let emb = naming(&v, &defaults);
assert_eq!(emb.len(), 1, "{v}");
assert_eq!(emb[0]["source"], "embedding", "{}", emb[0]);
assert!(emb[0]["avg_cosine"].as_f64().is_some(), "an embedding finding carries its cosine: {}", emb[0]);
assert!((v["indexes"]["embedding"].as_u64().unwrap(), v["indexes"]["both"].as_u64().unwrap()) >= (1, 1), "{}", v["indexes"]);
}
// ── same_intent ─────────────────────────────────────────────────────────────
#[test]
fn same_intent_answers_from_the_graph_names_with_no_embeddings() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
let v = f.ws.ask("same_intent", json!({ "limit": 500 }));
assert_graph_alone("same_intent", &v);
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("same_intent", &v);
assert_eq!(v["name_driven"], true);
// `bump_alpha` / `bump_beta`: their names say the same, their structure does not
let hit = naming(&v, &clo2("bump_alpha", "bump_beta"));
assert_eq!(hit.len(), 1, "{v}");
assert_eq!(hit[0]["source"], "graph", "{}", hit[0]);
assert!(hit[0]["found_by"].to_string().contains("NAME-DRIVEN"), "{}", hit[0]);
assert!(naming(&v, &clo2("kill", "delete")).is_empty(), "{v}");
}
#[test]
fn same_intent_adds_the_embedding_clusters_beside_the_graph_and_marks_both() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
f.embed(&super::fixture::vectors::Bag::default());
// the Bag is no language model: the floor is lowered to test the shape
let v = f.ws.ask("same_intent", json!({ "cosine": 0.65, "limit": 500 }));
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("same_intent", &v);
let s = sources(&v);
assert!(s.iter().any(|x| x == "embedding"), "an embedding-only cluster is added: {s:?} {v}");
assert!(s.iter().any(|x| x == "both"), "a cluster both find is marked both: {s:?} {v}");
for w in v["worst"].as_array().unwrap() {
if w["source"] == "graph" {
assert!(w.get("avg_cosine").is_none() || w["avg_cosine"].as_f64().is_some(), "{w}");
} else {
assert!(w["avg_cosine"].as_f64().is_some(), "an embedding finding carries its cosine: {w}");
}
}
}
// ── semantic_clones ─────────────────────────────────────────────────────────
#[test]
fn semantic_clones_answers_from_the_graph_with_no_embeddings() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
let v = f.ws.ask("semantic_clones", json!({ "limit": 500 }));
assert_graph_alone("semantic_clones", &v);
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("semantic_clones", &v);
// the renamed copy (one normalised body) and the structural pair
let hit = naming(&v, &clo2("tally", "summarize"));
assert!(!hit.is_empty(), "{v}");
assert_eq!(hit[0]["source"], "graph", "{}", hit[0]);
assert!(hit[0].get("cosine_normalised").is_none(), "no cosine without vectors: {}", hit[0]);
let hit = naming(&v, &clo2("place", "arrange"));
assert_eq!(hit.len(), 1, "the structural pair is found from the graph: {v}");
assert!(hit[0]["found_by"].to_string().contains("structural"), "{}", hit[0]);
assert!(naming(&v, &clo2("kill", "delete")).is_empty(), "{v}");
}
#[test]
fn semantic_clones_adds_the_embedding_pairs_beside_the_graph_and_marks_both() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
f.embed(&super::fixture::vectors::Bag::default());
let v = f.ws.ask("semantic_clones", json!({ "cosine": 0.65, "limit": 500 }));
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("semantic_clones", &v);
let hit = naming(&v, &clo2("tally", "summarize"));
assert!(!hit.is_empty(), "{v}");
assert_eq!(hit[0]["source"], "both", "{}", hit[0]);
assert!(hit[0]["cosine_normalised"].as_f64().is_some(), "{}", hit[0]);
// `clo` is ONE crate: the model's own look-alikes are refused by the
// cross-crate gate (an embedding-only pair that passes is in
// `semantic_clones_adds_no_embedding_pair_of_families_…`)
assert!(v["embedding_refused"]["same crate"].as_u64().is_some_and(|n| n >= 1), "{}", v["embedding_refused"]);
assert!(!v["worst"].as_array().unwrap().iter().any(|w| w["source"] == "embedding"), "{v}");
}
// ── semantic_twins ──────────────────────────────────────────────────────────
#[test]
fn semantic_twins_answers_from_the_graph_with_no_embeddings() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
let v = f.ws.ask("semantic_twins", json!({ "limit": 500 }));
assert_graph_alone("semantic_twins", &v);
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("semantic_twins", &v);
// a near copy that touches the same things: a copy, from the graph and the bodies
let copy = naming(&v, &clo2("tally", "tally_more"));
assert_eq!(copy.len(), 1, "{v}");
assert_eq!((copy[0]["kind"].as_str(), copy[0]["source"].as_str()), (Some("copy"), Some("graph")), "{}", copy[0]);
assert!(copy[0].get("cosine").is_none(), "{}", copy[0]);
// the same rare inputs, outputs and fields, written differently: the
// graph's Type-4 — but in ONE file, which the owner's audit leaves out
assert!(naming(&v, &clo2("place", "arrange")).is_empty(), "{v}");
assert!(v["excluded"]["a twin pair within one file"].as_u64().is_some_and(|n| n >= 1), "{}", v["excluded"]);
// touching nothing in common, only the model can pair these
assert!(naming(&v, &clo2("workspace_root", "repo_root")).is_empty(), "{v}");
// the headline: pairs AND the groups they form (one helper copied five times is one group)
let (pairs, groups) = (v["pairs"].as_u64().expect("pairs"), v["groups"].as_u64().expect("groups"));
assert_eq!(pairs, v["twins"].as_u64().unwrap() + v["copies"].as_u64().unwrap(), "{v}");
assert!(groups >= 1 && groups <= pairs, "{v}");
assert!(note(&v).contains(&format!("{pairs} pair(s) in {groups} group(s)")), "{}", note(&v));
}
#[test]
fn semantic_twins_adds_the_embedding_pairs_beside_the_graph_and_marks_both() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
f.embed(&super::fixture::vectors::Bag::default());
let v = f.ws.ask("semantic_twins", json!({ "cosine": 0.65, "limit": 500 }));
assert_eq!(state(&v), "complete", "{v}");
assert_index_counts("semantic_twins", &v);
// the embedding index's twin sits in one file with its sibling: left out, counted
assert!(naming(&v, &clo2("workspace_root", "repo_root")).is_empty(), "{v}");
assert!(v["excluded"]["a twin pair within one file"].as_u64().is_some_and(|n| n >= 1), "{}", v["excluded"]);
let copy = naming(&v, &clo2("bump_alpha", "bump_beta"));
assert_eq!(copy.len(), 1, "{v}");
assert_eq!(copy[0]["source"], "embedding", "structure 0: only the model proposes it: {}", copy[0]);
let copy = naming(&v, &clo2("tally", "tally_more"));
assert_eq!(copy.len(), 1, "{v}");
assert_eq!(copy[0]["source"], "both", "{}", copy[0]);
assert!(copy[0]["cosine"].as_f64().is_some(), "{}", copy[0]);
}
// ── role_neighbours: graph-derived already ──────────────────────────────────
/// The role vectors are FastRP over the room graph (no model): the lens
/// answers complete with no embeddings at all.
#[test]
fn role_neighbours_needs_no_embeddings() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = cx::build();
f.shapes();
let v = f.ws.ask("role_neighbours", json!({}));
assert_eq!(state(&v), "complete", "{v}");
assert!(!naming(&v, &clo2("tally", "summarize")).is_empty(), "{v}");
}
// ── the instrument ──────────────────────────────────────────────────────────
/// **The graph-first probe** on a real lake (a COPY: the role and twin lenses
/// keep state in it): each vector lens asked twice in one process (cold, then
/// warm), printing its state, the per-index counts and the time. `#[ignore]`d.
///
/// ```text
/// LENS_DUMP_BUILDS=<copy>/builds cargo test --lib graph_first_probe -- --ignored --nocapture
/// ```
#[test]
#[ignore = "reads a real lake: set LENS_DUMP_BUILDS"]
fn graph_first_probe() {
let builds = std::path::PathBuf::from(std::env::var("LENS_DUMP_BUILDS").expect("LENS_DUMP_BUILDS"));
let wh = crate::warehouse::iceberg::IcebergWarehouse::open(&builds).unwrap();
let room = crate::code_room::CodeRoom::new("nordisk", &builds);
let reach = crate::code_room::Reach::new(&room, &wh);
let lenses = std::env::var("LENS_DUMP_LENSES").unwrap_or_else(|_| "similar_code,same_intent,semantic_clones,semantic_twins,role_neighbours".into());
for lens in lenses.split(',') {
for pass in ["cold", "warm"] {
let t = std::time::Instant::now();
let v = crate::mimir_lens::answer(lens, &reach, &json!({ "limit": 20 }));
let shown: Vec<String> = v["worst"].as_array().map(|w| w.iter().take(5).map(|f| format!("{}:{}", f["source"].as_str().unwrap_or("-"), f["kind"].as_str().unwrap_or(""))).collect()).unwrap_or_default();
eprintln!("PROBE {lens} {pass}: {} · {} ms · indexes {} · top {shown:?}", state(&v), t.elapsed().as_millis(), v["indexes"]);
if pass == "cold" {
let n = note(&v);
eprintln!("PROBE {lens} note: {}", &n[..n.len().min(1500)]);
}
}
}
}
// ── the embedding index's gates ─────────────────────────────────────────────
/// A pile of cosine-only look-alikes (the same statements in another order:
/// cosine 1 for the model, nothing in the graph) that are trait-impl
/// methods, constructors, tests, one-liners or inside one crate: the
/// embedding index adds NONE of them — its pairs pass the gates a graph pair
/// passes. Only `other` (crate trb) × a plain function of crate tra may be added.
#[test]
fn semantic_clones_adds_no_embedding_pair_of_families_tests_one_liners_or_one_crate() {
use super::fixture::trivial as tv;
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = tv::build();
f.shapes();
f.embed(&super::fixture::vectors::Bag::default());
// the Bag is no language model: the floor is lowered so that `other` (another
// body over the same calls) is a cosine candidate of the plain functions
let v = f.ws.ask("semantic_clones", json!({ "limit": 500, "cosine": 0.6 }));
assert_eq!(state(&v), "complete", "{v}");
let emb: Vec<&Value> = v["worst"].as_array().unwrap().iter().filter(|w| w["source"] == "embedding").collect();
let other = mimir_schema::moniker::stable(&tv::trb("other().")).into_owned();
let plains: Vec<String> = (0..4).map(|i| format!("plain{i}().")).chain(["mirror().".to_string()]).map(|d| mimir_schema::moniker::stable(&tv::tra(&d)).into_owned()).collect();
for w in &emb {
let got = ids(w);
assert!(got.contains(&other) && got.iter().any(|i| plains.contains(i)), "only the cross-crate plain pair may be embedding-only: {w}");
}
assert!((1..=5).contains(&emb.len()), "the cross-crate plain pair is added, nothing else: {} refused {}", v["worst"], v["embedding_refused"]);
assert!(v["embedding_refused"].is_object(), "the refusals are counted by reason: {v}");
let refused = v["embedding_refused"].to_string();
// test code never reaches the embedding gate now: the population marks it (test_like)
assert!(refused.contains("trait-impl") && refused.contains("constructor"), "{refused}");
}
/// A few functions without a shape (the room moved on before the shapes
/// feed ran) do not make the graph-first lenses partial:
/// the count is in the answer and the note, the state is complete.
#[test]
fn a_few_functions_without_a_shape_are_a_counted_note_not_partial() {
let _g = fixture::serial();
crate::mimir_lens::clone_inc::forget();
let f = vx::build();
for repo in [vx::MONO, vx::OTHER] {
let (seq, sha) = f.at(repo);
let log = f.ws.room.log().unwrap();
crate::clone_signals::feed::shapes_member(&f.ws.warehouse, &log, repo, &f.checkout(repo), seq, &sha).unwrap();
}
// the room moves on (`total`, `checksum` change, `fresh` is new) and the
// shapes feed has not run for it: three functions without a shape
f.second_commit();
for lens in ["semantic_clones", "semantic_twins"] {
let v = f.ws.ask(lens, json!({ "limit": 500 }));
assert!(matches!(state(&v), "complete" | "empty_fact"), "{lens}: {v}");
assert!(v["functions_without_shape"].as_u64().is_some_and(|n| n >= 1), "{lens}: the count is in the answer: {v}");
assert!(note(&v).contains("have no shape"), "{lens}: {}", note(&v));
}
}