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/fixture/vectors.rs

//! The fixture of the per-function vectors: real source text on disk, and a
//! scripted dump whose spans point at it — so a chunk is cut exactly as in
//! production (the room's span, the checkout's lines).
//!
//! ```text
//! repo `mono` — crates alpha@0.1.0 and beta@0.1.0
//!   alpha/src/lib.rs   Reader::new · Reader::total · <Reader as Default>::default
//!                      parse_header · checksum · width (written by `make_getter!`)
//!   beta/src/lib.rs    Writer::new · <Writer as Default>::default
//!                      http::parse_header   ← alpha's, byte for byte, one level deeper
//!   shared/util.rs     clamp — ONE file compiled into both crates: two nodes, the same lines
//! repo `other` — crate gamma@0.3.0
//!   src/lib.rs         parse_header (a third copy) · digest
//!   (target dir)       proto::decode — build-script output, outside the checkout
//! ring: kit@1.0.0      pad · trim (their source in a registry directory)
//! ```
//!
//! [`Vx::second_commit`]: `mono` seq 2 — a comment line on top of alpha's file
//! (every span below moves, no text changes), `total` and `checksum` get
//! another body, `fresh` is new; the ring gains kit@2.0.0.

use std::collections::BTreeSet;
use std::path::{Path, PathBuf};
use std::sync::Mutex;

use mimir_ingest::{CommitDump, Consumer, CrateDump, RepoSpec};
use mimir_schema::{EdgeKind, EdgeRow, Level, NodeRow, Origin, SpanRow, moniker};

use super::{N, Scripted, Workspace, e, n, span, unit};
use crate::code_room::CodeRoom;
use crate::vector::store::{Embedder, ModelProfile};
use crate::warehouse::iceberg::IcebergWarehouse;

pub const MONO: &str = "mono";
pub const OTHER: &str = "other";

pub fn alpha(d: &str) -> String {
    moniker::moniker("alpha", "0.1.0", d)
}
pub fn beta(d: &str) -> String {
    moniker::moniker("beta", "0.1.0", d)
}
pub fn gamma(d: &str) -> String {
    moniker::moniker("gamma", "0.3.0", d)
}
pub fn kit(version: &str, d: &str) -> String {
    moniker::moniker("kit", version, d)
}

/// A deterministic embedder: a bag of the text's identifier-like tokens,
/// hashed into 64 buckets. Identical text → identical vector; it records every
/// text it was asked for, so a test can count what was embedded.
#[derive(Default)]
pub struct Bag {
    pub asked: Mutex<Vec<String>>,
}

impl Bag {
    pub fn count(&self) -> usize {
        self.asked.lock().unwrap().len()
    }
}

impl Embedder for Bag {
    fn profile(&self) -> ModelProfile {
        ModelProfile { model_name: "test-bag".into(), weights_sha: "w".into(), tokenizer_sha: "t".into(), pooling: "sum".into(), normalize: true, dim: 64, dtype: "f32".into() }
    }

    fn embed(&self, texts: &[&str]) -> anyhow::Result<Vec<Vec<f32>>> {
        self.asked.lock().unwrap().extend(texts.iter().map(|t| t.to_string()));
        Ok(texts
            .iter()
            .map(|t| {
                let mut v = vec![0f32; 64];
                for tok in t.split(|c: char| !(c.is_alphanumeric() || c == '_')).filter(|s| !s.is_empty()) {
                    let h = tok.bytes().fold(0xcbf2_9ce4_8422_2325u64, |h, b| (h ^ b as u64).wrapping_mul(0x0100_0000_01b3));
                    v[(h % 64) as usize] += 1.0;
                }
                let norm = v.iter().map(|x| x * x).sum::<f32>().sqrt().max(f32::MIN_POSITIVE);
                v.iter().map(|x| x / norm).collect()
            })
            .collect())
    }
}

/// A source file being written: plain lines, and items whose extent is recorded.
#[derive(Default)]
pub(super) struct Source {
    lines: Vec<String>,
    /// `(node id, start, end)`.
    at: Vec<(String, u32, u32)>,
}

