Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

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));
    }
}