src/mimir_lens/benchcov.rs
//! **BENCH coverage — the un-benched hot paths.** The model is dwarves'
//! (`dwarves/crates/dwarves/src/coverage/benchcov.rs`).
//!
//! `Gap_bench = HotPaths − Benched − Allowlist`. Hot paths are ranked from fan-in
//! (call sites arriving at a module's functions, from the code room) × churn
//! (`git_heat_facts`) × perf-name hint × test coverage; a module with no matching
//! `bench_results` arm is the gap L3 says must not exist. A repo with zero bench
//! runs reads as NEVER BENCHED, never as a clean bill.
use std::collections::{BTreeMap, BTreeSet};
use edda_autonom::{BencherRow, Gap, benchers, compute_gap, covered_benchers};
use serde::{Deserialize, Serialize};
use super::rows::{BenchResultFact, BenchRunFact, GitHeatFact};
/// Module/crate name fragments that mark a perf-sensitive path.
pub const PERF_MODULE_HINTS: &[&str] = &[
"alloc",
"batch",
"buffer",
"cache",
"chunk",
"codec",
"compress",
"decode",
"decompress",
"encode",
"hash",
"index",
"parse",
"pack",
"scan",
"search",
"serde",
"serialize",
"sort",
"stream",
"unpack",
"vector",
"zstd",
];
pub const W_FAN_IN: f64 = 0.40;
pub const W_CHURN: f64 = 0.25;
pub const W_HINT: f64 = 0.10;
pub const W_COVERAGE: f64 = 0.25;
/// One module ranked as a hot path, with the evidence for the ranking.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HotPath {
pub repo: String,
pub module: String,
pub surface_id: String,
pub fan_in: u32,
pub commits_90d: u64,
pub hint: Option<String>,
pub test_coverage: f64,
pub score: f64,
pub bench_ids: Vec<String>,
}
impl HotPath {
pub fn is_benched(&self) -> bool {
!self.bench_ids.is_empty()
}
}
/// The per-repo bench-coverage verdict.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RepoBenchCoverage {
pub repo: String,
pub hot_paths: usize,
pub benched: usize,
pub allowlisted: usize,
pub unbenched: usize,
pub bench_arms: usize,
pub bench_runs: usize,
pub worst: Vec<HotPath>,
}
impl RepoBenchCoverage {
pub fn never_benched(&self) -> bool {
self.bench_runs == 0
}
pub fn benched_frac(&self) -> f64 {
if self.hot_paths == 0 {
return 0.0;
}
self.benched as f64 / self.hot_paths as f64
}
}
/// What the code room knows about one module of a repo.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ModuleFacts {
/// The module's path (`znippy::decode`; the crate name for the root).
pub module: String,
/// CALLS sites arriving at the module's functions.
pub fan_in: u32,
/// The files its items lie in.
pub files: BTreeSet<String>,
/// `fn` + `method` items defined in it.
pub fns_total: u32,
/// Of those, the ones in the test-reachable set.
pub fns_covered: u32,
}
/// **Is this module a TEST module?** Test/bench harness modules are excluded from
/// the bench surface entirely.
pub fn is_test_module(module: &str) -> bool {
module.split("::").any(|seg| {
let s = seg.to_ascii_lowercase();
s == "tests" || s == "test" || s.ends_with("_tests") || s.starts_with("test_")
}) || module.to_ascii_lowercase().contains("::benches")
}
/// Structural tokens carrying no scenario meaning — excluded from both sides of
/// [`arm_covers_module`].
pub const STOP_TOKENS: &[&str] = &[
"all", "bench", "common", "core", "crate", "demo", "error", "full", "get", "impl", "lib",
"main", "mod", "new", "real", "run", "set", "test", "tests", "type", "types", "util", "utils",
];
const MIN_TOKEN: usize = 3;
/// **Does bench arm `arm` cover module `module`?**
pub fn arm_covers_module(repo: &str, arm: &str, module: &str) -> bool {
let repo_lc = repo.to_ascii_lowercase();
let repo_parts: BTreeSet<&str> = repo_lc
.split(|c: char| !c.is_ascii_alphanumeric())
.collect();
let tokens = |s: &'_ str| -> BTreeSet<String> {
s.split(|c: char| !c.is_ascii_alphanumeric())
.filter(|t| t.len() >= MIN_TOKEN && !STOP_TOKENS.contains(t) && !repo_parts.contains(t))
.map(str::to_string)
.collect()
};
let scenario = arm
.split_once('.')
.map(|(_, s)| s)
.unwrap_or(arm)
.to_ascii_lowercase();
let arm_tokens = tokens(&scenario);
if arm_tokens.is_empty() {
return false;
}
let module_lc = module.to_ascii_lowercase();
arm_tokens
.intersection(&tokens(&module_lc))
.next()
.is_some()
}
/// Which perf hint (if any) fires for a module name.
pub fn perf_hint(module: &str) -> Option<String> {
let m = module.to_ascii_lowercase();
PERF_MODULE_HINTS
.iter()
.find(|h| m.contains(*h))
.map(|h| (*h).to_string())
}
/// **Rank a repo's modules as hot paths and mark which carry a bench.**
pub fn hot_paths(repo: &str, modules: &[ModuleFacts], heat: &[GitHeatFact], arms: &BTreeSet<String>, top_n: usize) -> Vec<HotPath> {
// test / bench harness modules are not part of the bench surface
let modules: Vec<&ModuleFacts> = modules.iter().filter(|m| !is_test_module(&m.module)).collect();
let heat_by_file: BTreeMap<&str, u64> = heat.iter().map(|h| (h.file.as_str(), h.commits_90d)).collect();
let churn = |m: &ModuleFacts| -> u64 { m.files.iter().filter_map(|f| heat_by_file.get(f.as_str())).sum() };
let coverage_of = |m: &ModuleFacts| -> f64 {
match m.fns_total {
0 => 0.0,
t => m.fns_covered.min(t) as f64 / t as f64,
}
};
let max_fan = modules.iter().map(|m| m.fan_in).max().unwrap_or(0).max(1) as f64;
let max_churn = modules.iter().map(|m| churn(m)).max().unwrap_or(0).max(1) as f64;
let mut out: Vec<HotPath> = modules
.iter()
.map(|m| {
let f = m.fan_in;
let c = churn(m);
let hint = perf_hint(&m.module);
let cov = coverage_of(m);
let score = W_FAN_IN * (f as f64 / max_fan)
+ W_CHURN * (c as f64 / max_churn)
+ W_COVERAGE * cov
+ if hint.is_some() { W_HINT } else { 0.0 };
let bench_ids: Vec<String> = arms.iter().filter(|a| arm_covers_module(repo, a, &m.module)).cloned().collect();
HotPath {
repo: repo.to_string(),
module: m.module.clone(),
surface_id: format!("{repo}.{}", m.module),
fan_in: f,
commits_90d: c,
hint,
test_coverage: cov,
score,
bench_ids,
}
})
.collect();
out.sort_by(|a, b| {
b.score
.partial_cmp(&a.score)
.unwrap_or(std::cmp::Ordering::Equal)
.then_with(|| a.module.cmp(&b.module))
});
out.truncate(top_n);
out
}
/// **The per-repo bench-coverage verdict**, computed through autonom's gate.
pub fn repo_bench_coverage(
repo: &str,
modules: &[ModuleFacts],
heat: &[GitHeatFact],
runs: &[BenchRunFact],
results: &[BenchResultFact],
allowlist: &BTreeSet<String>,
top_n: usize,
) -> RepoBenchCoverage {
let run_ids: BTreeSet<&str> = runs
.iter()
.filter(|r| r.repo == repo)
.map(|r| r.run_id.as_str())
.collect();
let arms: BTreeSet<String> = results
.iter()
.filter(|r| run_ids.contains(r.run_id.as_str()))
.map(|r| r.result_name.clone())
.collect();
let hot = hot_paths(repo, modules, heat, &arms, top_n);
let bench_rows: Vec<BencherRow> = hot
.iter()
.map(|h| BencherRow {
module: h.surface_id.clone(),
has_bencher: h.is_benched(),
bench_ids: h.bench_ids.clone(),
})
.collect();
let mut surface = edda_autonom::Surface::new();
surface.extend(benchers(&bench_rows));
let gap: Gap = compute_gap(&surface, &covered_benchers(&bench_rows), allowlist);
let worst: Vec<HotPath> = hot.iter().filter(|h| !h.is_benched()).cloned().collect();
RepoBenchCoverage {
repo: repo.to_string(),
hot_paths: gap.total,
benched: gap.covered,
allowlisted: gap.allowlisted.len(),
unbenched: gap.missing.len(),
bench_arms: arms.len(),
bench_runs: run_ids.len(),
worst,
}
}
#[cfg(test)]
mod tests {
use super::*;
fn module(path: &str, fan_in: u32) -> ModuleFacts {
ModuleFacts { module: path.into(), fan_in, files: [format!("{path}.rs")].into(), fns_total: 1, fns_covered: 0 }
}
fn run(repo: &str, id: &str, machine: &str) -> BenchRunFact {
BenchRunFact {
run_id: id.into(),
repo: repo.into(),
ts_micros: 1,
date: "2026-07-22".into(),
version: "0.1.0".into(),
machine: machine.into(),
cores: 32,
..Default::default()
}
}
fn result(run_id: &str, arm: &str) -> BenchResultFact {
BenchResultFact {
run_id: run_id.into(),
result_name: arm.into(),
metric_name: "ms".into(),
metric_value: 1.0,
}
}
#[test]
fn arm_covers_the_module_its_scenario_names_and_no_other() {
assert!(arm_covers_module(
"znippy",
"znippy.decode_mt",
"znippy::decode"
));
assert!(!arm_covers_module(
"znippy",
"znippy.decode_mt",
"znippy::vault"
));
assert!(!arm_covers_module(
"skade",
"osm_ingest_skade_ram",
"skade::catalog"
));
}
#[test]
fn a_repo_that_was_never_benched_reads_as_never_benched_not_as_clean() {
let modules = [module("korp::clip", 1), module("korp::io", 0)];
let cov = repo_bench_coverage("korp", &modules, &[], &[], &[], &BTreeSet::new(), 10);
assert!(cov.never_benched());
assert_eq!(cov.benched, 0);
assert_eq!(cov.unbenched, cov.hot_paths);
assert!(cov.hot_paths > 0);
}
#[test]
fn the_unbenched_hot_path_is_named_and_the_benched_one_is_not() {
let modules = [module("znippy::decode", 20), module("znippy::encode", 20), module("znippy::caller", 0)];
let cov = repo_bench_coverage("znippy", &modules, &[], &[run("znippy", "r1", "oden")], &[result("r1", "znippy.decode_mt")], &BTreeSet::new(), 10);
let named: Vec<&str> = cov.worst.iter().map(|h| h.module.as_str()).collect();
assert!(named.contains(&"znippy::encode"), "{named:?}");
assert!(!named.contains(&"znippy::decode"));
}
#[test]
fn fan_in_churn_and_coverage_each_move_the_rank_and_test_modules_are_no_surface() {
let heat = [GitHeatFact { repo: "korp".into(), file: "korp::hot.rs".into(), commits_90d: 30 }];
let mut covered = module("korp::covered", 0);
covered.fns_covered = 1;
let modules = [module("korp::called", 9), module("korp::hot", 0), covered, module("korp::quiet", 0), module("korp::tests", 50)];
let hot = hot_paths("korp", &modules, &heat, &BTreeSet::new(), 10);
let order: Vec<&str> = hot.iter().map(|h| h.module.as_str()).collect();
assert_eq!(order, vec!["korp::called", "korp::covered", "korp::hot", "korp::quiet"]);
assert_eq!((hot[0].fan_in, hot[2].commits_90d, hot[1].test_coverage), (9, 30, 1.0));
}
}