impl Source {
    pub(super) fn plain(&mut self, text: &str) -> &mut Self {
        self.lines.extend(text.lines().map(str::to_string));
        self
    }

    /// An item's own text; `indent` spaces are put in front of every line.
    pub(super) fn item(&mut self, id: &str, indent: usize, text: &str) -> &mut Self {
        let start = self.lines.len() as u32 + 1;
        self.lines.extend(text.lines().map(|l| if l.is_empty() { String::new() } else { format!("{}{l}", " ".repeat(indent)) }));
        self.at.push((id.to_string(), start, self.lines.len() as u32));
        self.lines.push(String::new());
        self
    }

    pub(super) fn write(&self, root: &Path, file: &str) -> Vec<SpanRow> {
        let path = root.join(file);
        std::fs::create_dir_all(path.parent().unwrap()).unwrap();
        std::fs::write(&path, self.lines.join("\n") + "\n").unwrap();
        self.at.iter().map(|(id, s, e)| span(id, file, *s, *e)).collect()
    }
}

pub const PARSE_HEADER: &str = "pub fn parse_header(line: &str) -> Option<(String, String)> {
    let (key, value) = line.split_once(':')?;
    let key = key.trim().to_ascii_lowercase();
    let value = value.trim().to_string();
    if key.is_empty() {
        return None;
    }
    Some((key, value))
}";
const DEFAULT: &str = "fn default() -> Self {
    Self::new()
}";
const CLAMP: &str = "pub fn clamp(x: i64, lo: i64, hi: i64) -> i64 {
    if x < lo {
        return lo;
    }
    if x > hi { hi } else { x }
}";
const TOTAL_1: &str = "pub fn total(&self, xs: &[u32]) -> u32 {
    let mut sum = 0;
    for x in xs {
        sum += *x;
    }
    sum + self.at as u32
}";
const TOTAL_2: &str = "pub fn total(&self, xs: &[u32]) -> u32 {
    xs.iter().copied().fold(self.at as u32, u32::wrapping_add)
}";
const CHECKSUM_1: &str = "pub fn checksum(bytes: &[u8]) -> u32 {
    let mut acc = 17u32;
    for b in bytes {
        acc = acc.rotate_left(5) ^ u32::from(*b);
    }
    acc
}";
const CHECKSUM_2: &str = "pub fn checksum(bytes: &[u8]) -> u32 {
    let mut acc = 0x811c_9dc5u32;
    for b in bytes {
        acc = (acc ^ u32::from(*b)).wrapping_mul(0x0100_0193);
    }
    acc
}";
const FRESH: &str = "pub fn fresh(now: u64, then: u64) -> bool {
    now.saturating_sub(then) < 60
}";

fn method(id: String, name: &str, parent: &str) -> N {
    n(id, "method", Level::Part, name, Some(parent.to_string()))
}

pub(super) fn param(of: &str, name: &str, ty: &str) -> (N, EdgeRow) {
    let id = format!("{of}({name})");
    (n(id.clone(), "param", Level::Part, name, Some(of.to_string())).ty(ty), e(of, &id, EdgeKind::Contains, 1))
}

/// A callable with its params and the stubs it calls, appended to a unit.
#[allow(clippy::too_many_arguments)]
pub(super) fn callable(nodes: &mut Vec<N>, edges: &mut Vec<EdgeRow>, stubs: &mut BTreeSet<String>, node: N, parent: &str, params: &[(&str, &str)], calls: &[&str]) {
    let id = node.0.id.clone();
    nodes.push(node);
    edges.push(e(parent, &id, EdgeKind::Contains, 1));
    for (p, ty) in params {
        let (pn, pe) = param(&id, p, ty);
        nodes.push(pn);
        edges.push(pe);
    }
    for c in calls {
        let to = moniker::moniker("core", "1.0.0", &format!("{c}()."));
        stubs.insert(to.clone());
        edges.push(e(&id, &to, EdgeKind::Calls, 1));
    }
}

