crates/dwarves-embed/src/warehousehealth.rs
//! **The dwarves Mímir "Warehouse Health" backoffice pane.**
//!
//! Under the Mímir menu: EVERY warehouse table with its REAL numbers —
//! **row count · on-disk byte size · last-populated snapshot** — not green boxes.
//! The point is to make a *hollow Mímir* impossible to miss: after the 2026-07-24
//! repopulate that silently skipped vector/embedding indexing, this pane shows
//! `embeddings` / `embedding_snapshots` at **0 rows, 0 B, never** in RED, next to
//! `symbol_facts` at its real 150 MB — so the gap is visible at a glance.
//!
//! ## The seam (offline, host-agnostic — same shape as the Benches pane)
//! The numbers come from nornir's `Warehouse.TableStats` RPC (row count + byte
//! size + last snapshot, read cheaply off each table's Iceberg snapshot summary)
//! serialized to a per-workspace JSON file the host drops beside the other nornir
//! run artifacts. This pane reads that file as DATA — no gRPC, no nornir dep (the
//! POD is defined here).
//!
//! ## The fixture is gone (2026-09-10, the eighth pane)
//! A missing stats file used to mount `health_fixture()` — a mirror of the live
//! nordisk warehouse of 2026-07-24, real table names at real sizes, `symbol_facts`
//! at ~150 MB. `state_json`'s `source` said `"fixture"` beside it.
//!
//! This is the pane that suffered most from having one. Its stated job, three
//! paragraphs up, is to make a **hollow Mímir impossible to miss** — and with no
//! stats file it drew a *populated* warehouse: a COMPLETE banner, filled tables,
//! plausible byte sizes. The one pane built to show you an empty warehouse was the
//! one that invented a full one. A green COMPLETE chip IS a claim of health,
//! whatever the caption underneath says.
//!
//! `bf692d9` ("seven panes stop drawing invented data") did not cover this pane —
//! its seven were Status, Forge, Coderoom, Binary, Fleet, Profile and Saga. Now:
//! no file ⇒ zero tables, no banner, and the shared
//! [`facett_core::empty::EmptyState`] NAMING the stats file it wanted.
use std::path::{Path, PathBuf};
use facett_core::empty::EmptyState;
use facett_core::{Facet, Panel};
/// The stats feed, named the way an operator would go look it up.
const HEALTH_FEED: &str = "nornir Warehouse.TableStats JSON";
/// One warehouse table's health — the POD the pane renders. Mirrors nornir's
/// `WarehouseTableStat` proto message / `warehouse::iceberg::TableStat` field for
/// field, so the host can serialize the RPC result straight into the seam file.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct TableHealthRow {
pub table: String,
/// Row count from the snapshot summary; `-1` = unknown, `0` = never written.
pub row_count: i64,
/// On-disk byte size (`total-files-size`); `-1` = unknown.
pub byte_size: i64,
/// Last-populated snapshot timestamp (epoch ms); `0` = never populated.
pub last_snapshot_ms: i64,
/// `row_count<=0 && data_files<=0`.
pub empty: bool,
/// On the documented empty-until-triggered allowlist (an empty read is fine).
pub allowlisted: bool,
/// Why it is legitimately empty (if allowlisted).
#[serde(default)]
pub reason: String,
}
impl TableHealthRow {
/// An empty, NON-allowlisted expected table — a silent-skip regression (RED).
pub fn is_regression(&self) -> bool {
self.empty && !self.allowlisted
}
}
/// The full health document — the per-table rows plus the completeness roll-up
/// (`Warehouse.TableStats` returns exactly this shape).
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
pub struct WarehouseHealthDoc {
pub stats: Vec<TableHealthRow>,
/// No empty regression outside the allowlist.
pub complete: bool,
/// Expected index types that filled ZERO rows (the silent skips).
#[serde(default)]
pub empty_regressions: Vec<String>,
/// One-line human roll-up.
#[serde(default)]
pub summary: String,
}
/// Sanitize a workspace name to a filesystem-safe token — the SAME rule the other
/// dwarves panes use, kept in step.
fn safe(name: &str) -> String {
name.trim()
.chars()
.map(|c| {
if c.is_ascii_alphanumeric() || matches!(c, '.' | '_' | '-') {
c
} else {
'_'
}
})
.collect()
}
/// The **warehouse-health JSON** a host writes for a named workspace by
/// serializing nornir's `Warehouse.TableStats` result. Empty name ⇒ a shared
/// default. MUST match the host's emit path so the pane sees that workspace's
/// numbers.
pub fn workspace_health_path(workspace: &str) -> PathBuf {
let name = safe(workspace);
let file = if name.is_empty() {
"dwarves-warehouse-health.json".to_string()
} else {
format!("dwarves-warehouse-health-{name}.json")
};
std::env::temp_dir().join(file)
}
/// Human byte size (`0 B` / `1.2 KB` / `150.0 MB`); `-1` ⇒ `?`.
pub fn human_bytes(n: i64) -> String {
if n < 0 {
return "?".to_string();
}
let n = n as f64;
const KB: f64 = 1024.0;
if n < KB {
format!("{n:.0} B")
} else if n < KB * KB {
format!("{:.1} KB", n / KB)
} else if n < KB * KB * KB {
format!("{:.1} MB", n / (KB * KB))
} else {
format!("{:.1} GB", n / (KB * KB * KB))
}
}
/// Human last-populated: `never` for 0, else an epoch-ms date. No chrono dep — a
/// plain `<epoch>ms` marker keeps the pane leaf-light; the host can localize.
pub fn human_snapshot(ms: i64) -> String {
if ms <= 0 {
"never".to_string()
} else {
// seconds since epoch, good enough for an at-a-glance recency marker.
format!("@{}s", ms / 1000)
}
}
/// **The Warehouse Health pane.** Holds the health doc bound to one workspace.
pub struct WarehouseHealthView {
doc: WarehouseHealthDoc,
workspace: String,
/// Whether the numbers came from a real run file.
from_run: bool,
/// Set when there are no table stats to show — the NAMED empty state (which file,
/// why), drawn in place of the banner and the table. This replaced the fixture.
empty: Option<EmptyState>,
}
impl WarehouseHealthView {
/// Build for `workspace` by reading its health JSON. No file ⇒ the named empty
/// state, never an invented warehouse.
pub fn for_workspace(workspace: &str) -> Self {
Self::from_path(&workspace_health_path(workspace), workspace)
}
/// Build from an explicit path (the helper the tab + tests drive).
/// Missing/unreadable ⇒ zero tables + the NAMED empty state; never panics.
pub fn from_path(path: &Path, workspace: &str) -> Self {
let parsed = std::fs::read_to_string(path)
.ok()
.and_then(|s| serde_json::from_str::<WarehouseHealthDoc>(&s).ok());
let from_run = parsed.is_some();
let ws = if workspace.trim().is_empty() {
"no workspace selected".to_string()
} else {
format!("workspace `{workspace}`")
};
// `not-configured` (no readable stats file) is kept apart from `no-rows` (a
// file that parsed but lists no tables) — the two mean different things to an
// operator, and only the second is a statement about the warehouse.
let empty = match &parsed {
None => Some(
EmptyState::not_configured(
HEALTH_FEED,
format!("{} is missing or unreadable for {ws}", path.display()),
)
.with_hint("populate the warehouse, then drop the TableStats JSON beside it"),
),
Some(d) if d.stats.is_empty() => Some(
EmptyState::no_rows(
HEALTH_FEED,
format!("{} lists no tables for {ws}", path.display()),
)
.with_hint("re-run `Warehouse.TableStats`"),
),
Some(_) => None,
};
Self {
doc: parsed.unwrap_or_default(),
workspace: workspace.to_string(),
from_run,
empty,
}
}
/// Build directly from a fetched doc (a host that already called the RPC).
pub fn from_doc(doc: WarehouseHealthDoc, workspace: &str) -> Self {
let empty = doc.stats.is_empty().then(|| {
EmptyState::no_rows(HEALTH_FEED, "the fetched TableStats reply lists no tables")
.with_hint("re-run `Warehouse.TableStats`")
});
Self {
doc,
workspace: workspace.to_string(),
from_run: true,
empty,
}
}
/// Re-bind to a new workspace (the selector broadcast).
pub fn bind(&mut self, workspace: &str) {
*self = Self::for_workspace(workspace);
}
pub fn workspace(&self) -> &str {
&self.workspace
}
fn filled_count(&self) -> usize {
self.doc.stats.iter().filter(|r| !r.empty).count()
}
fn regression_count(&self) -> usize {
self.doc.stats.iter().filter(|r| r.is_regression()).count()
}
}
impl Facet for WarehouseHealthView {
fn title(&self) -> &str {
"Warehouse Health"
}
fn ui(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
if self.workspace.is_empty() {
ui.label("Warehouse Health: no workspace selected");
} else {
ui.label(format!("Warehouse Health: {}", self.workspace));
}
ui.separator();
ui.label(if self.from_run {
"● live stats"
} else {
"○ no stats"
});
});
if let Some(e) = &self.empty {
// No stats ⇒ no COMPLETE banner, no table rows, no byte sizes. A pane built
// to make a hollow warehouse visible must not paint a full one.
e.ui(ui);
return;
}
// Honest completeness banner — RED when an index type silently stopped filling.
if self.doc.complete && self.regression_count() == 0 {
ui.colored_label(
egui::Color32::from_rgb(90, 200, 120),
format!("● COMPLETE — {} table(s) filled", self.filled_count()),
);
} else {
ui.colored_label(
egui::Color32::from_rgb(224, 90, 90),
format!(
"● INCOMPLETE — {} index type(s) filled ZERO rows: {}",
self.regression_count(),
self.doc.empty_regressions.join(", ")
),
);
}
ui.label(&self.doc.summary);
ui.separator();
egui::ScrollArea::vertical()
.auto_shrink([false, false])
.show(ui, |ui| {
egui::Grid::new("warehouse-health-grid")
.striped(true)
.spacing([14.0, 3.0])
.show(ui, |ui| {
for h in ["table", "rows", "size", "last populated", "state"] {
ui.label(egui::RichText::new(h).strong());
}
ui.end_row();
for r in &self.doc.stats {
ui.label(&r.table);
ui.label(if r.row_count < 0 {
"?".to_string()
} else {
r.row_count.to_string()
});
ui.label(human_bytes(r.byte_size));
ui.label(human_snapshot(r.last_snapshot_ms));
let (txt, col) = if r.is_regression() {
("REGRESSION (empty)", egui::Color32::from_rgb(224, 90, 90))
} else if r.empty && r.allowlisted {
("empty (expected)", egui::Color32::GRAY)
} else {
("filled", egui::Color32::from_rgb(90, 200, 120))
};
ui.label(egui::RichText::new(txt).color(col)).on_hover_text(
if r.reason.is_empty() {
""
} else {
r.reason.as_str()
},
);
ui.end_row();
}
});
});
}
fn state_json(&self) -> serde_json::Value {
let rows: Vec<serde_json::Value> = self
.doc
.stats
.iter()
.map(|r| {
serde_json::json!({
"table": r.table,
"row_count": r.row_count,
"byte_size": r.byte_size,
"last_snapshot_ms": r.last_snapshot_ms,
"empty": r.empty,
"allowlisted": r.allowlisted,
"regression": r.is_regression(),
})
})
.collect();
serde_json::json!({
"component": "WarehouseHealthView",
"selected_workspace": self.workspace,
// `"fixture"` is gone: the only two values now are the real run and the
// honest empty, and the empty carries its own named block.
"source": if self.from_run { "workspace-run" } else { "empty" },
"health_feed": HEALTH_FEED,
"health_empty": self.empty.as_ref().map(|e| e.state_json()),
// With no stats there is nothing to be complete ABOUT, so this must not
// read `true` off an empty doc and paint a green COMPLETE chip.
"complete": self.empty.is_none() && self.doc.complete && self.regression_count() == 0,
"table_count": self.doc.stats.len(),
"filled_count": self.filled_count(),
"regression_count": self.regression_count(),
"empty_regressions": self.doc.empty_regressions,
"summary": self.doc.summary,
"tables": rows,
})
}
fn update_json(&mut self, msg_json: &str) {
if let Ok(v) = serde_json::from_str::<serde_json::Value>(msg_json) {
if let Some(ws) = v.get("set_workspace").and_then(|t| t.as_str()) {
self.bind(ws);
}
}
}
}
/// The dwarves Mímir **Warehouse Health** tab for a workspace.
pub fn warehouse_health_panel(workspace: &str) -> Box<dyn Panel> {
Box::new(WarehouseHealthView::for_workspace(workspace))
}
/// Build from an explicit path (a host/CLI that resolved it, or a test).
pub fn warehouse_health_panel_at(path: &Path, workspace: &str) -> Box<dyn Panel> {
Box::new(WarehouseHealthView::from_path(path, workspace))
}
/// A warehouse shaped like the live nordisk one of 2026-07-24 for a TEST: the
/// per-snapshot knowledge tables filled, and the embedding tables EMPTY +
/// non-allowlisted, so the regression detection has something to find.
///
/// **`#[cfg(test)]` since 2026-09-10.** As `pub fn health_fixture()` this was what the
/// SHIPPED pane drew whenever the stats file was missing — a populated warehouse with
/// plausible byte sizes, from the one pane whose entire purpose is to make an EMPTY
/// warehouse impossible to miss.
#[cfg(test)]
pub(crate) fn health_fixture() -> WarehouseHealthDoc {
let filled = |table: &str, rows: i64, bytes: i64| TableHealthRow {
table: table.into(),
row_count: rows,
byte_size: bytes,
last_snapshot_ms: 1_753_000_000_000,
empty: false,
allowlisted: false,
reason: String::new(),
};
let regression = |table: &str| TableHealthRow {
table: table.into(),
row_count: 0,
byte_size: 0,
last_snapshot_ms: 0,
empty: true,
allowlisted: false,
reason: String::new(),
};
let allowlisted = |table: &str, why: &str| TableHealthRow {
table: table.into(),
row_count: 0,
byte_size: 0,
last_snapshot_ms: 0,
empty: true,
allowlisted: true,
reason: why.into(),
};
let stats = vec![
filled("symbol_facts", 79_111, 157_005_137),
filled("call_edges", 537_754, 161_034_340),
filled("feature_gate_facts", 12_004, 14_893_547),
filled("test_inventory", 6_233, 10_608_525),
filled("git_heat_facts", 4_812, 2_631_142),
filled("scip_occurrences", 331_402, 20_977_681),
filled("tantivy_index_blobs", 1645, 934_771_098),
// THE REGRESSION — vector/embedding indexing silently skipped.
regression("embeddings"),
regression("embedding_snapshots"),
regression("embedding_manifest"),
// legitimately empty until triggered.
allowlisted("yank_events", "empty means NO crate versions were yanked"),
allowlisted(
"test_results",
"no `nornir test run`/release executed the matrix yet",
),
allowlisted("bench_runs", "filled by `nornir bench`, not by populate"),
];
WarehouseHealthDoc {
complete: false,
empty_regressions: vec![
"embeddings".into(),
"embedding_snapshots".into(),
"embedding_manifest".into(),
],
summary: "populate completeness: 7/10 expected tables filled · 3 regression(s) \
[embeddings, embedding_snapshots, embedding_manifest] · embeddings MISSING · scip ok"
.into(),
stats,
}
}
#[cfg(test)]
mod tests {
use super::*;
/// **THE WAREHOUSE FIXTURE IS GONE** (2026-09-10, the eighth pane — `bf692d9`
/// covered the other seven). With no stats file the pane used to draw
/// `health_fixture()`: a mirror of the live nordisk warehouse, `symbol_facts` at
/// ~150 MB, filled knowledge tables, plausible sizes. The pane whose entire stated
/// job is to make a HOLLOW Mímir impossible to miss was drawing a full one. Pins:
///
/// (a) a missing stats file gives ZERO tables, not ten;
/// (b) `complete` is NOT true — an empty doc must not paint a green COMPLETE chip;
/// (c) the pane carries the NAMED empty state over the stats file, cause
/// `not-configured`, and `source` is `empty` rather than `fixture`;
/// (d) none of the fixture's invented tables/sizes survives anywhere;
/// (e) a file that PARSED but lists no tables is a different cause (`no-rows`).
///
/// RED-when-broken: restore the fallback and (a)/(d) fail.
#[test]
fn an_unpopulated_warehouse_names_its_feed_never_a_fixture() {
let st = warehouse_health_panel_at(
Path::new("/nonexistent/dwarves/warehouse-health.json"),
"nordisk",
)
.state_json();
// (a) + (b)
assert_eq!(st["table_count"], 0, "no stats file ⇒ no tables: {st}");
assert!(st["tables"].as_array().unwrap().is_empty(), "{st}");
assert_eq!(
st["complete"], false,
"an empty doc is not a COMPLETE warehouse: {st}"
);
// (c)
assert_eq!(
st["source"], "empty",
"`fixture` is not a source any more: {st}"
);
assert_eq!(
st["health_empty"]["feed"], HEALTH_FEED,
"the pane NAMES its feed: {st}"
);
assert_eq!(st["health_empty"]["cause"], "not-configured");
assert!(st["health_empty"]["detail"]
.as_str()
.unwrap()
.contains("warehouse-health.json"));
// (d) the fixture's invented facts appear NOWHERE.
let whole = st.to_string();
for gone in [
"symbol_facts",
"tantivy_index_blobs",
"embedding_manifest",
"scip ok",
] {
assert!(
!whole.contains(gone),
"the deleted fixture's `{gone}` is gone: {whole}"
);
}
// (e) a present-but-tableless doc is read-and-empty, not not-configured.
let present = WarehouseHealthView::from_doc(WarehouseHealthDoc::default(), "nordisk");
assert_eq!(
Facet::state_json(&present)["health_empty"]["cause"],
"no-rows"
);
}
/// ROBOT SCENARIO — the **Warehouse Health** backoffice pane driven over the
/// remote seam (`Panel::state_json`): assert the pane shows REAL per-table numbers
/// AND red-flags the embeddings regression — the whole reason the pane exists.
/// Emits a testmatrix cell.
///
/// The doc is handed in DIRECTLY (2026-09-10). This used to read it off
/// `warehouse_health_panel("")`, which only worked because an unfed pane mounted
/// `health_fixture()` — so the test was asserting the fallback, not the render.
/// What it is about is what the pane does WITH stats, so it now gets stats.
#[test]
fn warehouse_health_pane_shows_real_numbers_and_flags_empty_index_types() {
let pane: Box<dyn Panel> =
Box::new(WarehouseHealthView::from_doc(health_fixture(), "nordisk"));
let st = pane.state_json();
let tables = st["tables"].as_array().unwrap();
// real numbers, not green boxes: symbol_facts carries a big row count + size.
let symbol_facts = tables
.iter()
.find(|t| t["table"] == "symbol_facts")
.unwrap();
let has_real_numbers = symbol_facts["row_count"].as_i64().unwrap_or(0) > 1000
&& symbol_facts["byte_size"].as_i64().unwrap_or(0) > 1_000_000;
// the regression is flagged: embeddings empty + regression:true + named in the roll-up.
let emb = tables.iter().find(|t| t["table"] == "embeddings").unwrap();
let flags_regression = emb["empty"] == true
&& emb["regression"] == true
&& st["complete"] == false
&& st["regression_count"].as_u64().unwrap_or(0) >= 3
&& st["empty_regressions"]
.as_array()
.unwrap()
.iter()
.any(|t| t == "embeddings");
// an allowlisted-empty table is NOT a regression (honest allowlist).
let yank = tables.iter().find(|t| t["table"] == "yank_events").unwrap();
let allowlist_ok = yank["empty"] == true && yank["regression"] == false;
let drivable = st["component"] == "WarehouseHealthView"
// The doc is handed straight in, so this is a real fetched reply as far as
// the pane is concerned — `"fixture"` is not a source any more.
&& st["source"] == "workspace-run"
&& st.get("health_empty").map(|v| v.is_null()).unwrap_or(true)
&& has_real_numbers
&& flags_regression
&& allowlist_ok;
assert!(
drivable,
"Warehouse Health pane shows real numbers + flags the empty index types: {st}"
);
facett_core::testmatrix::emit(
"dwarves-embed::warehousehealth",
"warehouse_health_pane_shows_real_numbers_and_flags_empty_index_types",
drivable,
"Warehouse Health backoffice pane (Mímir menu): every table's REAL row count + byte size + \
last-populated snapshot over Panel::state_json, red-flagging index types that filled ZERO \
rows outside the empty-until-triggered allowlist (the 2026-07-24 embeddings regression)",
);
}
/// RED-when-broken (the GATE): a workspace with a REAL health file reflects
/// THOSE numbers, not the fixture — including a COMPLETE warehouse flipping the
/// banner green.
#[test]
fn workspace_file_reflects_over_the_fixture() {
let ws = "dwarves-wh-health-test-ws";
let path = workspace_health_path(ws);
let _ = std::fs::remove_file(&path);
let doc = WarehouseHealthDoc {
stats: vec![TableHealthRow {
table: "symbol_facts".into(),
row_count: 42,
byte_size: 4096,
last_snapshot_ms: 1_753_000_000_000,
empty: false,
allowlisted: false,
reason: String::new(),
}],
complete: true,
empty_regressions: Vec::new(),
summary: "populate completeness: 1/1 expected tables filled".into(),
};
std::fs::write(&path, serde_json::to_string(&doc).unwrap()).unwrap();
let pane = warehouse_health_panel(ws);
let st = pane.state_json();
let ok = st["selected_workspace"] == ws
&& st["source"] == "workspace-run"
&& st["complete"] == true
&& st["regression_count"] == 0
&& st["table_count"] == 1
&& st["tables"][0]["row_count"] == 42;
assert!(
ok,
"the pane reflects the seeded health file, not the fixture: {st}"
);
let _ = std::fs::remove_file(&path);
}
#[test]
fn human_bytes_and_snapshot_render() {
assert_eq!(human_bytes(0), "0 B");
assert_eq!(human_bytes(-1), "?");
assert_eq!(human_bytes(1024), "1.0 KB");
assert!(human_bytes(157_005_137).ends_with("MB"));
assert_eq!(human_snapshot(0), "never");
assert!(human_snapshot(1_753_000_000_000).starts_with('@'));
}
}