pub(super) fn stubs_into(nodes: &mut Vec<N>, stubs: &BTreeSet<String>) {
    for s in stubs {
        let name = s.rsplit('/').next().unwrap_or(s).rsplit(' ').next().unwrap_or(s).trim_end_matches("().").to_string();
        nodes.push(n(s.clone(), "fn", Level::Item, &name, None).stub(Origin::Library));
    }
}

const HEADER_PARAMS: [(&str, &str); 1] = [("line", "&str")];
const HEADER_CALLS: [&str; 4] = ["split_once", "trim", "to_ascii_lowercase", "is_empty"];

/// `mono` at its first (`second = false`) or second commit, files written under `root`.
fn mono_commit(root: &Path, second: bool) -> CommitDump {
    // ── alpha ──
    let krate = alpha("crate/");
    let imp = alpha("impl#[Reader]");
    let imp_default = alpha("impl#[Reader][Default]");
    let mac = alpha("make_getter!");
    let util = alpha("util/");
    let mut src = Source::default();
    if second {
        src.plain("// every span below moved by one line");
    }
    src.plain("//! alpha\n\npub struct Reader {\n    at: usize,\n}\n\nimpl Reader {");
    src.item(&alpha("impl#[Reader]new()."), 4, "pub fn new() -> Self {\n    Reader { at: 0 }\n}");
    src.item(&alpha("impl#[Reader]total()."), 4, if second { TOTAL_2 } else { TOTAL_1 });
    src.plain("}\n\nimpl Default for Reader {");
    src.item(&alpha("impl#[Reader][Default]default()."), 4, DEFAULT);
    src.plain("}\n");
    src.item(&alpha("parse_header()."), 0, PARSE_HEADER);
    src.item(&alpha("checksum()."), 0, if second { CHECKSUM_2 } else { CHECKSUM_1 });
    if second {
        src.item(&alpha("fresh()."), 0, FRESH);
    }
    // the macro's product is positioned at the invocation
    src.item(&alpha("width()."), 0, "make_getter!(width);");
    let mut spans = src.write(root, "alpha/src/lib.rs");
    let mut shared = Source::default();
    shared.plain("//! compiled into alpha AND beta (`#[path]`)\n");
    shared.item(&alpha("util/clamp()."), 0, CLAMP);
    spans.extend(shared.write(root, "shared/util.rs"));

    let mut nodes = vec![
        n(krate.clone(), "crate", Level::Crate, "alpha", None),
        n(imp.clone(), "impl", Level::Item, "Reader", Some(krate.clone())),
        n(imp_default.clone(), "impl", Level::Item, "Reader", Some(krate.clone())),
        n(mac.clone(), "macro", Level::Item, "make_getter", Some(krate.clone())),
        n(util.clone(), "mod", Level::Module, "util", Some(krate.clone())),
    ];
    let default_trait = moniker::moniker("core", "1.0.0", "default/Default#");
    nodes.push(n(default_trait.clone(), "trait", Level::Item, "Default", None).stub(Origin::Library));
    let mut edges = vec![
        e(&krate, &imp, EdgeKind::Contains, 1),
        e(&krate, &imp_default, EdgeKind::Contains, 1),
        e(&krate, &mac, EdgeKind::Contains, 1),
        e(&krate, &util, EdgeKind::Contains, 1),
        e(&imp_default, &default_trait, EdgeKind::Implements, 1),
        e(&alpha("width()."), &mac, EdgeKind::Expands, 1),
        // the lockfile: kit 1.0.0, bumped to 2.0.0 by the second commit
        e(&krate, &kit(if second { "2.0.0" } else { "1.0.0" }, "crate/"), EdgeKind::DependsOn, 1),
    ];
    let mut stubs = BTreeSet::new();
    callable(&mut nodes, &mut edges, &mut stubs, method(alpha("impl#[Reader]new()."), "new", &imp), &imp, &[], &[]);
    callable(&mut nodes, &mut edges, &mut stubs, method(alpha("impl#[Reader]total()."), "total", &imp), &imp, &[("self", "&Reader"), ("xs", "&[u32]")], if second { &["fold", "copied"] } else { &[] });
    callable(&mut nodes, &mut edges, &mut stubs, method(alpha("impl#[Reader][Default]default()."), "default", &imp_default), &imp_default, &[], &["new"]);
    callable(&mut nodes, &mut edges, &mut stubs, n(alpha("parse_header()."), "fn", Level::Item, "parse_header", Some(krate.clone())), &krate, &HEADER_PARAMS, &HEADER_CALLS);
    callable(&mut nodes, &mut edges, &mut stubs, n(alpha("checksum()."), "fn", Level::Item, "checksum", Some(krate.clone())), &krate, &[("bytes", "&[u8]")], &["rotate_left"]);
    if second {
        callable(&mut nodes, &mut edges, &mut stubs, n(alpha("fresh()."), "fn", Level::Item, "fresh", Some(krate.clone())), &krate, &[("now", "u64"), ("then", "u64")], &["saturating_sub"]);
    }
    callable(&mut nodes, &mut edges, &mut stubs, n(alpha("width()."), "fn", Level::Item, "width", Some(krate.clone())), &krate, &[("self", "&Reader")], &[]);
    callable(&mut nodes, &mut edges, &mut stubs, n(alpha("util/clamp()."), "fn", Level::Item, "clamp", Some(util.clone())), &util, &[("x", "i64"), ("lo", "i64"), ("hi", "i64")], &[]);
    stubs_into(&mut nodes, &stubs);
    let alpha_unit = unit("alpha@0.1.0:lib", nodes, edges, spans);

    // ── beta ──
    let krate = beta("crate/");
    let imp = beta("impl#[Writer]");
    let imp_default = beta("impl#[Writer][Default]");
    let http = beta("http/");
    let util = beta("util/");
    let mut src = Source::default();
    src.plain("//! beta\n\npub struct Writer {\n    n: usize,\n}\n\nimpl Writer {");
    src.item(&beta("impl#[Writer]new()."), 4, "pub fn new() -> Self {\n    Writer { n: 0 }\n}");
    src.plain("}\n\nimpl Default for Writer {");
    src.item(&beta("impl#[Writer][Default]default()."), 4, DEFAULT);
    src.plain("}\n\npub mod http {");
    // alpha's function, byte for byte, one level deeper
    src.item(&beta("http/parse_header()."), 4, PARSE_HEADER);
    src.plain("}");
    let mut spans = src.write(root, "beta/src/lib.rs");
    // the SAME lines of the shared file, as beta's node
    spans.push(span(&beta("util/clamp()."), "shared/util.rs", shared.at[0].1, shared.at[0].2));
    let mut nodes = vec![
        n(krate.clone(), "crate", Level::Crate, "beta", None),
        n(imp.clone(), "impl", Level::Item, "Writer", Some(krate.clone())),
        n(imp_default.clone(), "impl", Level::Item, "Writer", Some(krate.clone())),
        n(http.clone(), "mod", Level::Module, "http", Some(krate.clone())),
        n(util.clone(), "mod", Level::Module, "util", Some(krate.clone())),
        n(default_trait.clone(), "trait", Level::Item, "Default", None).stub(Origin::Library),
    ];
    let mut edges = vec![
        e(&krate, &imp, EdgeKind::Contains, 1),
        e(&krate, &imp_default, EdgeKind::Contains, 1),
        e(&krate, &http, EdgeKind::Contains, 1),
        e(&krate, &util, EdgeKind::Contains, 1),
        e(&imp_default, &default_trait, EdgeKind::Implements, 1),
    ];
    let mut stubs = BTreeSet::new();
    callable(&mut nodes, &mut edges, &mut stubs, method(beta("impl#[Writer]new()."), "new", &imp), &imp, &[], &[]);
    callable(&mut nodes, &mut edges, &mut stubs, method(beta("impl#[Writer][Default]default()."), "default", &imp_default), &imp_default, &[], &["new"]);
    callable(&mut nodes, &mut edges, &mut stubs, n(beta("http/parse_header()."), "fn", Level::Item, "parse_header", Some(http.clone())), &http, &HEADER_PARAMS, &HEADER_CALLS);
    callable(&mut nodes, &mut edges, &mut stubs, n(beta("util/clamp()."), "fn", Level::Item, "clamp", Some(util.clone())), &util, &[("x", "i64"), ("lo", "i64"), ("hi", "i64")], &[]);
    stubs_into(&mut nodes, &stubs);
    let beta_unit = unit("beta@0.1.0:lib", nodes, edges, spans);

    let mut crates = vec![alpha_unit, beta_unit, ring_unit("1.0.0")];
    if second {
        crates.push(ring_unit("2.0.0"));
    }
    CommitDump {
        toolchain: "nightly-fixture".into(),
        workspace_crates: ["alpha@0.1.0:lib".to_string(), "beta@0.1.0:lib".to_string()].into(),
        workspace_targets: ["alpha:lib".to_string(), "beta:lib".to_string()].into(),
        failed_units: BTreeSet::new(),
        owner_disambiguations: 0,
        crates,
        binary: false,
        binaries: vec![],
    }
}

/// The lines of kit's `src/lib.rs` at `version`: `(text, [(descriptor, start, end)])`.
fn kit_source(version: &str) -> (String, Vec<(&'static str, u32, u32)>) {
    let pad = "pub fn pad(s: &str, width: usize) -> String {\n    format!(\"{s:>width$}\")\n}";
    let trim = if version == "1.0.0" { "pub fn trim(s: &str) -> &str {\n    s.trim()\n}" } else { "pub fn trim(s: &str) -> &str {\n    s.trim_matches(' ')\n}" };
    let text = format!("//! kit {version}\n\n{pad}\n\n{trim}\n");
    (text, vec![("pad().", 3, 5), ("trim().", 7, 9)])
}

/// One ring crate (`kit@<version>`): defined library nodes with spans relative
/// to its own manifest directory.
fn ring_unit(version: &str) -> CrateDump {
    let krate = kit(version, "crate/");
    let mut rows: Vec<NodeRow> = vec![NodeRow::new(krate.clone(), "crate", Level::Crate, "kit", "kit", version, Origin::Library)];
    let mut edges = Vec::new();
    let mut spans = Vec::new();
    for (d, start, end) in kit_source(version).1 {
        let id = kit(version, d);
        let mut row = NodeRow::new(id.clone(), "fn", Level::Item, d.trim_end_matches("()."), "kit", version, Origin::Library);
        row.parent = Some(krate.clone());
        rows.push(row);
        edges.push(e(&krate, &id, EdgeKind::Contains, 1));
        spans.push(span(&id, "src/lib.rs", start, end));
    }
    CrateDump {
        krate: format!("kit@{version}:lib"),
        universe: true,
        nodes: vec![mimir_schema::nodes_batch(&rows).unwrap()],
        edges: vec![mimir_schema::edges_batch(&edges).unwrap()],
        spans: vec![mimir_schema::spans_batch(&spans).unwrap()],
    }
}

/// [`Vx::digest_commit`]: gamma's `digest` becomes a fourth copy of
/// `parse_header` — the SAME bytes (so the feed re-links one function and
/// embeds nothing new), the same params and callees. Nothing above it moves.
fn other_commit(root: &Path, second: bool, uses: &[String]) -> CommitDump {
    let krate = gamma("crate/");
    // the manifest says the same as the lockfile edges: gamma depends on them
    if !uses.is_empty() {
        let deps: Vec<String> = uses.iter().filter_map(|m| moniker::parse(m)).map(|(p, v, _)| format!("{p} = {{ version = \"{v}\", path = \"../{p}\" }}")).collect();
        std::fs::create_dir_all(root).unwrap();
        std::fs::write(root.join("Cargo.toml"), format!("[package]\nname = \"gamma\"\nversion = \"0.3.0\"\n\n[dependencies]\n{}\n", deps.join("\n"))).unwrap();
    }
    let mut src = Source::default();
    src.plain("//! gamma\n");
    src.item(&gamma("parse_header()."), 0, PARSE_HEADER);
    src.item(&gamma("digest()."), 0, if second { PARSE_HEADER } else { "pub fn digest(data: &[u8]) -> u64 {\n    data.iter().fold(0u64, |h, b| h.wrapping_mul(31).wrapping_add(u64::from(*b)))\n}" });
    let mut spans = src.write(root, "src/lib.rs");
    // prost / bindgen output: positioned in the build's target directory, not in the repo
    spans.push(span(&gamma("proto/decode()."), "/nonexistent/target/debug/build/gamma-1/out/proto.rs", 10, 40));
    let mut nodes = vec![n(krate.clone(), "crate", Level::Crate, "gamma", None)];
    // the lockfile: the crates gamma depends on ([`build_using`])
    let mut edges: Vec<EdgeRow> = uses.iter().map(|to| e(&krate, to, EdgeKind::DependsOn, 1)).collect();
    let mut stubs = BTreeSet::new();
    callable(&mut nodes, &mut edges, &mut stubs, n(gamma("proto/decode()."), "fn", Level::Item, "decode", Some(krate.clone())), &krate, &[("buf", "&[u8]")], &[]);
    callable(&mut nodes, &mut edges, &mut stubs, n(gamma("parse_header()."), "fn", Level::Item, "parse_header", Some(krate.clone())), &krate, &HEADER_PARAMS, &HEADER_CALLS);
    let (digest_params, digest_calls): (&[(&str, &str)], &[&str]) = if second { (&HEADER_PARAMS, &HEADER_CALLS) } else { (&[("data", "&[u8]")], &["fold"]) };
    callable(&mut nodes, &mut edges, &mut stubs, n(gamma("digest()."), "fn", Level::Item, "digest", Some(krate.clone())), &krate, digest_params, digest_calls);
    stubs_into(&mut nodes, &stubs);
    CommitDump {
        toolchain: "nightly-fixture".into(),
        workspace_crates: ["gamma@0.3.0:lib".to_string()].into(),
        workspace_targets: ["gamma:lib".to_string()].into(),
        failed_units: BTreeSet::new(),
        owner_disambiguations: 0,
        crates: vec![unit("gamma@0.3.0:lib", nodes, edges, spans)],
        binary: false,
        binaries: vec![],
    }
}

/// The workspace, its two checkouts and the ring's registry directory.
pub struct Vx {
    pub ws: Workspace,
    root: PathBuf,
}

impl Vx {
    /// The checkout of `repo` (the tree a feed run reads).
    pub fn checkout(&self, repo: &str) -> PathBuf {
        self.root.join(format!("src-{repo}"))
    }

    /// `(seq, sha)` the code room holds `repo` at.
    pub fn at(&self, repo: &str) -> (i64, String) {
        let log = self.ws.room.log().unwrap();
        let o = log.block_on(log.offsets()).unwrap().remove(repo).unwrap_or_else(|| panic!("{repo} is not consumed"));
        (o.seq, o.sha)
    }

    /// The function half of the feed for `repo`, as the consumer runs it.
    pub fn embed(&self, repo: &str, bag: &Bag) -> crate::vector::fnvec::Run {
        let (seq, sha) = self.at(repo);
        let log = self.ws.room.log().unwrap();
        let mut embedding = crate::vector::fnvec::Loaded { embedder: bag, backend: "test bag (cpu)" };
        crate::vector::fnvec::room::embed_member_with(&self.ws.warehouse, &log, repo, &self.checkout(repo), seq, &sha, &mut embedding).unwrap()
    }

    /// The function shapes (`clone_shapes`' first half) of `repo` at its
    /// current commit, as the consumer writes them.
    pub fn shapes(&self, repo: &str) -> crate::clone_signals::feed::ShapeRun {
        let (seq, sha) = self.at(repo);
        let log = self.ws.room.log().unwrap();
        crate::clone_signals::feed::shapes_member(&self.ws.warehouse, &log, repo, &self.checkout(repo), seq, &sha).unwrap()
    }

    /// Consume `mono`'s second commit.
    pub fn second_commit(&self) {
        let dir = self.checkout(MONO);
        let dump = mono_commit(&dir, true);
        self.registry("2.0.0");
        nornir_git::gitio::commit_all(&dir, "second").unwrap();
        consume_next(&self.ws.room, &dir, MONO, dump);
    }

    /// Consume `other`'s second commit: ONE function changes — `digest`
    /// becomes a fourth copy of `parse_header` (same bytes, same callees);
    /// every other span of the workspace stays where it was.
    pub fn digest_commit(&self) {
        let dir = self.checkout(OTHER);
        let dump = other_commit(&dir, true, &[]);
        nornir_git::gitio::commit_all(&dir, "digest is a copy now").unwrap();
        consume_next(&self.ws.room, &dir, OTHER, dump);
    }

    /// The directory kit@`version`'s manifest is in, with its source written.
    fn registry(&self, version: &str) -> PathBuf {
        let dir = self.root.join("registry").join(format!("kit-{version}"));
        std::fs::create_dir_all(dir.join("src")).unwrap();
        std::fs::write(dir.join("Cargo.toml"), format!("[package]\nname = \"kit\"\nversion = \"{version}\"\n")).unwrap();
        std::fs::write(dir.join("src/lib.rs"), kit_source(version).0).unwrap();
        dir
    }

    /// Where kit's source is, per version — what `cargo metadata` tells the ring job.
    pub fn ring_dirs(&self, versions: &[&str]) -> std::collections::BTreeMap<String, PathBuf> {
        let packages: Vec<serde_json::Value> = versions.iter().map(|v| serde_json::json!({ "name": "kit", "version": v, "manifest_path": self.registry(v).join("Cargo.toml") })).collect();
        crate::vector::fnvec::ring::dirs_from_metadata(&serde_json::json!({ "packages": packages }))
    }
}

/// Consume the next commit of the repo at `dir` with `dump`.
pub(super) fn consume_next(room: &CodeRoom, dir: &Path, name: &str, dump: CommitDump) {
    let spec = RepoSpec { name: name.into(), source: dir.to_string_lossy().into_owned(), branch: "main".into(), worktree: room.layout().clone_of(name), initial_offset: None };
    let log = room.log().expect("the lake opens");
    let reports = log.block_on(async {
        let mut c = Consumer::boot(log.clone(), Scripted(vec![dump])).await.unwrap();
        c.run(&spec).await.unwrap()
    });
    assert!(reports.len() == 1 && reports[0].status == "ok", "{reports:?}");
}

/// Both repos consumed at their first commit; nothing embedded yet.
pub fn build() -> Vx {
    build_using(&[])
}

/// [`build`], gamma (repo `other`) depending on the crates `uses` names
/// (crate monikers, e.g. `alpha("crate/")`): its `parse_header` is then a copy
/// of a function of a crate it imports.
pub fn build_using(uses: &[String]) -> Vx {
    let tmp = tempfile::tempdir().unwrap();
    let root = tmp.path().to_path_buf();
    let builds = root.join("builds");
    std::fs::create_dir_all(&builds).unwrap();
    let warehouse = IcebergWarehouse::open(&builds).unwrap();
    let room = CodeRoom::new("vectors", &builds);
    for name in [MONO, OTHER] {
        let dir = root.join(format!("src-{name}"));
        nornir_git::gitio::init(&dir).unwrap();
        let dump = if name == MONO { mono_commit(&dir, false) } else { other_commit(&dir, false, uses) };
        nornir_git::gitio::commit_all(&dir, "first").unwrap();
        consume_next(&room, &dir, name, dump);
    }
    let vx = Vx { ws: Workspace { room, warehouse, builds, _tmp: tmp }, root };
    vx.registry("1.0.0");
    vx
}