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

nordisk/edda

crates/nornir-docgen/src/sections.rs

//! Section-level docs assembly.
//!
//! Looks for paired markers in a Markdown file:
//!
//! ```text
//! <!-- nornir:gen:start:bench -->
//!   ... auto-generated ...
//! <!-- nornir:gen:end:bench -->
//! ```
//!
//! Each `start` marker carries a section name and optional `key=value` args:
//!
//! ```text
//! <!-- nornir:gen:start:symbols binary=target/debug/foo limit=20 -->
//! ```
//!
//! Renderers (keyed by section name):
//!   - `bench`     — flat table from the latest [`BenchRun`] (back-compat).
//!   - `benches`   — pivot table from the latest [`BenchRun`]. `winner=col`
//!                   (default) bolds the best cell per row across same-unit rival
//!                   columns (ours-vs-legacy); `winner=row` bolds the best cell
//!                   down each column across rival rows (which system wins each
//!                   metric — for cross-system comparisons). `mode=compact`
//!                   collapses all rivals to one synthetic "best-of" row (absurd-
//!                   best value per column); `top=N` keeps the N strongest rows
//!                   by `rank=METRIC` — the tight top-of-README mashup.
//!   - `mashup`    — ZERO-CONFIG top-of-README comparison: auto-discovers *ours*
//!                   + every rival system from the latest [`BenchRun`] and renders
//!                   the N-way `compare`/`winner=row` table itself (no `compare=`
//!                   to hand-list), plus a biggest-diff headline. All args optional.
//!   - `bench_chart` — horizontal bar chart for one `metric=` across the matching
//!                   workloads, winner highlighted; an SVG asset (`export`) or
//!                   a unicode-bar text fallback. The "featured mashup" visual.
//!   - `bench_status` — the run's **provenance + honesty header**, and the one
//!                   place a repo with NO numbers still renders a statement
//!                   instead of a silent gap: version · host · cores · date, arm
//!                   and test counts, a PREVIEW banner when the harness declared
//!                   its own run unpublishable, and the arms screened out as not
//!                   credible as real work. Takes no arguments — with no run it
//!                   probes the repo for a `nornir-bench` entrypoint / criterion
//!                   `[[bench]]` targets and renders "not benched" with the
//!                   reason. See [`super::bench_status`].
//!   - `tests`     — unit/integration/doc test inventory (via `syn`).
//!   - `depgraph`  — workspace crate-dependency graph. With feature
//!                   `export`: rendered as static SVG (typst engine)
//!                   under `<repo_root>/.nornir/assets/depgraph.svg` (a
//!                   tracked path, so the link resolves on git hosts) and
//!                   referenced via a Markdown image link. Without the
//!                   feature: falls back to a self-contained inline SVG
//!                   (no JS, no build step — never Mermaid).
//!   - `symbols`   — top public symbols extracted from a binary (DWARF).
//!   - `callgraph` — most-called callees from a binary (DWARF inline edges).
//!   - `capabilities` — a ✓/✗ **static-capability matrix** built from a
//!                   [`BenchSource::Static`](nornir_bench::BenchSource) row's
//!                   `cap.<slug>.<rival>` numeric keys (the seam any repo emits
//!                   via [`BenchResult::static_capabilities`](nornir_bench::BenchResult)).
//!                   Rows are capabilities, columns are `ours` + rivals, the
//!                   `ours` column is bold: `source=<bench-name>` names the row,
//!                   `ours=<key>` picks our column (default: `source` minus a
//!                   trailing `.capabilities`).

use std::collections::HashMap;
use std::path::{Path, PathBuf};

use anyhow::{Context, Result, anyhow, bail};

use nornir_bench::BenchRun;
use nornir_introspect::{artifact, callgraph_dwarf, depgraph};

/// Outcome of an assemble run on one file.
#[derive(Debug, Default)]
pub struct FileReport {
    pub path: PathBuf,
    pub sections: Vec<String>,
    pub changed: bool,
}

/// Context passed to section renderers.
pub struct Ctx<'a> {
    pub repo_root: &'a Path,
    pub workspace_root: &'a Path,
    pub run: Option<&'a BenchRun>,
    /// Bench-run history (newest-first not assumed; the renderer sorts), used by
    /// the `bench_history` section. Pre-fetched by the caller — renderers must not
    /// open the warehouse themselves (the server already holds its single lock).
    /// Empty by default; populate via [`with_history`](Self::with_history).
    pub history: &'a [BenchRun],
    /// Directory of the doc currently being rendered, when known. Used to emit
    /// **doc-relative** asset links (e.g. the `depgraph` SVG) so an image
    /// embedded in `.nornir/design.md` points at `assets/depgraph.svg`, while
    /// the same section in the repo-root `README.md` points at
    /// `.nornir/assets/depgraph.svg`. Git hosts resolve image paths relative to
    /// the containing file, so this must track it. `None` ⇒ repo-root-relative
    /// (the historical default, correct for README).
    pub doc_dir: Option<&'a Path>,
    /// Pre-fetched source-coverage rows for the `coverage` section (feature N —
    /// `nornir:gen:coverage`). Pre-fetched by the caller (renderers must not open
    /// the warehouse). Empty by default; populate via [`with_coverage`](Self::with_coverage).
    pub coverage: &'a [nornir_coverage::CoverageRow],
    /// Markdown-only mode: never (re)write the heavy/non-deterministic media
    /// assets (`depgraph.svg`, bench-chart SVGs) to `.nornir/assets/`. The
    /// markdown still emits the image link (the asset is committed from a prior
    /// full render), so the README/CHANGELOG text stays deterministic. This is
    /// what the **pre-commit hook** uses so an ordinary commit never regenerates
    /// the noisy SVG/PDF — only `docs render` / the release backstop do.
    /// `false` ⇒ historical behaviour (assets are (re)written on render).
    pub no_assets: bool,
    /// Manual (thin-book) mode: when assembling the whole-doc book, include only
    /// the authoritative **manual** classes — README/CHANGELOG front matter plus
    /// `design` / `guide` / benchmark chapters — and EXCLUDE the non-manual
    /// back-matter (`*-reasoning.md`, `*-history.md`, `*-unsorted.md`,
    /// `*-for-idiots.md` / `*-for-dummies.md`, `docs-generation.md`, and the
    /// `Tankegångar` catch-all). This is the doctrine's thin manual — it keeps the
    /// shipped `docs/book.pdf` small (Codeberg space) without deleting any source;
    /// the reasoning/history still live in `.nornir/`. `false` ⇒ full assembly.
    pub manual: bool,
    /// The **network half** of path-dep prep for the `depgraph` section, injected
    /// by the caller so this crate stays free of any network/git-clone coupling:
    /// given `(repo_root, scan_root)` it clones any missing sibling repo into
    /// `scan_root` and returns how many it fetched (the same seam
    /// [`nornir_introspect::depgraph::extract_with_path_deps`] takes). nornir's
    /// CLI/server inject `security::clone_missing_path_dep_siblings`; `None`
    /// (the default) behaves as `|_, _| 0` — pure symlink materialization only,
    /// exactly what a unit test or an offline caller wants. Populate via
    /// [`with_path_dep_cloner`](Self::with_path_dep_cloner).
    pub path_dep_cloner: Option<&'a (dyn Fn(&Path, &Path) -> usize + Sync)>,
    /// The **kernel evidence reader** for the AI context pack (kernel tooling
    /// fix 16), injected by the caller so this leaf never links the build
    /// engine: given the repo root it returns the generated "Kernel evidence"
    /// Markdown section, `None` when the repo has no kernel evidence. nornir
    /// injects edda `nornir_build_thing::kernel_facts::ai_section`. `None` (the
    /// default) ⇒ no section. Populate via [`with_kernel_facts`](Self::with_kernel_facts).
    pub kernel_facts: Option<&'a (dyn Fn(&Path) -> anyhow::Result<Option<String>> + Sync)>,
}

impl<'a> Ctx<'a> {
    pub fn new(repo_root: &'a Path, workspace_root: &'a Path, run: Option<&'a BenchRun>) -> Self {
        Ctx {
            repo_root,
            workspace_root,
            run,
            history: &[],
            doc_dir: None,
            coverage: &[],
            no_assets: false,
            manual: false,
            path_dep_cloner: None,
            kernel_facts: None,
        }
    }

    /// Manual (thin-book) mode — exclude non-manual back-matter from the assembled
    /// book. See [`Ctx::manual`].
    pub fn manual(mut self) -> Self {
        self.manual = true;
        self
    }

    /// Markdown-only render: skip writing the heavy/non-deterministic SVG/PDF
    /// assets (see [`Ctx::no_assets`]). Used by the pre-commit hook.
    pub fn markdown_only(mut self) -> Self {
        self.no_assets = true;
        self
    }

    /// Attach pre-fetched bench-run history for the `bench_history` section.
    pub fn with_history(mut self, history: &'a [BenchRun]) -> Self {
        self.history = history;
        self
    }

    /// Attach pre-fetched source-coverage rows for the `coverage` section
    /// (feature N). The caller reads the latest `coverage` run from the warehouse
    /// and passes its rows; the renderer turns them into the maven-style table.
    pub fn with_coverage(
        mut self,
        coverage: &'a [nornir_coverage::CoverageRow],
    ) -> Self {
        self.coverage = coverage;
        self
    }

    /// Set the directory of the doc being rendered, so asset links are emitted
    /// relative to it. See [`Ctx::doc_dir`].
    pub fn with_doc_dir(mut self, doc_dir: &'a Path) -> Self {
        self.doc_dir = Some(doc_dir);
        self
    }

    /// Inject the network half of path-dep prep for the `depgraph` section
    /// (clone missing sibling repos into the scan root). See
    /// [`Ctx::path_dep_cloner`]. Absent ⇒ no cloning, symlink materialization only.
    pub fn with_path_dep_cloner(
        mut self,
        cloner: &'a (dyn Fn(&Path, &Path) -> usize + Sync),
    ) -> Self {
        self.path_dep_cloner = Some(cloner);
        self
    }

    /// Inject the kernel evidence reader for the AI context pack. See
    /// [`Ctx::kernel_facts`].
    pub fn with_kernel_facts(
        mut self,
        reader: &'a (dyn Fn(&Path) -> anyhow::Result<Option<String>> + Sync),
    ) -> Self {
        self.kernel_facts = Some(reader);
        self
    }
}

#[derive(Debug)]
struct Marker {
    line_start: usize,
    line_end: usize,
    name: String,
    args: HashMap<String, String>,
}

const START: &str = "<!-- nornir:gen:start:";
const END: &str = "<!-- nornir:gen:end:";

/// Split a marker body into tokens on whitespace, but keep a double-quoted span
/// together so an arg value may contain spaces (`title="catalog reads (ops/s)"`).
/// The surrounding quotes are stripped from the token.
fn tokenize_marker(s: &str) -> Vec<String> {
    let mut out = Vec::new();
    let mut cur = String::new();
    let mut in_q = false;
    let mut started = false;
    for c in s.chars() {
        match c {
            '"' => {
                in_q = !in_q;
                started = true;
            }
            c if c.is_whitespace() && !in_q => {
                if started {
                    out.push(std::mem::take(&mut cur));
                    started = false;
                }
            }
            c => {
                cur.push(c);
                started = true;
            }
        }
    }
    if started {
        out.push(cur);
    }
    out
}

fn parse_markers(text: &str) -> Result<Vec<(Marker, usize)>> {
    let lines: Vec<&str> = text.split_inclusive('\n').collect();
    let mut open: Vec<(usize, String, HashMap<String, String>)> = Vec::new();
    let mut out: Vec<(Marker, usize)> = Vec::new();
    let mut in_fence = false;
    for (i, line) in lines.iter().enumerate() {
        let t = line.trim();
        // Toggle fenced-code-block state. We track both ``` and ~~~ fences;
        // any marker lines *inside* a fence are documentation examples and
        // must be left alone.
        if t.starts_with("```") || t.starts_with("~~~") {
            in_fence = !in_fence;
            continue;
        }
        if in_fence {
            continue;
        }
        if let Some(rest) = t.strip_prefix(START) {
            let body = rest
                .strip_suffix("-->")
                .ok_or_else(|| anyhow!("malformed start marker at line {}: {t}", i + 1))?
                .trim();
            let mut parts = tokenize_marker(body).into_iter();
            let name = parts
                .next()
                .ok_or_else(|| anyhow!("missing section name at line {}", i + 1))?;
            let mut args = HashMap::new();
            for kv in parts {
                if let Some((k, v)) = kv.split_once('=') {
                    args.insert(k.to_string(), v.to_string());
                }
            }
            open.push((i, name, args));
        } else if let Some(rest) = t.strip_prefix(END) {
            let name = rest
                .strip_suffix("-->")
                .ok_or_else(|| anyhow!("malformed end marker at line {}: {t}", i + 1))?
                .trim()
                .to_string();
            let (start_i, start_name, args) = open
                .pop()
                .ok_or_else(|| anyhow!("unmatched end marker `{name}` at line {}", i + 1))?;
            if start_name != name {
                bail!(
                    "marker mismatch: start `{start_name}` at line {} vs end `{name}` at line {}",
                    start_i + 1,
                    i + 1
                );
            }
            out.push((
                Marker {
                    line_start: start_i,
                    line_end: i,
                    name,
                    args,
                },
                0,
            ));
        }
    }
    if let Some((i, name, _)) = open.pop() {
        bail!("unclosed marker `{name}` opened at line {}", i + 1);
    }
    Ok(out)
}

/// The "I have no fresh data" bodies a renderer emits when its source is empty:
/// no bench run at all (warehouse unreachable, never benched), no result matching
/// the marker's `name=`/`exclude=` filter in *this* run, or no capability row.
///
/// These are **absence markers, not content**. Splicing one over a section that
/// already holds a real rendered table destroys hard-won benchmark numbers that
/// simply have no live source right now — a bench that wasn't re-run, a rival arm
/// dropped from the latest sweep, a warehouse that was down when the pre-commit
/// hook fired. Docs generation must never be destructive: see
/// [`is_no_data_placeholder`] and its use in [`render`].
///
/// Author-error bodies (`_(bench_hero needs `fast=` …)_`) are deliberately NOT in
/// this list — a malformed marker should stay visible so it gets fixed.
/// ⚠ THE SIXTH ONE WAS MISSING, and it cost real numbers (measured 2026-08-01 on
/// nornir's own README — see [`super::bench_status::NOT_BENCHED_PREFIX`]). The
/// `bench_status` card's absence body opens `**Not benched.**`, not `_(no …`, so it
/// was classified as CONTENT and spliced over a real measured card while the
/// `benches` table two lines above it — whose placeholder IS listed — was correctly
/// preserved. A half-protected doc reads as a protected one.
///
/// The entry is the renderer's OWN constant, not a copy of its wording, so the
/// prose can be reworded without silently falling out of this list.
const NO_DATA_PREFIXES: [&str; 6] = [
    "_(no bench history yet",
    "_(no bench results",
    "_(no capability matrix yet",
    "_(no `",
    "_(no coverage recorded",
    super::bench_status::NOT_BENCHED_PREFIX,
];

/// Is `body` a renderer's "no fresh data" placeholder rather than real content?
///
/// Matches on the leading placeholder run so a multi-line body that *starts* with
/// content is never mistaken for absence.
pub(crate) fn is_no_data_placeholder(body: &str) -> bool {
    let t = body.trim();
    if t.is_empty() {
        return true;
    }
    NO_DATA_PREFIXES.iter().any(|p| t.starts_with(p))
}

/// Render one section. `prev_body` is the section's existing content (everything
/// strictly between its start and end markers), used to make generation
/// **non-destructive**: when the renderer has no fresh data but the section already
/// holds a real table, the existing body is kept instead of being blanked.
fn render(ctx: &Ctx, m: &Marker, prev_body: &str) -> Result<String> {
    let body = match m.name.as_str() {
        "bench" => render_bench(ctx, &m.args)?,
        "bench_history" => render_bench_history(ctx, &m.args)?,
        "benches" => render_benches(ctx, &m.args)?,
        "bench_chart" => render_bench_chart(ctx, &m.args)?,
        "bench_hero" => render_bench_hero(ctx, &m.args)?,
        "bench_status" => super::bench_status::render(ctx, &m.args)?,
        "mashup" => render_mashup(ctx, &m.args)?,
        "tests" => render_tests(ctx, &m.args)?,
        "coverage" => render_coverage(ctx, &m.args)?,
        "capabilities" => render_capabilities(ctx, &m.args)?,
        "depgraph" => render_depgraph(ctx)?,
        "symbols" => render_symbols(ctx, &m.args)?,
        "callgraph" => render_callgraph(ctx, &m.args)?,
        other => bail!("unknown section `{other}`"),
    };
    // NON-DESTRUCTIVE GENERATION: a renderer with no fresh data must never
    // overwrite a section that already has a body. Keep what is committed; the next
    // render with live bench data replaces it normally.
    //
    // This deliberately also keeps an existing *placeholder* rather than swapping it
    // for a differently-worded one. Absence is absence — rewording it changes no
    // fact, but it does leave the file dirty after every render, and a doc that is
    // perpetually dirty is one people stage blindly. That habit is how the real
    // tables got committed away in the first place.
    let body = if is_no_data_placeholder(&body) && !prev_body.trim().is_empty() {
        prev_body.to_string()
    } else {
        body
    };
    let mut out = String::new();
    out.push_str("<!-- nornir:gen:start:");
    out.push_str(&m.name);
    for (k, v) in args_sorted(&m.args) {
        out.push(' ');
        out.push_str(&k);
        out.push('=');
        // Re-quote values that carry spaces so the round-trip re-parses (see
        // `tokenize_marker`).
        if v.chars().any(char::is_whitespace) {
            out.push('"');
            out.push_str(&v);
            out.push('"');
        } else {
            out.push_str(&v);
        }
    }
    out.push_str(" -->\n");
    out.push_str(body.trim_end());
    out.push('\n');
    out.push_str("<!-- nornir:gen:end:");
    out.push_str(&m.name);
    out.push_str(" -->\n");
    Ok(out)
}

fn args_sorted(a: &HashMap<String, String>) -> Vec<(String, String)> {
    let mut v: Vec<(String, String)> = a.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
    v.sort_by(|a, b| a.0.cmp(&b.0));
    v
}

/// Rewrite `path` in place by replacing every section between paired markers.
pub fn assemble_file(path: &Path, ctx: &Ctx) -> Result<FileReport> {
    let text = std::fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?;
    // Scope the context to this doc's directory so asset links (depgraph SVG)
    // are emitted relative to where the file lives.
    let parent = path.parent().map(|p| p.to_path_buf());
    let scoped = match parent.as_deref() {
        Some(dir) => Ctx {
            doc_dir: Some(dir),
            ..*ctx
        },
        None => Ctx { ..*ctx },
    };
    let (new_text, sections) = rewrite(&text, &scoped)?;
    let changed = new_text != text;
    if changed {
        std::fs::write(path, &new_text).with_context(|| format!("write {}", path.display()))?;
    }
    Ok(FileReport {
        path: path.to_path_buf(),
        sections,
        changed,
    })
}

/// Like [`assemble_file`] but errors out (non-zero exit) if rewriting would
/// change the file. Use in CI / release gates.
pub fn check_file(path: &Path, ctx: &Ctx) -> Result<FileReport> {
    let text = std::fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?;
    let (new_text, sections) = rewrite(&text, ctx)?;
    if new_text != text {
        bail!(
            "{} is out of date — run `nornir docs assemble` to regenerate",
            path.display()
        );
    }
    Ok(FileReport {
        path: path.to_path_buf(),
        sections,
        changed: false,
    })
}

/// Like [`assemble_file`] / [`check_file`], but in-memory: returns the
/// rewritten text and the names of sections that were filled.
pub fn rewrite_str(text: &str, ctx: &Ctx) -> Result<(String, Vec<String>)> {
    rewrite_with_fallback(text, ctx, None)
}

/// Like [`rewrite_str`], but with the PREVIOUSLY RENDERED OUTPUT as the fallback
/// source of existing section bodies.
///
/// A MANAGED doc (`README.md`, `CHANGELOG.md`) is generated: `.nornir/README.md` is
/// a template whose `nornir:gen` markers are *intentionally empty*, and the filled
/// result is written to `<repo>/README.md`. So for those docs the rendered tables
/// live ONLY in the output — which means the non-destructive rule in [`render`] had
/// nothing to protect: `prev_body` came from the template and was always empty, the
/// no-data placeholder always won, and the output's real numbers were overwritten.
///
/// Observed 2026-07-22 on znippy-zoomies: with no warehouse rows reachable,
/// `nornir docs render` replaced **58 lines** of committed, measured bench tables
/// with 9 `_(no bench history yet …)_` placeholders. That is the same data loss the
/// in-place guard already prevents, arriving through the generated-output door — and
/// it had destroyed skade's whole benchmark set once before.
///
/// Sections are matched between output and template by their START MARKER LINE,
/// which carries the marker's full argument list (`compare=`, `cols=`, …) and so
/// distinguishes the many sibling `benches` blocks a README carries.
pub fn rewrite_str_against_output(
    text: &str,
    ctx: &Ctx,
    prev_output: &str,
) -> Result<(String, Vec<String>)> {
    rewrite_with_fallback(text, ctx, Some(prev_output))
}

/// Fill markers using only `text`'s own bodies. Correct for an IN-PLACE source —
/// a `.nornir/*.md` that is itself the published file, so its markers already hold
/// whatever was last rendered and there is no separate output to consult.
fn rewrite(text: &str, ctx: &Ctx) -> Result<(String, Vec<String>)> {
    rewrite_with_fallback(text, ctx, None)
}

/// A marker's identity: its name plus its arguments in a canonical order.
///
/// NOT the raw marker line. The renderer re-emits arguments SORTED, so the same
/// section reads `compare=… winner=… cols=…` in the hand-written source and
/// `cols=… compare=… winner=…` in the generated output. Keying on the raw text
/// therefore never matches across that boundary — which is exactly how the first
/// version of this fallback silently did nothing while looking correct.
fn marker_key(m: &Marker) -> String {
    let mut args: Vec<(&String, &String)> = m.args.iter().collect();
    args.sort();
    let mut k = m.name.clone();
    for (a, v) in args {
        k.push('\u{1}');
        k.push_str(a);
        k.push('=');
        k.push_str(v);
    }
    k
}

/// Existing section bodies in `text`, keyed by [`marker_key`]. Best effort: an
/// unparseable previous output yields no fallbacks, so a corrupt README can never
/// block a render.
fn bodies_by_marker(text: &str) -> HashMap<String, String> {
    let mut map = HashMap::new();
    let Ok(markers) = parse_markers(text) else {
        return map;
    };
    let lines: Vec<&str> = text.split_inclusive('\n').collect();
    for (m, _) in &markers {
        let body: String = lines[m.line_start + 1..m.line_end].concat();
        map.insert(marker_key(m), body);
    }
    map
}

fn rewrite_with_fallback(
    text: &str,
    ctx: &Ctx,
    prev_output: Option<&str>,
) -> Result<(String, Vec<String>)> {
    let markers = parse_markers(text)?;
    if markers.is_empty() {
        return Ok((text.to_string(), Vec::new()));
    }
    let fallback = prev_output.map(bodies_by_marker).unwrap_or_default();
    let lines: Vec<&str> = text.split_inclusive('\n').collect();
    let mut out = String::new();
    let mut cursor = 0usize;
    let mut sections = Vec::new();
    for (m, _) in &markers {
        for l in &lines[cursor..m.line_start] {
            out.push_str(l);
        }
        // The section's existing body — everything strictly between the paired
        // markers. Handed to `render` so a no-fresh-data render preserves it
        // instead of blanking real benchmark tables.
        //
        // For a MANAGED doc the template's own body is empty BY DESIGN, so fall back
        // to the same section in the previously rendered OUTPUT — that is where the
        // numbers actually are.
        let mut prev_body: String = lines[m.line_start + 1..m.line_end].concat();
        if prev_body.trim().is_empty()
            && let Some(prev) = fallback.get(&marker_key(m))
        {
            prev_body = prev.clone();
        }
        out.push_str(&render(ctx, m, &prev_body)?);
        sections.push(m.name.clone());
        cursor = m.line_end + 1;
    }
    for l in &lines[cursor..] {
        out.push_str(l);
    }
    Ok((out, sections))
}

// ----- renderers -------------------------------------------------------------

/// Legacy flat renderer: one row per (result, metric). Kept so existing
/// `bench` markers keep working; new docs should prefer `benches`.
/// The bolded run-context line shown above a bench table: version · machine ·
/// cores · date. `machine` is recorded from `NORNIR_MACHINE`; omitted when empty.
fn bench_header(run: &BenchRun) -> String {
    let mut parts = vec![format!("v{}", run.version)];
    if !run.machine.is_empty() {
        parts.push(run.machine.clone());
    }
    parts.push(format!("{} cores", run.cores));
    if !run.date.is_empty() {
        parts.push(run.date.clone());
    }
    format!("**{}**\n\n", parts.join(" · "))
}

/// The run a bench section is ALLOWED to render.
///
/// A **preview** run — one whose harness stamped [`super::bench_status::PREVIEW_TOKEN`]
/// into `machine` because its input was under the heavy floor it requires, and so
/// refused to emit a publishable row — is INVISIBLE to an ordinary bench marker.
/// It reads as "no fresh data", which the non-destructive guard in [`render`] turns
/// into "keep the committed table". That is the whole point: a preview pass on a
/// bigger box must never quietly replace measured, published numbers taken on
/// another host. znippy-zoomies' README carries real 12-core `loki` tables; an
/// under-floor 32-core `oden` preview would otherwise have overwritten every one of
/// them with numbers the harness had explicitly declined to publish.
///
/// A section that WANTS the preview (a clearly-labelled preview block) opts in with
/// `preview=yes`. `bench_status` is exempt — stating the refusal is its job.
fn usable_run<'a>(ctx: &'a Ctx, args: &HashMap<String, String>) -> Option<&'a BenchRun> {
    let run = ctx.run?;
    let opted_in = matches!(
        args.get("preview").map(|s| s.as_str()),
        Some("yes" | "only" | "allow" | "true")
    );
    if super::bench_status::is_preview(run) && !opted_in {
        return None;
    }
    Some(run)
}

fn render_bench(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let Some(run) = usable_run(ctx, args) else {
        return Ok(
            "_(no bench history yet — run a benchmark to populate this section)_\n".to_string(),
        );
    };
    let mut out = String::new();
    out.push_str(&bench_header(run));
    if run.results.is_empty() {
        out.push_str("_(no bench results)_\n");
        return Ok(out);
    }
    out.push_str("| name | metric | value |\n|------|--------|-------|\n");
    let mut rows: Vec<(String, String, f64)> = Vec::new();
    for r in &run.results {
        for (k, v) in &r.metrics {
            if let Some(f) = v.as_f64() {
                rows.push((r.name.clone(), k.clone(), f));
            }
        }
    }
    rows.sort_by(|a, b| a.0.cmp(&b.0).then(a.1.cmp(&b.1)));
    for (n, k, v) in rows {
        out.push_str(&format!("| {n} | {k} | {v:.2} |\n"));
    }
    Ok(out)
}

/// `bench_history` renderer: one row per past bench run (newest first) from the
/// warehouse — `| Version | Date | Machine | <metric> |`. Reads the pre-fetched
/// [`Ctx::history`] (the caller fetches via `query_bench_runs`; renderers must not
/// open the warehouse). Makes the hand-maintained "Benchmark history" tables in
/// the holger/znippy READMEs obsolete.
///
/// Args:
/// - `limit=N` — keep only the N most recent runs (default 20).
/// - `metric=NAME` — show this metric's value per run (matched against each
///   result's metric key or result name); default is the run's max numeric metric.
fn render_bench_history(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    if ctx.history.is_empty() {
        return Ok(
            "_(no bench history yet — run benchmarks to populate this section)_\n".to_string(),
        );
    }
    let limit: usize = args.get("limit").and_then(|s| s.parse().ok()).unwrap_or(20);
    let metric = args.get("metric").map(|s| s.as_str());

    let mut runs: Vec<&BenchRun> = ctx.history.iter().collect();
    // Newest first by timestamp when present, else by the `date` string.
    runs.sort_by(|a, b| {
        let ka = a.timestamp.as_deref().unwrap_or(&a.date);
        let kb = b.timestamp.as_deref().unwrap_or(&b.date);
        kb.cmp(ka)
    });

    let metric_label = metric.unwrap_or("best metric");
    let mut out = String::new();
    out.push_str(&format!(
        "| Version | Date | Machine | {metric_label} |\n|---|---|---|---|\n"
    ));
    for run in runs.into_iter().take(limit) {
        let date = if run.date.is_empty() {
            "-"
        } else {
            run.date.as_str()
        };
        let machine = if run.machine.is_empty() {
            "-"
        } else {
            run.machine.as_str()
        };
        let val = best_metric(run, metric)
            .map(|v| format!("{v:.2}"))
            .unwrap_or_else(|| "-".to_string());
        out.push_str(&format!(
            "| v{} | {} | {} | {} |\n",
            run.version, date, machine, val
        ));
    }
    Ok(out)
}

/// Pick a representative metric value from a run: the named `metric` (matched on a
/// result's metric key or the result name) when given, else the max numeric metric.
fn best_metric(run: &BenchRun, metric: Option<&str>) -> Option<f64> {
    let mut best: Option<f64> = None;
    for r in &run.results {
        for (k, v) in &r.metrics {
            let Some(f) = v.as_f64() else { continue };
            let take = match metric {
                Some(name) => k == name || r.name == name,
                None => true,
            };
            if take {
                best = Some(best.map_or(f, |b| b.max(f)));
            }
        }
    }
    best
}

/// `benches` renderer: a pivot table (one row per result/workload, one column
/// per metric) that **bolds the winning cell** in each row. Cells that share a
/// unit (e.g. `ljar_mbs` + `unzip_mbs`, both `mbs`) form a comparison group;
/// within a group of ≥2 the best value (highest for `High`, lowest for `Low`)
/// is bolded. Direction is inferred from each metric's unit
/// (`nornir_bench::unit_of`); the `best=` marker arg overrides the odd cases.
/// This is what turns paired ours-vs-legacy metrics into a "how much faster"
/// table.
///
/// Optional args:
/// - `name=PAT` — keep only results whose name contains `PAT`.
/// - `exclude=PAT` — drop results whose name contains `PAT` (e.g. `_st`
///   single-core rows from a multi-core headline).
/// - `best=metric:low,other:high` — per-metric direction overrides (for units
///   the suffix convention can't classify, e.g. a `_pct` that's higher-better).
/// - `bold=false` — disable winner-bolding (for tables whose same-unit columns
///   aren't rivals, e.g. archive `compress_mbs` + `decompress_mbs`).
///
/// Compact "best-of mashup" modes (collapse many variants to a few standout
/// rows — for the tight 10-second-readable block at the top of a README):
/// - `mode=compact` — collapse **all** matched rows to a SINGLE synthetic
///   "best-of" row that takes the absurd-best value per column across every
///   variant (highest for `High` metrics, lowest for `Low`; `Neutral` columns
///   are dropped — there's no "best" count to cherry-pick). The row label is
///   `best-of` unless `label=` overrides it. Honours `name=`/`exclude=`/`compare=`
///   first, so `mode=compact compare=skade_s3,nessie,polaris` distils exactly
///   those rivals into one champion line. Combine with `winner=row` to also bold
///   the (single) cell — though with one row every populated cell is the winner.
/// - `top=N` — keep only the N strongest rows, ranked by `rank=METRIC` (defaults
///   to the first throughput-like column, e.g. `ops_sec`/`*_per_sec`; direction
///   inferred from the unit, so latency ranks ascend). Use it to show "the 3
///   fastest backends" without hand-picking. `top=` applies after `compare=`.
///
/// Meaty-first column ranking for the crisp `compare=` mashup: throughput rates
/// lead, then headline latency (p50 → p90 → p99 → p999), then mean/min/max, with
/// everything else in the middle. Lower sorts further left. Ties break
/// alphabetically (see the caller).
fn col_rank(col: &str) -> u8 {
    if col == "ops_sec" || col.ends_with("_per_sec") {
        0
    } else if col.starts_with("p50") {
        10
    } else if col.starts_with("p90") {
        11
    } else if col.starts_with("p999") {
        13
    } else if col.starts_with("p99") {
        12
    } else if col.starts_with("mean") {
        20
    } else if col.starts_with("min") {
        21
    } else if col.starts_with("max") {
        22
    } else {
        15
    }
}

/// Does bench-arm `name` match a `compare=`/`self=` directive `token`? A token
/// matches ONLY when it equals the whole arm id OR appears as a WORD-BOUNDED segment
/// of it — delimited on both sides by a non-alphanumeric separator (`_`/`-`) or a
/// string edge — NEVER as a bare letter-adjacent substring.
///
/// This is the H3 fix: the rival compressor names are plain substrings of our arm
/// ids (`bzip2` ⊂ `lbzip2` ⊂ `zoomies-lbzip2`, `jar` ⊂ `zoomies-jar`, `zip` ⊂
/// `zoomies-zip`), so a plain `.contains()` let `compare=bzip2` mis-map the rival
/// row onto ours (the `bzip2` row printed `zoomies-lbzip2`'s number). Word-bounded
/// matching rejects `bzip2` inside `lbzip2` (the `l` is letter-adjacent — no
/// boundary) while still folding a variant family like `skade_s3` →
/// `data_pipe_skade_s3` (the `_` before `skade` IS a boundary), so the skade/holger
/// mashup tables that rely on that folding keep working. No arm is renamed.
fn token_matches(name: &str, token: &str) -> bool {
    if token.is_empty() {
        return false;
    }
    if name == token {
        return true;
    }
    let nb = name.as_bytes();
    let tb = token.as_bytes();
    if tb.len() > nb.len() {
        return false;
    }
    let boundary = |b: Option<&u8>| b.is_none_or(|c| !c.is_ascii_alphanumeric());
    let mut i = 0;
    while i + tb.len() <= nb.len() {
        if &nb[i..i + tb.len()] == tb
            && boundary(i.checked_sub(1).map(|p| &nb[p]))
            && boundary(nb.get(i + tb.len()))
        {
            return true;
        }
        i += 1;
    }
    false
}

fn render_benches(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    use nornir_bench::{MetricDirection, direction_of, unit_of};
    let Some(run) = usable_run(ctx, args) else {
        return Ok(
            "_(no bench history yet — run a benchmark to populate this section)_\n".to_string(),
        );
    };
    let overrides = parse_best_overrides(args.get("best").map(|s| s.as_str()));
    // `bold=false` disables winner-bolding — for tables whose same-unit columns
    // aren't rivals (e.g. archive `compress_mbs` + `decompress_mbs`).
    let bold_enabled = args.get("bold").map(|v| v != "false").unwrap_or(true);
    // `winner=` picks the comparison axis:
    //   `col` (default) — rows are workloads, columns are rivals sharing a unit;
    //                     bold the best cell *within each row* (ours-vs-legacy).
    //   `row`           — rows are rivals (systems/backends) for one workload,
    //                     columns are distinct metrics; bold the best cell *down
    //                     each column* by that metric's direction (which system
    //                     wins each metric). Use for cross-system comparisons.
    let winner_by_row = matches!(args.get("winner").map(|s| s.as_str()), Some("row" | "rows"));
    // `self=TOK[,TOK...]` — which system(s) are *ours*. Only used to break winner
    // ties in ours' favour (see the `winner=row` block); absent ⇒ no preference.
    let ours_tokens: Vec<String> = args
        .get("self")
        .map(|s| {
            s.split(',')
                .map(str::trim)
                .filter(|t| !t.is_empty())
                .map(str::to_string)
                .collect()
        })
        .unwrap_or_default();
    let filter = args.get("name").map(|s| s.as_str());
    let exclude = args.get("exclude").map(|s| s.as_str());
    // `suspect=` — what to do with arms [`bench_status::suspect_reasons`] judges
    // NOT CREDIBLE as real work (a rate divided by a sub-timing-floor interval; a
    // parallel speedup above the core count). `flag` (default) keeps the row and
    // marks the name ⚠ with a rendered footnote; `exclude` withholds it entirely
    // and says so under the table; `off` restores the unscreened behaviour.
    //
    // The screen is DERIVED, never a hand-listed `exclude=` of arm names — a hand
    // list is a copy of the data and goes stale the next time the bench moves.
    let suspect_mode = args.get("suspect").map(|s| s.as_str()).unwrap_or("flag");
    let flagged: std::collections::HashMap<&str, Vec<String>> = if suspect_mode == "off" {
        std::collections::HashMap::new()
    } else {
        super::bench_status::suspects(run)
            .into_iter()
            .map(|(r, w)| (r.name.as_str(), w))
            .collect()
    };
    let mut results: Vec<&nornir_bench::BenchResult> = run
        .results
        .iter()
        .filter(|r| filter.is_none_or(|p| r.name.contains(p)))
        .filter(|r| exclude.is_none_or(|p| !r.name.contains(p)))
        .filter(|r| suspect_mode != "exclude" || !flagged.contains_key(r.name.as_str()))
        .collect();
    // What the `exclude` mode actually withheld from THIS table (after `name=` /
    // `exclude=` narrowing), so the caveat under the table can never name a row the
    // table would not have shown anyway.
    let withheld: Vec<(&str, &Vec<String>)> = if suspect_mode == "exclude" {
        run.results
            .iter()
            .filter(|r| filter.is_none_or(|p| r.name.contains(p)))
            .filter(|r| exclude.is_none_or(|p| !r.name.contains(p)))
            .filter_map(|r| flagged.get(r.name.as_str()).map(|w| (r.name.as_str(), w)))
            .collect()
    } else {
        Vec::new()
    };
    if results.is_empty() {
        return Ok("_(no bench results)_\n".to_string());
    }
    // `compare=a,b,c` collapses the matches to exactly one row per named backend
    // token (first hit, in the given order) — the crisp N-way "mashup" table.
    // Use it to fold nornir's nvme/ram/s3 variants down to a single rival row
    // for a head-to-head vs Nessie / Polaris.
    if let Some(spec) = args.get("compare") {
        // Each token claims a DISTINCT row: an EXACT arm-id match first, then a
        // WORD-BOUNDED match ([`token_matches`]) — NEVER a bare substring. Exact-first
        // lets `compare=zoomies-jar,jar` give each token its own row; the word-bounded
        // fallback still folds a variant family (`skade_s3` → `data_pipe_skade_s3`)
        // WITHOUT letting `bzip2` steal `lbzip2`/`zoomies-lbzip2` (letter-adjacent, no
        // boundary — the H3 mis-map). Put the more specific token first to let it
        // claim its row.
        let mut used = vec![false; results.len()];
        let mut picked: Vec<&nornir_bench::BenchResult> = Vec::new();
        for t in spec.split(',').map(str::trim).filter(|t| !t.is_empty()) {
            let hit = (0..results.len())
                .find(|&i| !used[i] && results[i].name == t)
                .or_else(|| {
                    (0..results.len()).find(|&i| !used[i] && token_matches(&results[i].name, t))
                });
            if let Some(i) = hit {
                used[i] = true;
                picked.push(results[i]);
            }
        }
        if !picked.is_empty() {
            results = picked;
        }
    }

    // `top=N` — rank the matched rows by a chosen metric (direction-aware) and
    // keep only the strongest N. `rank=METRIC` selects the axis; default is the
    // first throughput-like column present (`ops_sec` / `*_per_sec`), falling
    // back to the first numeric column. Latency metrics (`Low`) rank ascending.
    if let Some(n) = args
        .get("top")
        .and_then(|v| v.parse::<usize>().ok())
        .filter(|n| *n > 0)
    {
        let rank_col = args
            .get("rank")
            .cloned()
            .or_else(|| {
                results.iter().find_map(|r| {
                    r.metrics
                        .keys()
                        .find(|k| {
                            r.metrics[*k].as_f64().is_some()
                                && (k.as_str() == "ops_sec" || k.ends_with("_per_sec"))
                        })
                        .cloned()
                })
            })
            .or_else(|| {
                results.iter().find_map(|r| {
                    r.metrics
                        .keys()
                        .find(|k| r.metrics[*k].as_f64().is_some())
                        .cloned()
                })
            });
        if let Some(col) = rank_col {
            let dir = direction_of(&overrides, &col);
            let key = |r: &&nornir_bench::BenchResult| r.metrics.get(&col).and_then(|v| v.as_f64());
            results.sort_by(|a, b| {
                let (av, bv) = (key(a), key(b));
                match (av, bv) {
                    (Some(x), Some(y)) => match dir {
                        // Best first: High → descending, else ascending.
                        MetricDirection::High => y.total_cmp(&x),
                        _ => x.total_cmp(&y),
                    },
                    (Some(_), None) => std::cmp::Ordering::Less,
                    (None, Some(_)) => std::cmp::Ordering::Greater,
                    (None, None) => std::cmp::Ordering::Equal,
                }
            });
            results.truncate(n);
        }
    }

    // `mode=compact` — collapse every matched row to ONE synthetic "best-of" row
    // that, per column, takes the absurd-best value across all variants (max for
    // `High`, min for `Low`; `Neutral` columns are skipped — there's no winning
    // count). Built for the tight top-of-README mashup. The owned row is held in
    // `compact_holder` so `results` can keep its `&` shape downstream.
    let compact_holder: Vec<nornir_bench::BenchResult>;
    if args.get("mode").map(|s| s.as_str()) == Some("compact") && !results.is_empty() {
        let mut cols: Vec<String> = Vec::new();
        for r in &results {
            for k in r.metrics.keys() {
                if r.metrics[k].as_f64().is_some() && !cols.contains(k) {
                    cols.push(k.clone());
                }
            }
        }
        let mut best = serde_json::Map::new();
        for c in &cols {
            let dir = direction_of(&overrides, c);
            if dir == MetricDirection::Neutral {
                continue; // no "best" count to cherry-pick
            }
            let vals: Vec<f64> = results
                .iter()
                .filter_map(|r| r.metrics.get(c).and_then(|v| v.as_f64()))
                .collect();
            let pick = match dir {
                MetricDirection::High => vals.iter().copied().reduce(f64::max),
                MetricDirection::Low => vals.iter().copied().reduce(f64::min),
                MetricDirection::Neutral => None,
            };
            if let Some(v) = pick {
                best.insert(c.clone(), serde_json::Value::from(v));
            }
        }
        let label = args
            .get("label")
            .cloned()
            .unwrap_or_else(|| "best-of".to_string());
        compact_holder = vec![nornir_bench::BenchResult {
            name: label,
            metrics: best,
            ..Default::default()
        }];
        results = compact_holder.iter().collect();
    }

    // Column order: first-seen across results (stable, deterministic).
    let mut columns: Vec<String> = Vec::new();
    for r in &results {
        for k in r.metrics.keys() {
            if r.metrics[k].as_f64().is_some() && !columns.contains(k) {
                columns.push(k.clone());
            }
        }
    }
    // `cols=a,b,c` — explicit ordered whitelist (meaty-first); keep only these,
    // in this order. Otherwise, for the crisp `compare=` mashup we (1) drop
    // columns that carry no signal — identical across every compared row, e.g. a
    // constant `encode_workers` that just echoes the core count already in the
    // header — and (2) float the meaty metrics (throughput, then latency) to the
    // left. Plain (non-`compare`) tables keep the full alphabetical breakdown.
    if let Some(spec) = args.get("cols") {
        let want: Vec<&str> = spec
            .split(',')
            .map(str::trim)
            .filter(|t| !t.is_empty())
            .collect();
        columns.retain(|c| want.iter().any(|w| *w == c));
        columns.sort_by_key(|c| want.iter().position(|w| *w == c).unwrap_or(usize::MAX));
    } else if args.contains_key("compare") && results.len() >= 2 {
        columns.retain(|c| {
            let vals: Vec<f64> = results
                .iter()
                .filter_map(|r| r.metrics.get(c).and_then(|v| v.as_f64()))
                .collect();
            // Keep unless it's present in every row and constant across them.
            !(vals.len() == results.len() && vals.windows(2).all(|w| w[0] == w[1]))
        });
        columns.sort_by(|a, b| col_rank(a).cmp(&col_rank(b)).then_with(|| a.cmp(b)));
    } else {
        columns.sort();
    }
    // `drop=a,b` — remove named columns after selection (data-driven, generic).
    // Lets a mashup strip FORMAT-level columns that don't belong in the story,
    // e.g. `drop=compress_mbs,ratio` on a *decompressor* mashup keeps only the
    // decode metrics. Applied last so it composes with `cols=`/`compare=`.
    if let Some(spec) = args.get("drop") {
        let unwanted: Vec<&str> = spec
            .split(',')
            .map(str::trim)
            .filter(|t| !t.is_empty())
            .collect();
        columns.retain(|c| !unwanted.iter().any(|w| *w == c));
    }

    let mut out = String::new();
    out.push_str(&bench_header(run));

    // Header.
    out.push_str("| workload |");
    for c in &columns {
        out.push_str(&format!(" {c} |"));
    }
    out.push('\n');
    out.push_str("|---|");
    for _ in &columns {
        out.push_str("---|");
    }
    out.push('\n');

    // Precompute the set of cells `(row_index, column)` to bold.
    let pick_best = |cells: &[(usize, f64)], dir: MetricDirection| -> Option<usize> {
        match dir {
            MetricDirection::High => cells.iter().max_by(|a, b| a.1.total_cmp(&b.1)),
            MetricDirection::Low => cells.iter().min_by(|a, b| a.1.total_cmp(&b.1)),
            MetricDirection::Neutral => None,
        }
        .map(|(i, _)| *i)
    };
    let mut bold: std::collections::HashSet<(usize, &String)> = std::collections::HashSet::new();
    if bold_enabled && winner_by_row {
        // Down each column: rivals (systems) compete on one metric. Bold the best
        // cell per column by that metric's direction; needs ≥2 rivals to compare.
        for c in &columns {
            let dir = direction_of(&overrides, c);
            if dir == MetricDirection::Neutral {
                continue;
            }
            let cells: Vec<(usize, f64)> = results
                .iter()
                .enumerate()
                .filter_map(|(i, r)| r.metrics.get(c).and_then(|v| v.as_f64()).map(|f| (i, f)))
                .collect();
            if cells.len() < 2 {
                continue;
            }
            if let Some(default_i) = pick_best(&cells, dir) {
                // On a TIE for the best value, favour OURS: if any row tied for the
                // winning value is ours, bold that one instead of the arbitrary
                // rival `pick_best` (max_by/min_by) happened to land on. With no
                // `self=`, or no ours in the tied-best set, keep the default cell.
                let best_val = cells
                    .iter()
                    .find(|(i, _)| *i == default_i)
                    .map(|(_, f)| *f)
                    .unwrap_or(f64::NAN);
                let chosen = cells
                    .iter()
                    .filter(|(_, f)| f.total_cmp(&best_val) == std::cmp::Ordering::Equal)
                    .map(|(i, _)| *i)
                    .find(|i| row_is_ours(&results[*i].name, &ours_tokens))
                    .unwrap_or(default_i);
                bold.insert((chosen, c));
            }
        }
    } else if bold_enabled {
        // Across each row: group same-unit columns (rivals); bold the best per group.
        for (i, r) in results.iter().enumerate() {
            let mut groups: HashMap<&'static str, Vec<(usize, f64)>> = HashMap::new();
            let mut col_of: HashMap<usize, &String> = HashMap::new();
            for (ci, c) in columns.iter().enumerate() {
                if let Some(f) = r.metrics.get(c).and_then(|v| v.as_f64()) {
                    if let Some(u) = unit_of(c) {
                        groups.entry(u.name).or_default().push((ci, f));
                        col_of.insert(ci, c);
                    }
                }
            }
            for cells in groups.values() {
                if cells.len() < 2 {
                    continue;
                }
                let dir = direction_of(&overrides, col_of[&cells[0].0]);
                if let Some(ci) = pick_best(cells, dir) {
                    bold.insert((i, col_of[&ci]));
                }
            }
        }
    }

    // Per-column uniform magnitude: scan each column's max |value| once so every
    // cell in the column shares one unit suffix (M/B/T) — no mixing 2.12M with
    // 3930. Below a million the column keeps plain, un-separated values (L3/L8).
    let col_scale: Vec<Option<(f64, &'static str, usize)>> = columns
        .iter()
        .map(|c| {
            let vals: Vec<f64> = results
                .iter()
                .filter_map(|r| r.metrics.get(c).and_then(|v| v.as_f64()))
                .collect();
            column_format(&vals)
        })
        .collect();

    let trophies = hard_broken_trophies(ctx, &results, &ours_tokens);
    for (i, r) in results.iter().enumerate() {
        let name_cell = if trophies.contains(r.name.as_str()) {
            format!("{} 🏆", r.name)
        } else if flagged.contains_key(r.name.as_str()) {
            // `suspect=flag`: the row stays, but the reader is told before reading it.
            format!("{} ⚠", r.name)
        } else {
            r.name.clone()
        };
        out.push_str(&format!("| {} |", name_cell));
        for (ci, c) in columns.iter().enumerate() {
            match r.metrics.get(c).and_then(|v| v.as_f64()) {
                Some(f) => {
                    let cell = fmt_metric_scaled(f, col_scale[ci]);
                    if bold.contains(&(i, c)) {
                        out.push_str(&format!(" **{cell}** |"));
                    } else {
                        out.push_str(&format!(" {cell} |"));
                    }
                }
                None => out.push_str(" |"),
            }
        }
        out.push('\n');
    }
    // The caveat is rendered from the SAME screen that shaped the table, so a
    // published number and its warning can never drift apart.
    let shown_flags: Vec<(&str, &Vec<String>)> = results
        .iter()
        .filter_map(|r| flagged.get(r.name.as_str()).map(|w| (r.name.as_str(), w)))
        .collect();
    if !shown_flags.is_empty() {
        out.push_str(
            "\n⚠ **not credible as real work — read as an artefact, not a measurement:**\n\n",
        );
        for (name, why) in shown_flags {
            out.push_str(&format!("- `{name}` — {}\n", why.join("; ")));
        }
    }
    if !withheld.is_empty() {
        out.push_str("\n⚠ **withheld from this table — not credible as real work:**\n\n");
        for (name, why) in withheld {
            out.push_str(&format!("- `{name}` — {}\n", why.join("; ")));
        }
    }
    Ok(out)
}

/// `bench_hero name=PAT fast=TOK slow=TOK [unit=_s] [label=query]` — the "most
/// dramatic" callout. Among the per-item metrics the two backends share (keys
/// like `q01_s`..`q22_s` — i.e. `q<digits><unit>`, lower-better), find the item
/// where `fast` beats `slow` by the biggest ratio and render a one-line headline
/// + a tiny 1-row table. Built for per-query TPC-H across nornir vs a competitor.
fn render_bench_hero(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let Some(run) = usable_run(ctx, args) else {
        return Ok(
            "_(no bench history yet — run a benchmark to populate this section)_\n".to_string(),
        );
    };
    let name = args.get("name").map(|s| s.as_str()).unwrap_or("");
    let (Some(fast_tok), Some(slow_tok)) = (args.get("fast"), args.get("slow")) else {
        return Ok("_(bench_hero needs `fast=` and `slow=` backend tokens)_\n".to_string());
    };
    let unit = args.get("unit").map(|s| s.as_str()).unwrap_or("_s");
    let find = |tok: &str| {
        run.results
            .iter()
            .find(|r| r.name.contains(name) && r.name.contains(tok))
    };
    let (Some(fast), Some(slow)) = (find(fast_tok), find(slow_tok)) else {
        return Ok("_(bench_hero: backend rows not found for this run)_\n".to_string());
    };
    // (item-key, ratio = slow/fast, fast_seconds, slow_seconds)
    let mut best: Option<(String, f64, f64, f64)> = None;
    for (k, v) in fast.metrics.iter() {
        let Some(stem) = k.strip_suffix(unit) else {
            continue;
        };
        let is_item = stem.len() > 1
            && stem.starts_with('q')
            && stem[1..].bytes().all(|b| b.is_ascii_digit());
        if !is_item {
            continue;
        }
        let (Some(fv), Some(sv)) = (v.as_f64(), slow.metrics.get(k).and_then(|x| x.as_f64()))
        else {
            continue;
        };
        if fv <= 0.0 {
            continue;
        }
        let ratio = sv / fv;
        if best.as_ref().is_none_or(|b| ratio > b.1) {
            best = Some((stem.to_string(), ratio, fv, sv));
        }
    }
    let Some((item, ratio, fv, sv)) = best else {
        return Ok("_(bench_hero: the two backends share no per-item metrics)_\n".to_string());
    };
    let label = args.get("label").map(|s| s.as_str()).unwrap_or("query");
    let mut out = String::new();
    out.push_str(&bench_header(run));
    out.push_str(&format!(
        "> **Most dramatic {label} — `{item}`: nornir is {ratio:.1}× faster** \
         ({:.1} ms vs {:.1} ms).\n\n",
        fv * 1000.0,
        sv * 1000.0
    ));
    out.push_str(&format!(
        "| {label} | {} | {} | speedup |\n|---|---|---|---|\n| `{item}` | **{:.1} ms** | {:.1} ms | **{:.1}×** |\n",
        fast.name,
        slow.name,
        fv * 1000.0,
        sv * 1000.0,
        ratio
    ));
    Ok(out)
}

/// The "system" token of a bench result: the first `_`-delimited segment of its
/// `name`. Results carry no dedicated system field — the identity is embedded in
/// the name (`holger_get_blob`, `nexus_get_blob`, `nornir_embedded_table_exists`),
/// so the leading segment is the system (`holger` / `nexus` / `nornir`). Variants
/// of one system (`nornir_ram`, `nornir_nvme`) collapse to a single token, which
/// is exactly what the mashup wants — one row per system.
fn system_token(name: &str) -> &str {
    name.split('_').next().unwrap_or(name)
}

/// The system token honoring the single-thread VARIANT dimension. With
/// `keep_st` `false` this is exactly [`system_token`] — an `_st` variant
/// collapses into its base system (`zoomies-lgz_st` → `zoomies-lgz`), the
/// historical one-row-per-system behaviour. With `keep_st` `true` a
/// single-thread (`_st`) row keeps a DISTINCT token (`zoomies-lgz` vs
/// `zoomies-lgz_st`), so the mashup can render a base system and its
/// single-core variant as TWO rows. The `_st` notion is the SAME one the
/// core-saturation gate exempts — both go through [`nornir_bench`]
/// ([`nornir_bench::is_single_thread`] / [`nornir_bench::strip_single_thread`])
/// so the two subsystems can never drift.
fn system_token_variant(name: &str, keep_st: bool) -> String {
    if keep_st && nornir_bench::is_single_thread(name) {
        let base = system_token(nornir_bench::strip_single_thread(name));
        format!("{base}{}", nornir_bench::SINGLE_THREAD_SUFFIX)
    } else {
        system_token(name).to_string()
    }
}

/// Does this result row belong to *ours* (for winner-tie preference)? Matches when
/// the row's system token equals any `self` token, or shares its leading `-`-family
/// segment — so a single `self=zoomies-lbz2` claims BOTH `zoomies-lbz2` and its
/// sibling `zoomies-lgz` (family `zoomies`). `ours` may be a comma-list of tokens.
/// Empty `ours` ⇒ never ours (preserves the no-`self=` behaviour untouched).
fn row_is_ours(name: &str, ours: &[String]) -> bool {
    if ours.is_empty() {
        return false;
    }
    let tok = system_token(name).to_ascii_lowercase();
    let fam = tok.split('-').next().unwrap_or(tok.as_str());
    ours.iter().any(|o| {
        let ol = o.to_ascii_lowercase();
        let of = ol.split('-').next().unwrap_or(ol.as_str());
        tok == ol || (!of.is_empty() && of == fam)
    })
}

/// Every distinct system token present in the run, in first-seen order.
/// `keep_st` opts into the single-thread VARIANT dimension: when `true` an
/// `_st` row surfaces as its own system (distinct from its multi-core base);
/// when `false` (the default) it collapses into the base — see
/// [`system_token_variant`].
fn discover_systems_variant(run: &BenchRun, keep_st: bool) -> Vec<String> {
    let mut seen: Vec<String> = Vec::new();
    for r in &run.results {
        let tok = system_token_variant(&r.name, keep_st);
        if !tok.is_empty() && !seen.iter().any(|s| *s == tok) {
            seen.push(tok);
        }
    }
    seen
}

/// The system with the most result rows (first-seen wins ties) — the "we bench
/// ourselves across many workloads" fallback for detecting *ours* when neither an
/// explicit `self=` nor the repo/package name resolves to a discovered system.
fn most_frequent_system(run: &BenchRun) -> Option<String> {
    let mut counts: Vec<(String, usize)> = Vec::new();
    for r in &run.results {
        let tok = system_token(&r.name);
        if tok.is_empty() {
            continue;
        }
        if let Some(e) = counts.iter_mut().find(|(t, _)| t == tok) {
            e.1 += 1;
        } else {
            counts.push((tok.to_string(), 1));
        }
    }
    let mut best: Option<(String, usize)> = None;
    for (t, c) in counts {
        if best.as_ref().is_none_or(|b| c > b.1) {
            best = Some((t, c));
        }
    }
    best.map(|(t, _)| t)
}

/// The repo's own name for the *ours* heuristic: the `[package] name` in
/// `<repo_root>/Cargo.toml` when present (a workspace-root manifest may have none),
/// falling back to the repo-root directory basename.
fn repo_self_name(ctx: &Ctx) -> String {
    let cargo = ctx.repo_root.join("Cargo.toml");
    if let Ok(txt) = std::fs::read_to_string(&cargo) {
        if let Ok(val) = txt.parse::<toml::Table>().map(toml::Value::Table) {
            if let Some(n) = val
                .get("package")
                .and_then(|p| p.get("name"))
                .and_then(|n| n.as_str())
            {
                return n.to_string();
            }
        }
    }
    ctx.repo_root
        .file_name()
        .and_then(|s| s.to_str())
        .unwrap_or("")
        .to_string()
}

/// Map a wanted token (from `self=`) onto a discovered system when they overlap
/// case-insensitively, else return it verbatim so `compare=` can still match it.
fn resolve_token(want: &str, systems: &[String]) -> String {
    let wl = want.to_ascii_lowercase();
    systems
        .iter()
        .find(|t| {
            let tl = t.to_ascii_lowercase();
            tl == wl || tl.contains(&wl) || wl.contains(&tl)
        })
        .cloned()
        .unwrap_or_else(|| want.to_string())
}

/// Auto-detect *ours* among the discovered systems. Priority:
/// 1. explicit `self=TOKEN` override (resolved onto a discovered system);
/// 2. the system whose token overlaps the repo/package name (case-insensitive,
///    either-contains — so package `holger` ↔ system `holger`, `nornir` ↔
///    `nornir_embedded`);
/// 3. fallback: the most-frequent system (we bench ourselves across many
///    workloads). Failure mode: if a rival happens to carry more rows than ours
///    *and* the repo name doesn't match any token, ours is mis-guessed — pin it
///    with `self=`.
fn detect_ours(
    ctx: &Ctx,
    run: &BenchRun,
    systems: &[String],
    args: &HashMap<String, String>,
) -> String {
    if let Some(s) = args.get("self") {
        return resolve_token(s, systems);
    }
    let repo = repo_self_name(ctx).to_ascii_lowercase();
    if !repo.is_empty() {
        if let Some(t) = systems.iter().find(|t| {
            let tl = t.to_ascii_lowercase();
            tl == repo || tl.contains(&repo) || repo.contains(&tl)
        }) {
            return t.clone();
        }
    }
    most_frequent_system(run).unwrap_or_else(|| systems[0].clone())
}

/// The single biggest-diff pairwise story: across every metric ours and a rival
/// share, the (rival, metric) where ours wins by the largest ratio (direction-
/// aware — throughput ratios ours/rival, latency rival/ours). Mirrors the max-
/// ratio tracking of [`render_bench_hero`], generalised past its `q<n>_s` items to
/// any metric and any rival. `None` when ours never wins (or there are no rivals).
struct MashupStory {
    token: String,
    metric: String,
    ratio: f64,
    ours_val: f64,
    rival_val: f64,
}

fn biggest_story(
    ours: &nornir_bench::BenchResult,
    rivals: &[(String, &nornir_bench::BenchResult)],
    overrides: &HashMap<String, nornir_bench::MetricDirection>,
    only_metric: Option<&str>,
) -> Option<MashupStory> {
    use nornir_bench::{MetricDirection, direction_of};
    let mut best: Option<MashupStory> = None;
    for (k, v) in ours.metrics.iter() {
        if let Some(m) = only_metric {
            if k != m {
                continue;
            }
        }
        let Some(ov) = v.as_f64() else { continue };
        if ov <= 0.0 {
            continue;
        }
        let higher_better = match direction_of(overrides, k) {
            MetricDirection::High => true,
            MetricDirection::Low => false,
            MetricDirection::Neutral => continue,
        };
        for (tok, rr) in rivals {
            let Some(rv) = rr.metrics.get(k).and_then(|x| x.as_f64()) else {
                continue;
            };
            if rv <= 0.0 {
                continue;
            }
            let ratio = if higher_better { ov / rv } else { rv / ov };
            if ratio <= 1.0 {
                continue; // ours must actually win this pairing
            }
            if best.as_ref().is_none_or(|b| ratio > b.ratio) {
                best = Some(MashupStory {
                    token: tok.clone(),
                    metric: k.clone(),
                    ratio,
                    ours_val: ov,
                    rival_val: rv,
                });
            }
        }
    }
    best
}

/// `mashup` renderer — the **zero-config** top-of-README comparison table. Unlike
/// `benches`, it takes NO required args: it AUTO-DISCOVERS the repo's own system
/// (*ours*) and EVERY rival system from the latest [`BenchRun`], then renders the
/// crisp N-way table (effectively `benches compare=<ours+rivals> winner=row` with
/// meaty-first columns — throughput, then p50→p99 latency — and ours' winning
/// cells bolded). Above the table it surfaces the single biggest-diff pairwise
/// story (max-ratio, à la `bench_hero`) when a clear standout exists.
///
/// All args are optional:
/// - `self=TOKEN` — pin *ours* instead of guessing from the repo/package name.
/// - `exclude=PAT` — drop rival systems whose token contains `PAT`.
/// - `metric=KEY` — restrict the table to (and headline to) a single metric column.
/// - `cols=a,b,c` — explicit ordered column whitelist (scope the table to these
///   metrics only, e.g. decode metrics in a bake-off); does not scope the headline.
/// - `top=N` — keep only the N strongest systems (ranked as in `benches`).
/// - `best=metric:dir` — per-metric direction overrides (passed through).
///
/// Empty/absent bench data → a graceful placeholder, matching the other bench
/// sections (never a panic/error).
/// True if `token` matches any of the comma-separated `exclude` patterns
/// (case-insensitive substring). Lets a marker drop several rival systems at
/// once, e.g. `exclude=zstd,lz4,xz` — the opponents of a decompressor are only
/// the reference tools of the formats it reimplements, not unrelated codecs.
fn is_excluded(token: &str, exclude: Option<&str>) -> bool {
    let tl = token.to_ascii_lowercase();
    exclude.is_some_and(|pats| {
        pats.split(',')
            .map(str::trim)
            .filter(|p| !p.is_empty())
            .any(|p| tl.contains(&p.to_ascii_lowercase()))
    })
}

fn render_mashup(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let Some(run) = usable_run(ctx, args) else {
        return Ok(
            "_(no bench history yet — run a benchmark to populate this section)_\n".to_string(),
        );
    };
    if run.results.is_empty() {
        return Ok("_(no bench results)_\n".to_string());
    }
    let exclude = args.get("exclude").map(|s| s.as_str());
    // VARIANT DIMENSION (`variant=st` / `variant=cores` / `variant=true`): keep a
    // single-thread (`_st`) bench a DISTINCT mashup row from its multi-core base
    // system, so a single-core-vs-multi-core story (znippy-zoomies "lens B":
    // `zoomies-lgz_st` vs `gzip`) can be a grouped row. OFF by default — `_st`
    // collapses into its base system (one row), the historical behaviour. The
    // `_st` marker is the SAME one the core-saturation gate exempts.
    let keep_st = args
        .get("variant")
        .map(|v| {
            let v = v.trim().to_ascii_lowercase();
            !matches!(v.as_str(), "" | "false" | "none" | "off" | "0" | "no")
        })
        .unwrap_or(false);
    // (b) auto-discover every distinct ROW-system (`<system>_<workload>` scheme),
    //     then drop excluded rivals.
    let systems: Vec<String> = discover_systems_variant(run, keep_st)
        .into_iter()
        .filter(|t| !is_excluded(t, exclude))
        .collect();
    // The row-wise scheme only applies when *ours* is actually one of the row
    // systems (a `self=` pin, or the repo name matching a row prefix) AND there are
    // ≥2 systems to compare. Otherwise the "systems" are really workload names
    // (holger's `java_jar`, `pip_wheel`, …) and the rivals live in COLUMNS — fall
    // through to the column-wise scheme.
    let repo = repo_self_name(ctx).to_ascii_lowercase();
    let ours_is_row_system = args.contains_key("self")
        || systems.iter().any(|t| {
            let tl = t.to_ascii_lowercase();
            !repo.is_empty() && (tl == repo || tl.contains(&repo) || repo.contains(&tl))
        });
    if ours_is_row_system && systems.len() >= 2 {
        // GROUPED PAIRING (`grouped` / `pairing=grouped`): instead of one flat
        // N-way table, pair each of OUR codecs against its DIRECT rival by format
        // and emit one sub-table per format group (e.g. group "gzip": our
        // `zoomie-lgz` vs `gzip`; group "bzip2": our `zoomie-lbzip2` vs `bzip2`).
        // Pairing is data-driven (longest-common-substring of the codec names) —
        // no repo-specific hardcoding.
        let grouped = args.get("grouped").map(|v| v != "false").unwrap_or(false)
            || matches!(
                args.get("pairing").map(|s| s.as_str()),
                Some("grouped" | "group" | "pairs" | "format")
            );
        if grouped {
            if let Some(s) = render_mashup_grouped(ctx, args, run, &systems)? {
                return Ok(s);
            }
        }
        return render_mashup_rowwise(ctx, args, run, &systems);
    }
    // (B) COLUMN-WISE: rivals are column prefixes sharing a metric suffix
    //     (`holger_served_mbs` vs `nexus_served_mbs` vs `artifactory_served_mbs`).
    if let Some(s) = render_mashup_columnwise(ctx, args, run, exclude)? {
        return Ok(s);
    }
    // (C) SINGLE-SYSTEM: no rival persisted anywhere — a clean headline line, not a
    //     lonely raw row (the full matrix, if any, lives in README-full).
    Ok(render_mashup_solo(run))
}

/// The original ROW-WISE mashup: rows are `<system>_<workload>`, *ours* is one of
/// them, and every rival is a sibling row sharing a metric column. Delegates the
/// pivot to `render_benches compare=<ours+rivals> winner=row`.
fn render_mashup_rowwise(
    ctx: &Ctx,
    args: &HashMap<String, String>,
    run: &nornir_bench::BenchRun,
    systems: &[String],
) -> Result<String> {
    // (a) auto-detect ours, then order ours-first + rivals in discovery order.
    let ours = detect_ours(ctx, run, systems, args);
    let mut order: Vec<String> = Vec::new();
    if systems.iter().any(|s| *s == ours) {
        order.push(ours.clone());
    }
    for s in systems {
        if !order.iter().any(|o| o == s) {
            order.push(s.clone());
        }
    }

    // (c) delegate the pivot table to `render_benches` — the N-way `compare=` +
    // `winner=row` mashup, with its meaty-first column ranking and winner bolding.
    // No rendering logic is duplicated here.
    let mut bargs: HashMap<String, String> = HashMap::new();
    bargs.insert("compare".into(), order.join(","));
    bargs.insert("winner".into(), "row".into());
    // Tell the pivot which row is *ours* so winner-ties bold ours, not a rival.
    // `detect_ours` resolved a single token (e.g. `zoomies-lbz2`); `row_is_ours`
    // widens it to the whole `-`-family (`zoomies-lbz2` + `zoomies-lgz`).
    bargs.insert("self".into(), ours.clone());
    // Column scoping: `cols=a,b,c` is an explicit ordered whitelist (e.g. scope a
    // decode bake-off to its decode metrics, dropping format-level columns);
    // `metric=KEY` is the single-column shorthand. `cols=` wins when both appear.
    // `metric=` additionally scopes the headline below; `cols=` does not.
    if let Some(c) = args.get("cols") {
        bargs.insert("cols".into(), c.clone());
    } else if let Some(m) = args.get("metric") {
        bargs.insert("cols".into(), m.clone()); // single meaty column
    }
    if let Some(t) = args.get("top") {
        bargs.insert("top".into(), t.clone());
    }
    if let Some(b) = args.get("best") {
        bargs.insert("best".into(), b.clone());
    }
    let table = render_benches(ctx, &bargs)?;

    // (d) the single biggest-diff headline — reuse the max-ratio logic across the
    // same one-row-per-system set `compare=` picks (first name-containing hit).
    let overrides = parse_best_overrides(args.get("best").map(|s| s.as_str()));
    let pick = |tok: &str| run.results.iter().find(|r| r.name.contains(tok));
    let only_metric = args.get("metric").map(|s| s.as_str());
    let mut headline = String::new();
    if let Some(ours_row) = pick(&ours) {
        let rivals: Vec<(String, &nornir_bench::BenchResult)> = order
            .iter()
            .filter(|t| **t != ours)
            .filter_map(|t| pick(t).map(|r| (t.clone(), r)))
            .collect();
        if let Some(s) = biggest_story(ours_row, &rivals, &overrides, only_metric) {
            headline = format!(
                "> **Biggest gap — `{}`: {} leads {} by {:.1}×** ({} vs {}).\n\n",
                s.metric,
                ours,
                s.token,
                s.ratio,
                fmt_metric(s.ours_val),
                fmt_metric(s.rival_val),
            );
        }
    }

    Ok(format!("{headline}{table}"))
}

/// Length of the longest common (contiguous) substring of two strings, comparing
/// only lowercase alphanumerics (separators/case ignored). The data-driven
/// pairing key: `zoomie-lgz` ↔ `gzip` share `gz` (2); `zoomie-lbzip2` ↔ `bzip2`
/// share `bzip2` (5); `zoomie-lgz` ↔ `bzip2` share only `z` (1) — so each of our
/// codecs snaps to its true format rival, not a spurious one.
fn common_run(a: &str, b: &str) -> usize {
    let norm = |s: &str| -> Vec<u8> {
        s.bytes()
            .filter(|c| c.is_ascii_alphanumeric())
            .map(|c| c.to_ascii_lowercase())
            .collect()
    };
    let (a, b) = (norm(a), norm(b));
    if a.is_empty() || b.is_empty() {
        return 0;
    }
    let mut best = 0usize;
    let mut prev = vec![0usize; b.len() + 1];
    for i in 1..=a.len() {
        let mut cur = vec![0usize; b.len() + 1];
        for j in 1..=b.len() {
            if a[i - 1] == b[j - 1] {
                cur[j] = prev[j - 1] + 1;
                best = best.max(cur[j]);
            }
        }
        prev = cur;
    }
    best
}

/// GROUPED-PAIRING mashup: snap each of OUR codecs to its single closest rival
/// (by [`common_run`]), then GROUP our codecs by that rival and render one
/// sub-table per format group. Usually 2 rows (ours + rival), but when several
/// of ours snap to the same rival — notably a base system AND its single-thread
/// `_st` variant (`variant=st`), both snapping to the same format tool — they
/// share ONE sub-table so the single-core and multi-core rows sit together under
/// their format. `ours` is the detected family; rivals are every other discovered
/// system. A group is emitted only when the best match clears a 2-char shared run
/// (so unrelated systems don't get force-paired). Returns `None` (caller falls
/// back to the flat row-wise table) when no real group forms. Each sub-table
/// reuses [`render_benches`] (`compare=ours…,rival winner=row self=ours`) so winner
/// bolding + tie-favour-ours + `cols=`/`drop=`/`metric=` scoping all apply
/// per-group unchanged.
fn render_mashup_grouped(
    ctx: &Ctx,
    args: &HashMap<String, String>,
    run: &nornir_bench::BenchRun,
    systems: &[String],
) -> Result<Option<String>> {
    let ours = detect_ours(ctx, run, systems, args);
    let ours_family: Vec<String> = vec![ours.clone()];
    // Partition discovered systems into ours (family match) and rivals.
    let (mine, rivals): (Vec<&String>, Vec<&String>) =
        systems.iter().partition(|s| row_is_ours(s, &ours_family));
    if mine.is_empty() || rivals.is_empty() {
        return Ok(None);
    }
    // Pair each of our codecs to its best rival (max shared run, ≥2 chars), then
    // GROUP our codecs by that rival: all of ours snapping to one rival (e.g. a
    // base `zoomies-lgz` AND its single-thread `zoomies-lgz_st` variant, which
    // both snap to `gzip`) share ONE format sub-table — the single-core and
    // multi-core rows sit together under their format, not in duplicate headers.
    // A rival may back more than one of ours only when it genuinely wins the run
    // for each — deterministic, data-driven, no 1:1 assumption baked in.
    let mut groups: Vec<(String, Vec<String>)> = Vec::new(); // (rival/header, ours…)
    for m in &mine {
        let mut best: Option<(usize, &String)> = None;
        for rv in &rivals {
            let run_len = common_run(m, rv);
            if best.as_ref().is_none_or(|(l, _)| run_len > *l) {
                best = Some((run_len, rv));
            }
        }
        if let Some((len, rv)) = best {
            if len >= 2 {
                // Header names the format = the rival token (e.g. `gzip`, `bzip2`).
                match groups.iter_mut().find(|(h, _)| h.as_str() == rv.as_str()) {
                    Some((_, ours_here)) => ours_here.push((*m).clone()),
                    None => groups.push(((*rv).clone(), vec![(*m).clone()])),
                }
            }
        }
    }
    if groups.is_empty() {
        return Ok(None);
    }
    // Render one sub-table per group, reusing the pivot for each ours-vs-rival set.
    let mut out = String::new();
    for (rival_tok, mine_toks) in &groups {
        let header = rival_tok;
        // `compare=` claims one DISTINCT row per token (first unused hit, in token
        // order), so a token that is a substring of another must come FIRST to
        // claim its own row. Order ours by descending length — the more specific
        // `zoomies-lgz_st` precedes the base `zoomies-lgz` it contains — then the
        // rival last. `self=` widens to the whole family, so any of ours bolds.
        let mut ordered = mine_toks.clone();
        ordered.sort_by(|a, b| b.len().cmp(&a.len()).then_with(|| a.cmp(b)));
        let self_tok = ordered.first().cloned().unwrap_or_default();
        let mut compare = ordered;
        compare.push(rival_tok.clone());
        let mut bargs: HashMap<String, String> = HashMap::new();
        bargs.insert("compare".into(), compare.join(","));
        bargs.insert("winner".into(), "row".into());
        bargs.insert("self".into(), self_tok);
        // Column scoping / format-col dropping pass straight through per group.
        for k in ["cols", "metric", "drop", "best", "top"] {
            if let Some(v) = args.get(k) {
                let key = if k == "metric" && !args.contains_key("cols") {
                    "cols"
                } else {
                    k
                };
                bargs.insert(key.into(), v.clone());
            }
        }
        let table = render_benches(ctx, &bargs)?;
        // Strip the per-run bench header from all but the first group so the
        // grouped block reads as one section with per-format sub-headers.
        let table = if out.is_empty() {
            table
        } else {
            strip_bench_header(&table)
        };
        out.push_str(&format!("**{header}**\n\n{table}\n"));
    }
    Ok(Some(out))
}

/// Drop a leading `bench_header` block (the italic `_run …_` provenance line plus
/// its trailing blank line) from a rendered table, keeping only the markdown
/// table — used so grouped sub-tables share one header instead of repeating it.
fn strip_bench_header(table: &str) -> String {
    // The table proper starts at the first pipe-row (`| workload |`).
    match table.find("\n| ") {
        Some(idx) => table[idx + 1..].to_string(),
        None => table.to_string(),
    }
}

/// Split a column key into `(system, suffix)` given the detected rival systems:
/// a leading `<system>_` prefix that names a discovered system peels off (so
/// `nexus_served_mbs` → `("nexus", "served_mbs")`); anything else belongs to
/// *ours*, with the whole key as the suffix (so a bare `ops_per_sec` → `(ours,
/// "ops_per_sec")` and aligns with a rival's `artifactory_ops_per_sec`).
fn classify_column<'a>(
    col: &'a str,
    systems: &std::collections::BTreeSet<String>,
    ours: &str,
) -> (String, &'a str) {
    if let Some((head, tail)) = col.split_once('_') {
        if systems.iter().any(|s| s == head) {
            return (head.to_string(), tail);
        }
    }
    (ours.to_string(), col)
}

/// COLUMN-WISE mashup — the scheme holger uses: rows are workloads and the rivals
/// live in **columns** that share a metric suffix across a system prefix
/// (`holger_served_mbs` / `nexus_served_mbs` / `artifactory_served_mbs`). We
/// (1) discover systems from prefixes that share a suffix, (2) keep only the
/// columns whose suffix is contested by ≥2 systems, (3) keep only the workload
/// rows that carry a rival's column (dropping self-only throughput + internal
/// micro-benchmarks), then render the tight ours-vs-rivals table + the biggest
/// same-suffix win as the headline. Returns `None` when no column-wise rivalry
/// exists (so the caller can fall through to the single-system line).
fn render_mashup_columnwise(
    ctx: &Ctx,
    args: &HashMap<String, String>,
    run: &nornir_bench::BenchRun,
    exclude: Option<&str>,
) -> Result<Option<String>> {
    use nornir_bench::{MetricDirection, direction_of};
    use std::collections::{BTreeMap, BTreeSet};

    let ours = repo_self_name(ctx).to_ascii_lowercase();
    if ours.is_empty() {
        return Ok(None);
    }
    // Every numeric column across the run, first-seen order.
    let mut cols: Vec<String> = Vec::new();
    for r in &run.results {
        for (k, v) in &r.metrics {
            if v.as_f64().is_some() && !cols.contains(k) {
                cols.push(k.clone());
            }
        }
    }
    // (1) Detect rival systems. A first-segment is a *system* only when it prefixes
    //     ≥2 distinct metric suffixes AND contests at least one suffix with another
    //     such prefix. This separates real system names (holger/nexus/artifactory,
    //     each spanning several metrics) from metric-name fragments that merely
    //     share a unit word — `mb_per_sec` & `ops_per_sec` split to heads `mb`/`ops`
    //     over the SAME tail `per_sec`, but neither prefixes a second suffix, so
    //     neither is a system.
    let mut head_tails: BTreeMap<&str, BTreeSet<&str>> = BTreeMap::new();
    for c in &cols {
        if let Some((head, tail)) = c.split_once('_') {
            head_tails.entry(head).or_default().insert(tail);
        }
    }
    let candidates: BTreeSet<&str> = head_tails
        .iter()
        .filter(|(_, t)| t.len() >= 2)
        .map(|(h, _)| *h)
        .collect();
    let mut tail_cands: BTreeMap<&str, BTreeSet<&str>> = BTreeMap::new();
    for h in &candidates {
        for t in &head_tails[h] {
            tail_cands.entry(*t).or_default().insert(*h);
        }
    }
    let mut systems: BTreeSet<String> = BTreeSet::new();
    for hs in tail_cands.values() {
        if hs.len() >= 2 {
            for h in hs {
                systems.insert((*h).to_string());
            }
        }
    }
    // Drop excluded rivals (never ours). `exclude=` is a comma list.
    systems.retain(|s| s.eq_ignore_ascii_case(&ours) || !is_excluded(s, exclude));
    let has_rival = systems.iter().any(|s| !s.eq_ignore_ascii_case(&ours));
    if !has_rival {
        return Ok(None);
    }
    // (2) Group columns by suffix; a suffix contested by ≥2 systems is a rival group.
    let mut suffix_systems: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
    for c in &cols {
        let (sys, suf) = classify_column(c, &systems, &ours);
        suffix_systems
            .entry(suf.to_string())
            .or_default()
            .insert(sys);
    }
    // A suffix is shown only when it is contested by ≥2 systems AND *ours* is one of
    // them — i.e. a real head-to-head where our column can crush the rivals'. A
    // suffix carried only by rivals (no ours column) is not a comparison we win, so
    // it's dropped. `ours` is the repo/package name — nothing here is repo-specific.
    let rival_suffixes: BTreeSet<String> = suffix_systems
        .iter()
        .filter(|(_, sys)| sys.len() >= 2 && sys.iter().any(|s| s.eq_ignore_ascii_case(&ours)))
        .map(|(s, _)| s.clone())
        .collect();
    if rival_suffixes.is_empty() {
        return Ok(None);
    }
    let overrides = parse_best_overrides(args.get("best").map(|s| s.as_str()));
    // Order systems ours-first, then rivals; order the contested metrics meaty-first.
    let mut ordered: Vec<String> = Vec::new();
    if systems.iter().any(|s| s.eq_ignore_ascii_case(&ours)) {
        ordered.push(ours.clone());
    }
    for s in &systems {
        if !s.eq_ignore_ascii_case(&ours) {
            ordered.push(s.clone());
        }
    }
    let mut sufs: Vec<String> = rival_suffixes.iter().cloned().collect();
    sufs.sort_by(|a, b| col_rank(a).cmp(&col_rank(b)).then_with(|| a.cmp(b)));

    // Transpose the column-wise data into a crisp SYSTEMS-as-rows table: one row per
    // system, one column per contested metric (the same shape as the row-wise
    // mashup). For each (system, metric) take the best value — but ONLY over rows
    // where a RIVAL competes on that metric, so ours' number is drawn from the same
    // workloads as the rivals' (never inflated by a self-only workload with no rival).
    let mut sys_rows: Vec<nornir_bench::BenchResult> = Vec::new();
    for sys in &ordered {
        let mut m = serde_json::Map::new();
        for suf in &sufs {
            let dir = direction_of(&overrides, suf);
            let mut best: Option<f64> = None;
            for r in &run.results {
                let contested_here = r.metrics.iter().any(|(k, v)| {
                    v.as_f64().is_some() && {
                        let (cs, cf) = classify_column(k, &systems, &ours);
                        cf == suf.as_str() && !cs.eq_ignore_ascii_case(&ours)
                    }
                });
                if !contested_here {
                    continue;
                }
                for (k, v) in &r.metrics {
                    if let Some(f) = v.as_f64() {
                        let (cs, cf) = classify_column(k, &systems, &ours);
                        if cf == suf.as_str() && cs.eq_ignore_ascii_case(sys) {
                            best = Some(match dir {
                                MetricDirection::Low => best.map_or(f, |b| b.min(f)),
                                _ => best.map_or(f, |b| b.max(f)),
                            });
                        }
                    }
                }
            }
            if let Some(b) = best {
                m.insert(suf.clone(), serde_json::Value::from(b));
            }
        }
        if !m.is_empty() {
            sys_rows.push(nornir_bench::BenchResult {
                name: sys.clone(),
                metrics: m,
                ..Default::default()
            });
        }
    }
    // Need ours + ≥1 rival with data to be a comparison.
    if sys_rows.len() < 2 || !sys_rows.iter().any(|r| r.name.eq_ignore_ascii_case(&ours)) {
        return Ok(None);
    }

    // Render the systems×metrics pivot via `render_benches winner=row` (rows are
    // systems, columns are metrics; bold the best system down each metric column) on
    // a synthetic run that carries the real run's header metadata.
    let synth = nornir_bench::BenchRun {
        // A SYNTHETIC run for rendering only — it is never persisted, so it
        // carries the source run's id rather than minting one. Two rows with
        // one id would be a lie about identity.
        id: run.id,
        machine_facts: run.machine_facts.clone(),
        date: run.date.clone(),
        timestamp: run.timestamp.clone(),
        version: run.version.clone(),
        machine: run.machine.clone(),
        cores: run.cores,
        results: sys_rows.clone(),
        tests: vec![],
    };
    let sctx = Ctx {
        run: Some(&synth),
        ..*ctx
    };
    let mut bargs: HashMap<String, String> = HashMap::new();
    bargs.insert("winner".into(), "row".into());
    bargs.insert("cols".into(), sufs.join(","));
    let table = render_benches(&sctx, &bargs)?;

    // Headline: the biggest ours-vs-rival ratio across the contested metrics.
    let ours_row = sys_rows.iter().find(|r| r.name.eq_ignore_ascii_case(&ours));
    let mut best: Option<(String, String, f64, f64, f64)> = None; // suffix, rival, ratio, ours, rival
    if let Some(orow) = ours_row {
        for suf in &sufs {
            let Some(ov) = orow.metrics.get(suf).and_then(|v| v.as_f64()) else {
                continue;
            };
            if ov <= 0.0 {
                continue;
            }
            let higher = match direction_of(&overrides, suf) {
                MetricDirection::High => true,
                MetricDirection::Low => false,
                MetricDirection::Neutral => continue,
            };
            for rr in &sys_rows {
                if rr.name.eq_ignore_ascii_case(&ours) {
                    continue;
                }
                let Some(rv) = rr.metrics.get(suf).and_then(|v| v.as_f64()) else {
                    continue;
                };
                if rv <= 0.0 {
                    continue;
                }
                let ratio = if higher { ov / rv } else { rv / ov };
                if ratio <= 1.0 {
                    continue;
                }
                if best.as_ref().is_none_or(|b| ratio > b.2) {
                    best = Some((suf.clone(), rr.name.clone(), ratio, ov, rv));
                }
            }
        }
    }
    let headline = match best {
        Some((suf, rsys, ratio, ov, rv)) => format!(
            "> **Biggest gap — `{}`: {} leads {} by {:.1}×** ({} vs {}).\n\n",
            suf,
            ours,
            rsys,
            ratio,
            fmt_metric(ov),
            fmt_metric(rv),
        ),
        None => String::new(),
    };
    Ok(Some(format!("{headline}{table}")))
}

/// SINGLE-SYSTEM mashup — no rival persisted (e.g. nornir's latest run is its own
/// `dep_graph_build`). Emit a clean one-line headline of *ours'* meatiest metrics
/// rather than a lonely raw table; the competitive matrix, if any, lives in
/// README-full.
fn render_mashup_solo(run: &nornir_bench::BenchRun) -> String {
    // The row carrying the most numeric metrics is the representative self-bench.
    let Some(row) = run
        .results
        .iter()
        .max_by_key(|r| r.metrics.values().filter(|v| v.as_f64().is_some()).count())
    else {
        return "_(no bench results)_\n".to_string();
    };
    // Meaty-first: throughput/latency columns lead (col_rank), then the rest.
    let mut keys: Vec<&String> = row
        .metrics
        .keys()
        .filter(|k| row.metrics[*k].as_f64().is_some())
        .collect();
    keys.sort_by(|a, b| col_rank(a).cmp(&col_rank(b)).then_with(|| a.cmp(b)));
    let bits: Vec<String> = keys
        .iter()
        .take(3)
        .filter_map(|k| {
            row.metrics[*k]
                .as_f64()
                .map(|f| format!("**{}** {}", fmt_metric(f), k))
        })
        .collect();
    let header = bench_header(run);
    if bits.is_empty() {
        return format!("{header}_(single-system bench — no rival persisted yet.)_\n");
    }
    format!(
        "{header}`{}` — {} _(single-system bench; competitive matrix in [`README-full`](.nornir/README-full.md))_\n",
        row.name,
        bits.join(" · "),
    )
}

/// `bench_chart` renderer: a horizontal bar chart comparing one metric across
/// the matching workloads/systems — the visual counterpart to a `benches` table,
/// for the "featured mashup" at the top of a README (e.g. nornir vs nessie vs
/// polaris throughput). The winner (best by the metric's direction) is highlighted.
///
/// Args:
/// - `metric=KEY`   — which metric column to chart (required).
/// - `name=PAT`     — only workloads whose name contains `PAT`.
/// - `exclude=PAT`  — drop workloads whose name contains `PAT`.
/// - `title=TEXT`   — chart title (default: the metric name).
/// - `dir=high|low` — winner direction override (default: inferred from the unit).
/// - `log=true`     — log-scale bar widths (default: auto when the spread >100×).
/// - `file=NAME`    — asset basename under `.nornir/assets/` (default: derived).
///
/// With `export`: writes an SVG under `.nornir/assets/` and emits a markdown
/// image link. Without it: falls back to a unicode-bar text block so the section
/// still conveys the comparison.
fn render_bench_chart(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    use nornir_bench::{MetricDirection, direction_of};
    let Some(run) = usable_run(ctx, args) else {
        return Ok(
            "_(no bench history yet — run a benchmark to populate this section)_\n".to_string(),
        );
    };
    let metric = args
        .get("metric")
        .map(|s| s.as_str())
        .ok_or_else(|| anyhow!("bench_chart requires a `metric=` arg"))?;
    let filter = args.get("name").map(|s| s.as_str());
    let exclude = args.get("exclude").map(|s| s.as_str());

    // (workload, value) for every matching result that carries this metric.
    let mut points: Vec<(String, f64)> = run
        .results
        .iter()
        .filter(|r| filter.is_none_or(|p| r.name.contains(p)))
        .filter(|r| exclude.is_none_or(|p| !r.name.contains(p)))
        .filter_map(|r| {
            r.metrics
                .get(metric)
                .and_then(|v| v.as_f64())
                .map(|f| (r.name.clone(), f))
        })
        .collect();
    if points.is_empty() {
        return Ok(format!("_(no bench results carry metric `{metric}`)_\n"));
    }

    // Winner direction: explicit `dir=` wins, else the `best=` override, else the
    // unit's natural direction (ops/sec → high, latency → low).
    let overrides = parse_best_overrides(args.get("best").map(|s| s.as_str()));
    let dir = match args.get("dir").map(|s| s.to_ascii_lowercase()) {
        Some(d) if d == "high" || d == "max" => MetricDirection::High,
        Some(d) if d == "low" || d == "min" => MetricDirection::Low,
        _ => direction_of(&overrides, metric),
    };
    // Sort so the winner is on top (best first); ties keep input order.
    match dir {
        MetricDirection::High => points.sort_by(|a, b| b.1.total_cmp(&a.1)),
        MetricDirection::Low => points.sort_by(|a, b| a.1.total_cmp(&b.1)),
        MetricDirection::Neutral => {}
    }
    let best_val = match dir {
        MetricDirection::High => points.iter().map(|p| p.1).fold(f64::MIN, f64::max),
        MetricDirection::Low => points.iter().map(|p| p.1).fold(f64::MAX, f64::min),
        MetricDirection::Neutral => f64::NAN,
    };

    let title = args
        .get("title")
        .cloned()
        .unwrap_or_else(|| format!("{metric} by workload"));
    let unit = friendly_unit(metric);
    // Auto log scale when the spread exceeds 100× (embedded-vs-REST throughput).
    let max_v = points.iter().map(|p| p.1).fold(f64::MIN, f64::max);
    let min_pos = points
        .iter()
        .map(|p| p.1)
        .filter(|v| *v > 0.0)
        .fold(f64::MAX, f64::min);
    let log = match args.get("log").map(|s| s.as_str()) {
        Some("true") => true,
        Some("false") => false,
        _ => min_pos.is_finite() && max_v > 0.0 && max_v / min_pos > 100.0,
    };

    #[cfg(feature = "export")]
    {
        let bars: Vec<crate::svg::Bar> = points
            .iter()
            .map(|(label, v)| crate::svg::Bar {
                label: label.clone(),
                value: *v,
                best: dir != MetricDirection::Neutral && *v == best_val,
            })
            .collect();
        let chart = crate::svg::BarChart {
            title: title.clone(),
            unit: unit.clone(),
            bars,
            log,
        };
        let base = args
            .get("file")
            .cloned()
            .unwrap_or_else(|| format!("bench_{}", sanitize_asset(metric)));
        let rel = std::path::PathBuf::from(format!(".nornir/assets/{base}.svg"));
        let abs = ctx.repo_root.join(&rel);
        // Markdown-only (pre-commit hook): reuse the committed chart asset.
        if !ctx.no_assets {
            crate::svg::render_bars_to_file(&chart, &abs)?;
        }
        // Alt text: strip the only chars that would break `![alt](path)`.
        let alt = title.replace(['[', ']'], "");
        return Ok(format!("![{}]({})\n", alt, rel.display()));
    }
    #[cfg(not(feature = "export"))]
    {
        // Text fallback: a unicode bar per workload, winner marked with ★.
        let _ = (log, best_val);
        let mut out = format!("**{title}**\n\n");
        let max = points
            .iter()
            .map(|p| p.1)
            .fold(f64::MIN, f64::max)
            .max(f64::MIN_POSITIVE);
        let scale = column_format(&points.iter().map(|p| p.1).collect::<Vec<_>>());
        for (label, v) in &points {
            let filled = ((v / max).clamp(0.0, 1.0) * 24.0).round() as usize;
            let bar: String = "█".repeat(filled);
            let star = if dir != MetricDirection::Neutral && *v == best_val {
                " ★"
            } else {
                ""
            };
            let unit_sfx = if unit.is_empty() {
                String::new()
            } else {
                format!(" {unit}")
            };
            out.push_str(&format!(
                "- `{label}` {bar} {}{}{star}\n",
                fmt_metric_scaled(*v, scale),
                unit_sfx
            ));
        }
        out.push('\n');
        Ok(out)
    }
}

/// Human-readable unit suffix for a metric key, for chart value labels.
fn friendly_unit(metric: &str) -> String {
    let m = metric.to_ascii_lowercase();
    if m.contains("ops_sec") || m.contains("ops_per_sec") || m.contains("commits_per_sec") {
        "ops/sec".into()
    } else if m.contains("rows_per_sec") || m.ends_with("_per_sec") {
        "/sec".into()
    } else if m.ends_with("_us") {
        "µs".into()
    } else if m.ends_with("_ms") {
        "ms".into()
    } else if m.ends_with("_ns") {
        "ns".into()
    } else if m.ends_with("_mbs") || m.contains("mbps") || m.contains("mb_per_sec") {
        "MB/s".into()
    } else if m.ends_with("_secs") || m == "seconds" {
        "s".into()
    } else {
        String::new()
    }
}

/// Sanitize a metric key into a safe asset-file basename component.
#[cfg_attr(not(feature = "export"), allow(dead_code))]
fn sanitize_asset(s: &str) -> String {
    s.chars()
        .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
        .collect()
}

/// `tests` renderer: enumerate the repo's tests grouped by the Rust-standard
/// categories — **unit** (`#[test]` under `src/`), **integration** (under
/// `tests/`), and **doc** (runnable fences in `///`/`//!` comments) — via `syn`,
/// so the inventory stays correct as tests come and go.
///
/// Optional args:
/// - `crate=PAT` — only crates whose name contains `PAT`.
/// - `kind=unit|integration|doc` — render only that category (default: all).
/// - `include_benches=true` — also count perf-benchmark files (`*_bench.rs`,
///   `perf_*.rs`, …), which are skipped by default so they don't inflate the
///   test count (they belong in a `benches` section).
fn render_tests(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let include_benches = args
        .get("include_benches")
        .map(|v| v == "true")
        .unwrap_or(false);
    let inv = crate::test_inventory::scan_opts(
        ctx.repo_root,
        args.get("crate").map(|s| s.as_str()),
        include_benches,
    );
    let only = args.get("kind").map(|s| s.as_str());
    let mut out = String::new();

    let want = |k: &str| only.is_none_or(|o| o == k);

    if want("unit") {
        out.push_str(&format!("**Unit tests** ({})\n\n", inv.unit_total()));
        out.push_str(&file_tests_table(&inv.unit));
        out.push('\n');
    }
    if want("integration") {
        out.push_str(&format!(
            "**Integration tests** ({})\n\n",
            inv.integration_total()
        ));
        out.push_str(&file_tests_table(&inv.integration));
        out.push('\n');
    }
    if want("doc") {
        out.push_str(&format!("**Doc tests** ({})\n\n", inv.doc_total()));
        if inv.doc.is_empty() {
            out.push_str("_(none)_\n");
        } else {
            out.push_str("| file | doc-tests |\n|---|--:|\n");
            for f in &inv.doc {
                out.push_str(&format!("| `{}` | {} |\n", md_escape(&f.file), f.count));
            }
        }
    }
    Ok(out.trim_end().to_string() + "\n")
}

/// Render the `nornir:gen:coverage` section (feature N — maven-style): an
/// overall line/region % line + a per-crate table, from the pre-fetched latest
/// `coverage` run (`Ctx::coverage`). With `worst=N`, also a worst-files table.
/// Empty (a graceful `_(no coverage recorded)_`) when no run is pre-fetched, so
/// a repo that never ran `nornir coverage` still renders.
fn render_coverage(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let rows = ctx.coverage;
    if rows.is_empty() {
        return Ok("_(no coverage recorded — run `nornir coverage <repo>`)_\n".to_string());
    }
    let mut out = String::new();
    if let Some(o) = rows.iter().find(|r| r.scope == "overall") {
        out.push_str(&format!(
            "**Overall coverage:** {:.1}% lines · {:.1}% regions\n\n",
            o.line_pct(),
            o.region_pct()
        ));
    }
    out.push_str("| crate | line % | region % |\n|---|--:|--:|\n");
    for c in rows.iter().filter(|r| r.scope.starts_with("crate:")) {
        out.push_str(&format!(
            "| `{}` | {:.1}% | {:.1}% |\n",
            md_escape(&c.krate),
            c.line_pct(),
            c.region_pct()
        ));
    }
    // Optional worst-files table (`worst=N`).
    if let Some(n) = args.get("worst").and_then(|v| v.parse::<usize>().ok()) {
        let mut files: Vec<_> = rows
            .iter()
            .filter(|r| r.scope.starts_with("file:") && r.lines > 0)
            .collect();
        files.sort_by(|a, b| a.line_pct().total_cmp(&b.line_pct()));
        out.push_str("\n**Worst-covered files**\n\n| file | line % |\n|---|--:|\n");
        for f in files.iter().take(n) {
            out.push_str(&format!(
                "| `{}` | {:.1}% |\n",
                md_escape(&f.file),
                f.line_pct()
            ));
        }
    }
    Ok(out.trim_end().to_string() + "\n")
}

/// Map a numeric coverage code to the matrix glyph. Mirrors the numeric
/// convention a [`BenchSource::Static`](nornir_bench::BenchSource) capability
/// writer emits (skade's `Cov::code`): `1.0`=✅ full, `0.5`=◐ partial, `0.0`=✗
/// none, `-1.0`=NA not-applicable, `-2.0`=— unknown/unmeasured. Any code outside
/// that set also renders as `—` (unknown), so a stray value can never
/// masquerade as support. Compared with a small tolerance because the codes
/// round-trip through JSON floats.
fn capability_glyph(code: f64) -> &'static str {
    const EPS: f64 = 1e-9;
    if (code - 1.0).abs() < EPS {
        "✅"
    } else if (code - 0.5).abs() < EPS {
        "◐"
    } else if code.abs() < EPS {
        "✗"
    } else if (code + 1.0).abs() < EPS {
        "NA"
    } else {
        // `-2.0` (explicit unknown) and any unrecognised code both land here.
        "—"
    }
}

/// Render the `nornir:gen:capabilities` section: a ✓/✗ capability matrix built
/// from a [`BenchSource::Static`](nornir_bench::BenchSource) row's
/// `cap.<slug>.<rival>` numeric keys — the first-class renderer for the
/// static-capabilities seam (issue #13) so any repo can render its
/// feature-matrix without hand-rolling a namespaced marker.
///
/// Rows are capability slugs; columns are `ours` + the rival systems, with the
/// `ours` column bold. Deterministic order: rows by slug, columns `ours`-first
/// then the rest alphabetically. Graceful (never an error) when no run or no
/// matching Static row is present, so `nornir docs check` doesn't fail merely
/// because the static bench hasn't been (re)run.
///
/// Args:
///   - `source=<bench-name>` (required) — the Static result to read (e.g.
///     `skade.capabilities`).
///   - `ours=<rival-key>` — the column to bold as *ours*; defaults to the
///     `source` name with a trailing `.capabilities` stripped (so
///     `skade.capabilities` ⇒ `skade`).
fn render_capabilities(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let source = args
        .get("source")
        .ok_or_else(|| anyhow!("`capabilities` needs a `source=<bench-name>` arg"))?;
    let Some(run) = usable_run(ctx, args) else {
        return Ok(format!(
            "_(no capability matrix yet — run the `{source}` static-capabilities bench)_\n"
        ));
    };
    // Only a Static row is a capability matrix; a measured row sharing the name
    // would be a category error, so require the tag.
    let Some(res) = run
        .results
        .iter()
        .find(|r| r.name == *source && r.is_static())
    else {
        return Ok(format!(
            "_(no `{source}` static-capabilities row in the latest run)_\n"
        ));
    };

    // Which column is *ours* (bold). Default: the source name minus a trailing
    // `.capabilities` (`skade.capabilities` ⇒ `skade`).
    let ours = args.get("ours").cloned().unwrap_or_else(|| {
        source
            .strip_suffix(".capabilities")
            .unwrap_or(source)
            .to_string()
    });

    // Collect (slug, rival) → code from the `cap.<slug>.<rival>` numeric keys.
    // The `rsplit_once('.')` peels the rival (last dot-segment) off the slug, so
    // the accompanying `capability_rows` count and any non-`cap.` metric are
    // naturally skipped.
    let mut cells: HashMap<(String, String), f64> = HashMap::new();
    let mut slugs: Vec<String> = Vec::new();
    let mut rivals: Vec<String> = Vec::new();
    for (k, v) in &res.metrics {
        let Some(rest) = k.strip_prefix("cap.") else {
            continue;
        };
        let Some((slug, rival)) = rest.rsplit_once('.') else {
            continue;
        };
        let Some(code) = v.as_f64() else { continue };
        if !slugs.iter().any(|s| s == slug) {
            slugs.push(slug.to_string());
        }
        if !rivals.iter().any(|r| r == rival) {
            rivals.push(rival.to_string());
        }
        cells.insert((slug.to_string(), rival.to_string()), code);
    }
    if cells.is_empty() {
        return Ok(format!(
            "_(the `{source}` row carries no `cap.<slug>.<rival>` capability cells)_\n"
        ));
    }

    // Deterministic order: rows by slug; columns = ours first (if present),
    // then the remaining rivals alphabetically.
    slugs.sort();
    rivals.sort();
    let mut cols: Vec<String> = Vec::new();
    if rivals.iter().any(|r| *r == ours) {
        cols.push(ours.clone());
    }
    for r in &rivals {
        if *r != ours {
            cols.push(r.clone());
        }
    }
    let is_ours = |c: &str| c == ours;

    // Header + alignment separator (each column centre-aligned like skade's).
    let mut out = String::from("| capability |");
    for c in &cols {
        if is_ours(c) {
            out.push_str(&format!(" **{}** |", md_escape(c)));
        } else {
            out.push_str(&format!(" {} |", md_escape(c)));
        }
    }
    out.push_str("\n|---|");
    for _ in &cols {
        out.push_str(":--:|");
    }
    out.push('\n');
    // One line per capability; the `ours` cell is bold.
    for slug in &slugs {
        out.push_str(&format!("| {} |", md_escape(slug)));
        for c in &cols {
            let glyph = cells
                .get(&(slug.clone(), c.clone()))
                .map(|code| capability_glyph(*code))
                .unwrap_or("—");
            if is_ours(c) {
                out.push_str(&format!(" **{glyph}** |"));
            } else {
                out.push_str(&format!(" {glyph} |"));
            }
        }
        out.push('\n');
    }
    Ok(out)
}

fn file_tests_table(files: &[crate::test_inventory::FileTests]) -> String {
    if files.is_empty() {
        return "_(none)_\n".to_string();
    }
    let mut out = String::from("| file | tests |\n|---|---|\n");
    for f in files {
        let names = f
            .tests
            .iter()
            .map(|t| format!("`{}`", md_escape(t)))
            .collect::<Vec<_>>()
            .join(", ");
        out.push_str(&format!("| `{}` | {} |\n", md_escape(&f.file), names));
    }
    out
}

/// Parse a `best=metric:low,other:high` marker arg into per-metric direction
/// overrides. Unparseable pairs are skipped (the suffix fallback then applies).
fn parse_best_overrides(arg: Option<&str>) -> HashMap<String, nornir_bench::MetricDirection> {
    use nornir_bench::MetricDirection;
    let mut out = HashMap::new();
    let Some(s) = arg else { return out };
    for pair in s.split(',') {
        if let Some((metric, dir)) = pair.split_once(':') {
            let d = match dir.trim().to_ascii_lowercase().as_str() {
                "high" | "max" | "up" => MetricDirection::High,
                "low" | "min" | "down" => MetricDirection::Low,
                "neutral" | "none" => MetricDirection::Neutral,
                _ => continue,
            };
            out.insert(metric.trim().to_string(), d);
        }
    }
    out
}

/// Format a metric value for readability. Millions and up collapse to a unit
/// suffix (3_390_444.67 → "3.39M", 2_375_747.21 → "2.38M") so wide columns stay
/// scannable instead of becoming a wall of digits; smaller values keep full
/// precision as PLAIN digits — no thousands separators (12809.87 → "12809.87",
/// L3/L8). Integers drop the decimal tail. Display only — winner selection
/// always uses the raw f64.
pub(crate) fn fmt_metric(f: f64) -> String {
    let a = f.abs();
    if a >= 1e6 {
        let (scaled, suffix) = if a >= 1e12 {
            (f / 1e12, "T")
        } else if a >= 1e9 {
            (f / 1e9, "B")
        } else {
            (f / 1e6, "M")
        };
        let s = format!("{scaled:.2}");
        let s = s.trim_end_matches('0').trim_end_matches('.');
        return format!("{s}{suffix}");
    }
    // A thousand and up: round to a whole number — the fractional tail (8,869.62)
    // is just noise at that magnitude.
    if a >= 1e3 {
        return group_thousands(&format!("{}", f.round() as i64));
    }
    let plain = if f.fract() == 0.0 {
        format!("{}", f as i64)
    } else {
        format!("{f:.2}")
    };
    group_thousands(&plain)
}

/// Pick one uniform magnitude (divisor, suffix) for a whole column / chart series
/// from its largest |value|, so every cell renders in the *same* unit — 2.12M
/// next to 0.00M — instead of mixing "2.12M" with "3,930". Returns `None` below a
/// million, where plain, un-separated values already read cleanly.
pub(crate) fn metric_scale(max_abs: f64) -> Option<(f64, &'static str)> {
    if max_abs >= 1e12 {
        Some((1e12, "T"))
    } else if max_abs >= 1e9 {
        Some((1e9, "B"))
    } else if max_abs >= 1e6 {
        Some((1e6, "M"))
    } else {
        None
    }
}

/// Decide how a whole column / chart series prints: a shared magnitude
/// (divisor, suffix) from the column max, plus a shared decimal count chosen so
/// the *smallest* non-zero value still shows ~3 significant figures — otherwise a
/// 2.12M leader would force a 3,930 also-ran to round to a useless "0.00M". The
/// decimals apply to every cell, so the column stays aligned (2.11930M next to
/// 0.00393M). Returns `None` below a million, where plain, un-separated
/// per-value [`fmt_metric`] already reads cleanly.
pub(crate) fn column_format(vals: &[f64]) -> Option<(f64, &'static str, usize)> {
    let max_abs = vals.iter().copied().map(f64::abs).fold(0.0_f64, f64::max);
    let (div, suffix) = metric_scale(max_abs)?;
    let min_scaled = vals
        .iter()
        .copied()
        .map(f64::abs)
        .filter(|v| *v > 0.0)
        .map(|v| v / div)
        .fold(f64::INFINITY, f64::min);
    // ~3 sig-figs of the smallest scaled value; floor 2, cap 6.
    let decimals = if min_scaled.is_finite() && min_scaled > 0.0 {
        ((2 - min_scaled.log10().floor() as i32).max(2) as usize).min(6)
    } else {
        2
    };
    Some((div, suffix, decimals))
}

/// Format one value inside its column's [`column_format`] (uniform suffix +
/// decimals), or fall back to per-value [`fmt_metric`] when the column carries no
/// million-plus value.
pub(crate) fn fmt_metric_scaled(f: f64, fmt: Option<(f64, &'static str, usize)>) -> String {
    match fmt {
        Some((div, suffix, decimals)) => format!("{:.*}{suffix}", decimals, f / div),
        None => fmt_metric(f),
    }
}

/// Numeric strings render WITHOUT thousands separators — `1622`, never `1,622`
/// or `1.622` (a decision for the bench tables: bare digits read cleanest and
/// never collide with a decimal point). Kept as a pass-through so every caller
/// funnels through one place if grouping is ever wanted back.
fn group_thousands(s: &str) -> String {
    s.to_string()
}

/// Trophy (🏆) set: the names of *our* rows that beat a long-reigning
/// "hard-broken record" rival — one declared in `<repo>/.nornir/records.toml`
/// (keyed by the rival's workload name; fields `metric` default `decompress_mbs`).
/// A record earns the badge ONLY when one of our rows actually beats it on that
/// metric in THIS table, so a contended run where we lose shows no trophy. Empty
/// when the file is absent/unparseable or no record is present/beaten.
fn hard_broken_trophies(
    ctx: &Ctx,
    results: &[&nornir_bench::BenchResult],
    ours_tokens: &[String],
) -> std::collections::HashSet<String> {
    let mut trophies = std::collections::HashSet::new();
    let Ok(text) = std::fs::read_to_string(ctx.repo_root.join(".nornir/records.toml")) else {
        return trophies;
    };
    let Ok(tbl) = text.parse::<toml::Table>() else {
        return trophies;
    };
    // Word-bounded (H3): a `self=` token marks a row ours only on an exact or
    // segment match — `self=bzip2` must NOT claim `lbzip2`/`zoomies-lbzip2`.
    let is_ours = |name: &str| ours_tokens.iter().any(|t| token_matches(name, t));
    for (rival, spec) in &tbl {
        // The record rival must be one of THIS table's rows to be beatable here.
        let Some(rv) = results.iter().find(|r| r.name.as_str() == rival.as_str()) else {
            continue;
        };
        let metric = spec
            .get("metric")
            .and_then(|v| v.as_str())
            .unwrap_or("decompress_mbs");
        let Some(rival_val) = rv.metrics.get(metric).and_then(|v| v.as_f64()) else {
            continue;
        };
        // The fastest of OUR rows on that metric — trophy it iff it beats the record.
        let best = results
            .iter()
            .filter(|r| is_ours(&r.name))
            .filter_map(|r| {
                r.metrics
                    .get(metric)
                    .and_then(|v| v.as_f64())
                    .map(|f| (f, r.name.clone()))
            })
            .fold(None::<(f64, String)>, |acc, (f, n)| match acc {
                Some((bf, _)) if bf >= f => acc,
                _ => Some((f, n)),
            });
        if let Some((of, on)) = best {
            if of > rival_val {
                trophies.insert(on);
            }
        }
    }
    trophies
}

fn render_depgraph(ctx: &Ctx) -> Result<String> {
    // DR1: materialize sibling path-deps (clone+symlink) before `cargo metadata`
    // so a headless server-side docs render of a path-dep'd repo (nornir → skade)
    // resolves the same siblings the SBOM security scan does. The workspace's
    // `workspace_root` is the `git/` dir holding every member checkout — the
    // scan_root. DR2: a still-unresolved sibling surfaces a clear named error.
    // The network clone half of the prep stays in nornir (needs gitio) and is
    // INJECTED via `Ctx::path_dep_cloner` (nornir passes
    // `security::clone_missing_path_dep_siblings`); this leaf crate does the
    // pure symlink materialization + unresolved diagnostics. No cloner ⇒ 0.
    let g = depgraph::extract_with_path_deps(ctx.repo_root, ctx.workspace_root, &|repo, root| {
        match ctx.path_dep_cloner {
            Some(clone_missing) => clone_missing(repo, root),
            None => 0,
        }
    })?;
    // No silent gaps: if `cargo metadata` yielded no crates (not a cargo
    // workspace, or metadata produced nothing), emit a visible note instead of
    // an empty marker so the reader knows *why* there's no graph and how to fix
    // it — rather than seeing nothing at all.
    if g.nodes.is_empty() {
        return Ok(format!(
            "_no dependency-graph data for `{}` — `cargo metadata` returned no \
             packages. Ensure this is a Cargo workspace and re-run \
             `nornir docs render`._\n",
            ctx.repo_root.display()
        ));
    }
    #[cfg(feature = "export")]
    {
        // Generated media lives under `.nornir/assets/` (tracked) alongside the
        // doc sources — one nornir-owned namespace, no copy at the repo root.
        // Git hosts (Codeberg/GitHub) resolve this relative path in the web UI,
        // and the typst exporter resolves it via the repo-root filesystem root.
        let rel = std::path::PathBuf::from(".nornir/assets/depgraph.svg");
        let abs = ctx.repo_root.join(&rel);
        // Markdown-only (pre-commit hook): emit the image link but do NOT
        // regenerate the SVG — the committed asset from a prior full render is
        // reused, keeping the commit cheap and the markdown deterministic.
        if !ctx.no_assets {
            crate::svg::render_to_file(&g, &abs)?;
        }
        // Emit the link relative to the doc being rendered. README (repo root)
        // ⇒ `.nornir/assets/depgraph.svg`; a doc under `.nornir/` ⇒
        // `assets/depgraph.svg`. Git hosts resolve image src relative to the
        // file, so a repo-root-relative path would 404 inside `.nornir/`.
        let link = doc_relative_asset(ctx, &abs);
        return Ok(format!("![workspace dependency graph]({link})\n"));
    }
    #[cfg(not(feature = "export"))]
    {
        // No typst engine in this build: emit the self-contained static SVG
        // inline (no JS, no build step — NUKE-MERMAID house style).
        let mut out = g.to_svg();
        if !out.ends_with('\n') {
            out.push('\n');
        }
        Ok(out)
    }
}

/// Compute the link to `asset_abs` (an absolute path under `repo_root`)
/// relative to the doc being rendered. Falls back to the repo-root-relative
/// path when `ctx.doc_dir` is unset or the two diverge outside the repo.
///
/// Pure path arithmetic over normalised components (no filesystem access):
/// walk off the shared prefix of `doc_dir` and the asset, emitting one `..`
/// per remaining `doc_dir` component, then the asset's tail. Both inputs are
/// taken relative to `repo_root` so the result is repo-portable.
// Reached from the `export`-gated asset emitters (depgraph/bench-chart); the
// no-export build still compiles it for the unit test below.
#[cfg_attr(not(feature = "export"), allow(dead_code))]
fn doc_relative_asset(ctx: &Ctx, asset_abs: &Path) -> String {
    use std::path::Component;
    let repo_rel = asset_abs
        .strip_prefix(ctx.repo_root)
        .map(|p| p.to_path_buf())
        .unwrap_or_else(|_| asset_abs.to_path_buf());
    let Some(doc_dir) = ctx.doc_dir else {
        return repo_rel.display().to_string();
    };
    let Ok(doc_rel) = doc_dir.strip_prefix(ctx.repo_root) else {
        return repo_rel.display().to_string();
    };

    let from: Vec<&std::ffi::OsStr> = doc_rel
        .components()
        .filter_map(|c| match c {
            Component::Normal(s) => Some(s),
            _ => None,
        })
        .collect();
    let to: Vec<&std::ffi::OsStr> = repo_rel
        .components()
        .filter_map(|c| match c {
            Component::Normal(s) => Some(s),
            _ => None,
        })
        .collect();

    // Drop the shared leading components.
    let common = from
        .iter()
        .zip(to.iter())
        .take_while(|(a, b)| a == b)
        .count();
    let mut out = PathBuf::new();
    for _ in common..from.len() {
        out.push("..");
    }
    for s in &to[common..] {
        out.push(s);
    }
    if out.as_os_str().is_empty() {
        ".".to_string()
    } else {
        out.display().to_string()
    }
}

fn resolve_binary(ctx: &Ctx, raw: &str) -> PathBuf {
    let p = PathBuf::from(raw);
    if p.is_absolute() {
        p
    } else if ctx.repo_root.join(&p).exists() {
        ctx.repo_root.join(&p)
    } else {
        ctx.workspace_root.join(&p)
    }
}

fn render_symbols(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let bin_arg = args
        .get("binary")
        .ok_or_else(|| anyhow!("section `symbols` needs binary=PATH"))?;
    let limit: usize = args.get("limit").and_then(|v| v.parse().ok()).unwrap_or(20);
    let binary = resolve_binary(ctx, bin_arg);
    let syms = artifact::extract_symbols(&binary, ctx.workspace_root)?;
    let mut visible: Vec<&artifact::Symbol> = syms
        .iter()
        .filter(|s| !s.name_demangled.contains("::{{closure}}"))
        .collect();
    visible.sort_by(|a, b| b.size_bytes.unwrap_or(0).cmp(&a.size_bytes.unwrap_or(0)));
    visible.truncate(limit);
    let mut out = String::new();
    out.push_str(&format!(
        "_top {} symbols by size from `{}`_\n\n",
        visible.len(),
        bin_arg
    ));
    out.push_str("| symbol | size | file |\n|--------|------|------|\n");
    for s in &visible {
        let file = if s.file.is_empty() {
            "?"
        } else {
            s.file.as_str()
        };
        let size = s
            .size_bytes
            .map(|n| n.to_string())
            .unwrap_or_else(|| "-".into());
        out.push_str(&format!(
            "| `{}` | {} | {} |\n",
            md_escape(&s.name_demangled),
            size,
            file
        ));
    }
    Ok(out)
}

fn render_callgraph(ctx: &Ctx, args: &HashMap<String, String>) -> Result<String> {
    let bin_arg = args
        .get("binary")
        .ok_or_else(|| anyhow!("section `callgraph` needs binary=PATH"))?;
    let limit: usize = args.get("limit").and_then(|v| v.parse().ok()).unwrap_or(15);
    let binary = resolve_binary(ctx, bin_arg);
    let edges = callgraph_dwarf::extract_callgraph(&binary, ctx.workspace_root)?;
    let mut count: HashMap<String, usize> = HashMap::new();
    for e in &edges {
        *count.entry(e.callee.clone()).or_default() += 1;
    }
    let mut ranked: Vec<(String, usize)> = count.into_iter().collect();
    ranked.sort_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
    ranked.truncate(limit);
    let mut out = String::new();
    out.push_str(&format!(
        "_{} inline edges in `{}`; top {} callees:_\n\n",
        edges.len(),
        bin_arg,
        ranked.len()
    ));
    out.push_str("| callee | inline sites |\n|--------|-------------:|\n");
    for (n, c) in ranked {
        out.push_str(&format!("| `{}` | {} |\n", md_escape(&n), c));
    }
    Ok(out)
}

fn md_escape(s: &str) -> String {
    s.replace('|', "\\|").replace('`', "\\`")
}

// ----- tests -----------------------------------------------------------------

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::{Map, Value};

    fn ctx<'a>(root: &'a Path, run: Option<&'a BenchRun>) -> Ctx<'a> {
        Ctx::new(root, root, run)
    }

    #[test]
    fn doc_relative_asset_is_relative_to_doc_dir() {
        let root = Path::new("/repo");
        let asset = Path::new("/repo/.nornir/assets/depgraph.svg");

        // README at repo root → repo-root-relative path.
        let c_root = Ctx::new(root, root, None).with_doc_dir(root);
        assert_eq!(
            doc_relative_asset(&c_root, asset),
            ".nornir/assets/depgraph.svg"
        );

        // design.md under .nornir/ → the leading `.nornir/` is cancelled by one
        // `../`, yielding the clean doc-relative `assets/depgraph.svg`.
        let nornir_dir = root.join(".nornir");
        let c_nornir = Ctx::new(root, root, None).with_doc_dir(&nornir_dir);
        assert_eq!(doc_relative_asset(&c_nornir, asset), "assets/depgraph.svg");

        // No doc_dir → repo-root-relative (historical default).
        let c_none = Ctx::new(root, root, None);
        assert_eq!(
            doc_relative_asset(&c_none, asset),
            ".nornir/assets/depgraph.svg"
        );
    }

    /// `Ctx::markdown_only()` suppresses the heavy SVG asset write: with
    /// `export`, `render_depgraph` must emit the image link but NOT create
    /// the depgraph.svg file (reusing the committed one). This is the engine of
    /// the pre-commit hook's `--no-assets` behaviour. Inject a real cargo crate
    /// so the depgraph has a known node, then assert the marker body has the link
    /// and the SVG file was NOT written.
    #[cfg(feature = "export")]
    #[test]
    fn markdown_only_suppresses_svg_asset_write() {
        let t = tempfile::TempDir::new().unwrap();
        let root = t.path();
        std::fs::write(
            root.join("Cargo.toml"),
            "[package]\nname = \"widget_lib\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n\
             [dependencies]\nserde = \"1\"\n",
        )
        .unwrap();
        std::fs::create_dir_all(root.join("src")).unwrap();
        std::fs::write(root.join("src/lib.rs"), "pub fn noop() {}\n").unwrap();

        let svg = root.join(".nornir/assets/depgraph.svg");

        // markdown_only ⇒ NO file written, but the link is still emitted.
        let c = Ctx::new(root, root, None).markdown_only();
        let body = render_depgraph(&c).expect("render depgraph");
        assert!(
            body.contains("![workspace dependency graph]"),
            "markdown-only depgraph must still emit the image link; got {body}"
        );
        assert!(
            !svg.exists(),
            "markdown-only render must NOT (re)write the depgraph SVG asset"
        );

        // Full render (assets on) DOES write the SVG.
        let c_full = Ctx::new(root, root, None);
        render_depgraph(&c_full).expect("render depgraph full");
        assert!(
            svg.exists(),
            "full render must write the depgraph SVG asset"
        );
    }

    fn run_fixture() -> BenchRun {
        let mut m: Map<String, Value> = Map::new();
        m.insert("ops".to_string(), Value::from(123.45f64));
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-05-30".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "test".into(),
            cores: 8,
            results: vec![nornir_bench::BenchResult {
                name: "decode".into(),
                metrics: m,
                ..Default::default()
            }],
            tests: vec![],
        }
    }

    fn arm(name: &str, val: f64) -> nornir_bench::BenchResult {
        let mut m: Map<String, Value> = Map::new();
        m.insert("decompress_mbs".into(), Value::from(val));
        nornir_bench::BenchResult {
            name: name.into(),
            metrics: m,
            ..Default::default()
        }
    }

    fn multi_arm_run(arms: &[(&str, f64)]) -> BenchRun {
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-13".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "test".into(),
            cores: 12,
            results: arms.iter().map(|(n, v)| arm(n, *v)).collect(),
            tests: vec![],
        }
    }

    /// A PREVIEW run must be invisible to an ordinary bench marker, so the
    /// non-destructive guard keeps the committed table. znippy-zoomies' README
    /// carries measured 12-core `loki` numbers; an under-floor 32-core preview must
    /// not replace a single one of them.
    #[test]
    fn a_preview_run_never_reaches_a_marker_that_did_not_ask_for_it() {
        let mut run = multi_arm_run(&[("znippy-gz", 12800.0), ("pigz", 459.19)]);
        run.machine =
            "PREVIEW · AMD Ryzen Threadripper PRO 3975WX 32-Cores · corpus 1024 MB".into();
        let root = Path::new("/repo");
        let c = ctx(root, Some(&run));

        // No opt-in ⇒ the renderer reports absence …
        let plain = render_benches(&c, &HashMap::new()).unwrap();
        assert!(
            is_no_data_placeholder(&plain),
            "preview leaked into a plain marker: {plain}"
        );

        // … and `render` therefore KEEPS whatever the doc already had.
        let m = Marker {
            name: "benches".into(),
            args: HashMap::new(),
            line_start: 0,
            line_end: 2,
        };
        let kept = render(
            &c,
            &m,
            "| workload | decompress_mbs |\n| znippy-gz | 5760 |\n",
        )
        .unwrap();
        assert!(
            kept.contains("5760"),
            "committed table was overwritten by a preview: {kept}"
        );

        // Opting in is the only way through.
        let args: HashMap<String, String> = [("preview".to_string(), "yes".to_string())]
            .into_iter()
            .collect();
        let opted = render_benches(&c, &args).unwrap();
        assert!(
            opted.contains("12800"),
            "preview=yes did not admit the preview: {opted}"
        );
        assert!(
            opted.contains("PREVIEW"),
            "the preview stamp must survive into the table"
        );
    }

    /// A non-preview run is unaffected by the gate.
    #[test]
    fn an_ordinary_run_still_renders_without_opting_in() {
        let run = multi_arm_run(&[("znippy-gz", 5760.0), ("pigz", 589.32)]);
        let body = render_benches(&ctx(Path::new("/repo"), Some(&run)), &HashMap::new()).unwrap();
        assert!(body.contains("5760"), "{body}");
    }

    /// `suspect=exclude` withholds an implausible arm AND says so — the table and
    /// its caveat come from one screen, so they cannot disagree.
    #[test]
    fn an_implausible_arm_is_withheld_with_a_rendered_reason() {
        let mut fabric: Map<String, Value> = Map::new();
        fabric.insert("fabric_s".into(), Value::from(1.4929e-5f64));
        fabric.insert("rows_per_s".into(), Value::from(6.698e9f64));
        let mut honest: Map<String, Value> = Map::new();
        honest.insert("scan_s".into(), Value::from(0.00206f64));
        honest.insert("rows_per_s".into(), Value::from(48.5e6f64));
        let run = BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-23".into(),
            timestamp: None,
            version: "0.1.3".into(),
            machine: "oden".into(),
            cores: 32,
            results: vec![
                nornir_bench::BenchResult {
                    name: "bifrost_fabric".into(),
                    metrics: fabric,
                    ..Default::default()
                },
                nornir_bench::BenchResult {
                    name: "file_source_scan".into(),
                    metrics: honest,
                    ..Default::default()
                },
            ],
            tests: vec![],
        };
        let c = ctx(Path::new("/repo"), Some(&run));

        let args: HashMap<String, String> = [("suspect".to_string(), "exclude".to_string())]
            .into_iter()
            .collect();
        let body = render_benches(&c, &args).unwrap();
        assert!(
            body.contains("file_source_scan"),
            "the honest arm must stay: {body}"
        );
        assert!(
            !body.contains("| bifrost_fabric |"),
            "the arm was still tabled: {body}"
        );
        assert!(
            body.contains("withheld from this table"),
            "no rendered reason: {body}"
        );

        // Default is `flag`: the row stays, marked, with the reason underneath.
        let flagged = render_benches(&c, &HashMap::new()).unwrap();
        assert!(flagged.contains("bifrost_fabric ⚠"), "{flagged}");
        assert!(flagged.contains("not credible as real work"), "{flagged}");

        // `off` restores the unscreened table.
        let off: HashMap<String, String> = [("suspect".to_string(), "off".to_string())]
            .into_iter()
            .collect();
        let raw = render_benches(&c, &off).unwrap();
        assert!(!raw.contains('⚠'), "suspect=off still flagged: {raw}");
    }

    #[test]
    fn token_matches_is_word_bounded_not_substring() {
        // H3: rival ids are bare substrings of ours (letter-adjacent) → NO match.
        assert!(
            !token_matches("lbzip2", "bzip2"),
            "bzip2 ⊄ lbzip2 (l-adjacent)"
        );
        assert!(
            !token_matches("zoomies-lbzip2", "bzip2"),
            "bzip2 ⊄ zoomies-lbzip2"
        );
        // Exact + separator-delimited segments DO match.
        assert!(token_matches("bzip2", "bzip2"));
        assert!(token_matches("zoomies-jar", "zoomies-jar"));
        assert!(
            token_matches("zoomies-lbzip2", "lbzip2"),
            "`-`-delimited segment matches"
        );
        // Variant-folding (skade/holger mashups) must survive: `_`-delimited segment.
        assert!(token_matches("data_pipe_skade_s3", "skade_s3"));
        assert!(token_matches("oxr_skade", "skade"));
        assert!(!token_matches("data_pipe_skade_nvme", "skade_s3"));
        // self= word-boundary: `self=zoomies-lbzip2` claims ONLY ours.
        assert!(!token_matches("lbzip2", "zoomies-lbzip2"));
        assert!(!token_matches("bzip2", "zoomies-lbzip2"));
    }

    #[test]
    fn compare_selects_exact_arm_no_rival_contamination() {
        // H3 verified case: rival ids are substrings of our arm ids. `compare=bzip2`
        // must select ONLY the `bzip2` row (value 100) — NOT lbzip2 (700) and NOT
        // zoomies-lbzip2 (755, the number that leaked into the bzip2 row pre-fix).
        let run = multi_arm_run(&[
            ("bzip2", 100.0),
            ("lbzip2", 700.0),
            ("zoomies-lbzip2", 755.0),
            ("jar", 200.0),
            ("zoomies-jar", 900.0),
            ("zip", 300.0),
            ("zoomies-zip", 800.0),
        ]);
        let root = Path::new("/repo");
        let c = ctx(root, Some(&run));

        let mut args = HashMap::new();
        args.insert("compare".to_string(), "bzip2".to_string());
        args.insert("cols".to_string(), "decompress_mbs".to_string());
        let out = render_benches(&c, &args).unwrap();
        assert!(out.contains("bzip2"), "bzip2 row present:\n{out}");
        assert!(out.contains("100"), "bzip2's OWN number shown:\n{out}");
        assert!(
            !out.contains("755"),
            "must NOT show zoomies-lbzip2's number:\n{out}"
        );
        assert!(
            !out.contains("700"),
            "must NOT show lbzip2's number:\n{out}"
        );
        assert!(
            !out.contains("zoomies-lbzip2"),
            "rival row excluded:\n{out}"
        );

        // The renamed self= arm selects itself cleanly (no substring bleed).
        let mut a2 = HashMap::new();
        a2.insert("compare".to_string(), "zoomies-lbzip2".to_string());
        a2.insert("self".to_string(), "zoomies-lbzip2".to_string());
        a2.insert("cols".to_string(), "decompress_mbs".to_string());
        let out2 = render_benches(&c, &a2).unwrap();
        assert!(
            out2.contains("755"),
            "ours row shows its own number:\n{out2}"
        );
        assert!(
            !out2.contains("100"),
            "bzip2's number must not leak in:\n{out2}"
        );
    }

    #[test]
    fn parses_and_rewrites_bench_section() {
        let r = run_fixture();
        let d = tempfile::tempdir().unwrap();
        let p = d.path().join("README.md");
        std::fs::write(
            &p,
            "# x\n\n<!-- nornir:gen:start:bench -->\nstale\n<!-- nornir:gen:end:bench -->\n\ntail\n",
        )
        .unwrap();
        let c = ctx(d.path(), Some(&r));
        let rep = assemble_file(&p, &c).unwrap();
        assert!(rep.changed);
        assert_eq!(rep.sections, vec!["bench".to_string()]);
        let txt = std::fs::read_to_string(&p).unwrap();
        assert!(txt.contains("v0.1.0"));
        assert!(txt.contains("decode"));
        assert!(txt.ends_with("tail\n"));
    }

    #[test]
    fn bench_history_renders_rows_newest_first() {
        let mk = |date: &str, ver: &str, ops: f64| -> BenchRun {
            let mut m: Map<String, Value> = Map::new();
            m.insert("ops".into(), Value::from(ops));
            BenchRun {
                id: Default::default(),
                machine_facts: None,
                date: date.into(),
                timestamp: None,
                version: ver.into(),
                machine: "tr".into(),
                cores: 8,
                results: vec![nornir_bench::BenchResult {
                    name: "x".into(),
                    metrics: m,
                    ..Default::default()
                }],
                tests: vec![],
            }
        };
        // Intentionally not pre-sorted — the renderer must order newest-first.
        let history = vec![
            mk("2026-05-01", "0.1.0", 100.0),
            mk("2026-06-01", "0.2.0", 200.0),
        ];
        let root = Path::new(".");
        let c = Ctx::new(root, root, None).with_history(&history);
        let text =
            "<!-- nornir:gen:start:bench_history -->\n<!-- nornir:gen:end:bench_history -->\n";
        let (out, sections) = rewrite_str(text, &c).unwrap();
        assert_eq!(sections, vec!["bench_history".to_string()]);
        assert!(
            out.contains("| Version | Date | Machine |"),
            "header: {out}"
        );
        let i2 = out.find("v0.2.0").expect("v0.2.0 present");
        let i1 = out.find("v0.1.0").expect("v0.1.0 present");
        assert!(i2 < i1, "newest (0.2.0) must come first:\n{out}");
        assert!(
            out.contains("200.00") && out.contains("100.00"),
            "best-metric values: {out}"
        );
    }

    #[test]
    fn bench_history_empty_is_graceful() {
        let root = Path::new(".");
        let c = Ctx::new(root, root, None); // no history attached
        let text =
            "<!-- nornir:gen:start:bench_history -->\n<!-- nornir:gen:end:bench_history -->\n";
        let (out, _) = rewrite_str(text, &c).unwrap();
        assert!(out.contains("no bench history"), "graceful empty: {out}");
    }

    /// feature N: the `nornir:gen:coverage` marker fills with the overall % + a
    /// per-crate table (+ worst files with `worst=N`) from pre-fetched coverage
    /// rows. INJECT known rows → ASSERT the rendered table values (LAW 1).
    #[test]
    fn coverage_marker_fills_overall_and_per_crate() {
        use nornir_coverage::CoverageRow;
        let r = |scope: &str, krate: &str, file: &str, l: i64, lc: i64| CoverageRow {
            run_id: "run".into(),
            ts_micros: 1,
            repo: "nornir".into(),
            scope: scope.into(),
            krate: krate.into(),
            file: file.into(),
            lines: l,
            lines_covered: lc,
            regions: l,
            regions_covered: lc,
        };
        let rows = vec![
            r("overall", "", "", 100, 80),
            r("crate:nornir", "nornir", "", 60, 42),
            r("crate:nornir-testmatrix", "nornir-testmatrix", "", 40, 38),
            r(
                "file:src/viz/test_tab.rs",
                "nornir",
                "src/viz/test_tab.rs",
                50,
                20,
            ),
        ];
        let root = Path::new(".");
        let c = Ctx::new(root, root, None).with_coverage(&rows);
        let text = "<!-- nornir:gen:start:coverage worst=1 -->\n<!-- nornir:gen:end:coverage -->\n";
        let (out, sections) = rewrite_str(text, &c).unwrap();
        assert_eq!(sections, vec!["coverage".to_string()]);
        // Overall 80/100 = 80.0% lines.
        assert!(out.contains("80.0% lines"), "overall line %: {out}");
        // Per-crate table rows: nornir 42/60 = 70.0%, testmatrix 38/40 = 95.0%.
        assert!(
            out.contains("`nornir`") && out.contains("70.0%"),
            "nornir crate row: {out}"
        );
        assert!(
            out.contains("`nornir-testmatrix`") && out.contains("95.0%"),
            "testmatrix row: {out}"
        );
        // worst=1 → the viz file (40%) shows in the worst-files table.
        assert!(out.contains("Worst-covered files"), "worst table: {out}");
        assert!(
            out.contains("src/viz/test_tab.rs") && out.contains("40.0%"),
            "worst file: {out}"
        );
    }

    /// The `coverage` marker renders a graceful fallback when no run is attached.
    #[test]
    fn coverage_marker_empty_is_graceful() {
        let root = Path::new(".");
        let c = Ctx::new(root, root, None); // no coverage attached
        let text = "<!-- nornir:gen:start:coverage -->\n<!-- nornir:gen:end:coverage -->\n";
        let (out, _) = rewrite_str(text, &c).unwrap();
        assert!(
            out.contains("no coverage recorded"),
            "graceful empty: {out}"
        );
    }

    /// A synthetic Static capability row (the `cap.<slug>.<rival>` seam) renders
    /// into the expected ✅/◐/✗/NA/— glyph table, `ours` column bold, columns
    /// `ours`-first (default derived from the `.capabilities` source name).
    /// INJECT known codes → ASSERT the exact rendered glyph cells (LAW 1).
    #[test]
    fn capabilities_marker_renders_glyph_matrix() {
        let mut m: Map<String, Value> = Map::new();
        // rows: speed, safety, portable ; cols: mytool (ours) + rival.
        m.insert("cap.speed.mytool".into(), Value::from(1.0)); // ✅
        m.insert("cap.speed.rival".into(), Value::from(0.5)); // ◐
        m.insert("cap.safety.mytool".into(), Value::from(1.0)); // ✅
        m.insert("cap.safety.rival".into(), Value::from(0.0)); // ✗
        m.insert("cap.portable.mytool".into(), Value::from(-1.0)); // NA
        m.insert("cap.portable.rival".into(), Value::from(-2.0)); // —
        m.insert("capability_rows".into(), Value::from(3.0)); // must be ignored
        let run = BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-08".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "t".into(),
            cores: 4,
            results: vec![nornir_bench::BenchResult::static_capabilities(
                "mytool.capabilities",
                m,
            )],
            tests: vec![],
        };
        let root = Path::new(".");
        let c = ctx(root, Some(&run));
        let text = "<!-- nornir:gen:start:capabilities source=mytool.capabilities -->\n<!-- nornir:gen:end:capabilities -->\n";
        let (out, sections) = rewrite_str(text, &c).unwrap();
        assert_eq!(sections, vec!["capabilities".to_string()]);
        // Ours column (mytool) is bold in the header and defaulted from the
        // source name (`mytool.capabilities` ⇒ `mytool`), placed first.
        assert!(
            out.contains("| capability | **mytool** | rival |"),
            "header: {out}"
        );
        assert!(out.contains("|---|:--:|:--:|"), "separator: {out}");
        // Each row: ours cell bold, rival cell plain; every glyph level present.
        assert!(out.contains("| speed | **✅** | ◐ |"), "speed row: {out}");
        assert!(out.contains("| safety | **✅** | ✗ |"), "safety row: {out}");
        assert!(
            out.contains("| portable | **NA** | — |"),
            "portable row: {out}"
        );
        // The `capability_rows` count is not a `cap.` cell → no stray row.
        assert!(
            !out.contains("capability_rows"),
            "count metric leaked: {out}"
        );
    }

    /// `ours=` overrides which column is bold, and a graceful fallback renders
    /// when the run has no matching Static row.
    #[test]
    fn capabilities_ours_override_and_graceful() {
        let mut m: Map<String, Value> = Map::new();
        m.insert("cap.speed.foo".into(), Value::from(1.0));
        m.insert("cap.speed.bar".into(), Value::from(0.0));
        let run = BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-08".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "t".into(),
            cores: 4,
            results: vec![nornir_bench::BenchResult::static_capabilities("cap.row", m)],
            tests: vec![],
        };
        let root = Path::new(".");
        let c = ctx(root, Some(&run));
        // ours=bar ⇒ bar column first and bold (not the default).
        let text = "<!-- nornir:gen:start:capabilities source=cap.row ours=bar -->\n<!-- nornir:gen:end:capabilities -->\n";
        let (out, _) = rewrite_str(text, &c).unwrap();
        assert!(
            out.contains("| capability | **bar** | foo |"),
            "ours=bar header: {out}"
        );
        assert!(
            out.contains("| speed | **✗** | ✅ |"),
            "ours=bar row: {out}"
        );

        // Missing source row ⇒ graceful (never an error, so `docs check` is safe).
        let text2 = "<!-- nornir:gen:start:capabilities source=absent.capabilities -->\n<!-- nornir:gen:end:capabilities -->\n";
        let (out2, _) = rewrite_str(text2, &c).unwrap();
        assert!(
            out2.contains("no `absent.capabilities` static-capabilities row"),
            "graceful: {out2}"
        );
    }

    /// The code→glyph mapping is exhaustive AND a WRONG (out-of-set) code must
    /// fall back to `—` (unknown) — a stray value can never masquerade as ✅.
    #[test]
    fn capability_glyph_maps_every_code_and_unknown_falls_back() {
        assert_eq!(capability_glyph(1.0), "✅");
        assert_eq!(capability_glyph(0.5), "◐");
        assert_eq!(capability_glyph(0.0), "✗");
        assert_eq!(capability_glyph(-1.0), "NA");
        assert_eq!(capability_glyph(-2.0), "—");
        // Out-of-set codes render as the unknown glyph, never as support.
        assert_eq!(capability_glyph(0.7), "—");
        assert_eq!(capability_glyph(42.0), "—");
        assert_eq!(capability_glyph(-5.0), "—");
    }

    fn vs_run() -> BenchRun {
        // One workload, paired ours-vs-legacy throughput + a derived speedup.
        let mut m: Map<String, Value> = Map::new();
        m.insert("ljar_mbs".into(), Value::from(2527.0f64));
        m.insert("unzip_mbs".into(), Value::from(1404.0f64));
        m.insert("speedup_x".into(), Value::from(1.8f64));
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-06-05".into(),
            timestamp: None,
            version: "0.9.0".into(),
            machine: "test".into(),
            cores: 32,
            results: vec![nornir_bench::BenchResult {
                name: "jar_2000".into(),
                metrics: m,
                ..Default::default()
            }],
            tests: vec![],
        }
    }

    #[test]
    fn benches_pivots_and_bolds_winner() {
        let r = vs_run();
        let c = ctx(Path::new("/tmp"), Some(&r));
        let out = render_benches(&c, &HashMap::new()).unwrap();
        // pivot header carries the metric columns + the workload row
        assert!(out.contains("| workload |"), "got: {out}");
        assert!(out.contains("ljar_mbs"));
        assert!(out.contains("jar_2000"));
        // ljar wins the mbs comparison → bolded; unzip not; speedup (unit `x`,
        // a lone neutral cell) never bolded.
        assert!(out.contains("**2527**"), "winner not bolded: {out}");
        assert!(!out.contains("**1404**"), "loser bolded: {out}");
        assert!(!out.contains("**1.8"), "neutral bolded: {out}");
    }

    #[test]
    fn benches_exclude_and_bold_false() {
        // Two results: one normal, one "_st"; exclude drops the _st row, and
        // bold=false suppresses winner bolding.
        let mut a: Map<String, Value> = Map::new();
        a.insert("ljar_mbs".into(), Value::from(1000.0f64));
        a.insert("unzip_mbs".into(), Value::from(60.0f64));
        let mut b: Map<String, Value> = Map::new();
        b.insert("ljar_mbs".into(), Value::from(120.0f64));
        b.insert("unzip_mbs".into(), Value::from(60.0f64));
        let run = BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-06-06".into(),
            timestamp: None,
            version: "0.9.0".into(),
            machine: "tr".into(),
            cores: 32,
            results: vec![
                nornir_bench::BenchResult {
                    name: "ljar_guava".into(),
                    metrics: a,
                    ..Default::default()
                },
                nornir_bench::BenchResult {
                    name: "ljar_guava_st".into(),
                    metrics: b,
                    ..Default::default()
                },
            ],
            tests: vec![],
        };
        let c = ctx(Path::new("/tmp"), Some(&run));
        let mut args = HashMap::new();
        args.insert("exclude".to_string(), "_st".to_string());
        args.insert("bold".to_string(), "false".to_string());
        let out = render_benches(&c, &args).unwrap();
        assert!(out.contains("ljar_guava"), "got: {out}");
        assert!(!out.contains("ljar_guava_st"), "exclude failed: {out}");
        // no bolded *cell* (the run header is bold, but cells aren't)
        assert!(
            !out.contains("**1000**"),
            "bold=false should suppress cell bolding: {out}"
        );
        // header carries machine + cores
        assert!(
            out.contains("tr · 32 cores"),
            "header missing machine: {out}"
        );
    }

    #[test]
    fn benches_best_override_flips_direction() {
        let r = vs_run();
        let c = ctx(Path::new("/tmp"), Some(&r));
        // Force "lower mbs is better" via the marker arg → unzip wins.
        let mut args = HashMap::new();
        args.insert("best".to_string(), "ljar_mbs:low,unzip_mbs:low".to_string());
        let out = render_benches(&c, &args).unwrap();
        assert!(out.contains("**1404**"), "override not applied: {out}");
        assert!(!out.contains("**2527**"), "override ignored: {out}");
    }

    /// The data-driven pairing key snaps each of OUR codecs to its TRUE format
    /// rival, not a spurious one sharing an incidental letter.
    #[test]
    fn common_run_snaps_codec_to_its_format_rival() {
        assert_eq!(common_run("zoomie-lgz", "gzip"), 2); // "gz"
        assert_eq!(common_run("zoomie-lbzip2", "bzip2"), 5); // "bzip2"
        assert!(common_run("zoomie-lgz", "gzip") > common_run("zoomie-lgz", "bzip2"));
        assert!(common_run("zoomie-lbzip2", "bzip2") > common_run("zoomie-lbzip2", "gzip"));
    }

    /// A codec-family bench-run: two of OUR codecs (`zoomie-lgz`, `zoomie-lbzip2`)
    /// and their two format rivals (`gzip`, `bzip2`), each carrying a decode metric
    /// plus format-level `compress_mbs`/`ratio` columns.
    fn codec_run() -> BenchRun {
        let mk = |name: &str, decode: f64, compress: f64, ratio: f64| {
            let mut m: Map<String, Value> = Map::new();
            m.insert("decompress_mbs".into(), Value::from(decode));
            m.insert("compress_mbs".into(), Value::from(compress));
            m.insert("ratio".into(), Value::from(ratio));
            nornir_bench::BenchResult {
                name: name.into(),
                metrics: m,
                ..Default::default()
            }
        };
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-07".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "test".into(),
            cores: 32,
            results: vec![
                mk("zoomie-lgz", 900.0, 400.0, 2.8),
                mk("gzip", 500.0, 90.0, 2.8),
                mk("zoomie-lbzip2", 700.0, 120.0, 3.5),
                mk("bzip2", 300.0, 20.0, 3.5),
            ],
            tests: vec![],
        }
    }

    /// GROUPED PAIRING: `grouped` emits ONE sub-table per format, each pairing our
    /// codec against its direct rival — 4 rows in 2 groups — not one flat 4-way
    /// table. `drop=` strips the format-level columns from a decompressor mashup.
    #[test]
    fn mashup_grouped_pairs_each_codec_with_its_rival() {
        let r = codec_run();
        let c = ctx(Path::new("/tmp"), Some(&r));
        let mut args = HashMap::new();
        args.insert("self".to_string(), "zoomie".to_string());
        args.insert("grouped".to_string(), "true".to_string());
        args.insert("drop".to_string(), "compress_mbs,ratio".to_string());
        let out = render_mashup(&c, &args).unwrap();

        // Two per-format group headers.
        assert!(out.contains("**gzip**"), "missing gzip group header: {out}");
        assert!(
            out.contains("**bzip2**"),
            "missing bzip2 group header: {out}"
        );
        // Every codec + rival row present.
        for row in ["zoomie-lgz", "gzip", "zoomie-lbzip2", "bzip2"] {
            assert!(out.contains(row), "missing row {row}: {out}");
        }
        // The gzip group header precedes its rows and the bzip2 group.
        let gz = out.find("**gzip**").unwrap();
        let bz = out.find("**bzip2**").unwrap();
        assert!(gz < bz, "gzip group must precede bzip2 group: {out}");
        // `drop=` stripped the format-level columns; the decode metric survives.
        // Match the column-HEADER form (`| compress_mbs |`) so the check isn't
        // fooled by `decompress_mbs`, which contains `compress_mbs` as a substring.
        assert!(
            out.contains("decompress_mbs"),
            "decode column dropped: {out}"
        );
        assert!(
            !out.contains("| compress_mbs |"),
            "compress_mbs column not dropped: {out}"
        );
        assert!(
            !out.contains("| ratio |"),
            "ratio column not dropped: {out}"
        );
        // Our codec wins the decode column in each group → bolded.
        assert!(
            out.contains("**900**"),
            "gzip-group winner not bolded: {out}"
        );
        assert!(
            out.contains("**700**"),
            "bzip2-group winner not bolded: {out}"
        );
        // The run-provenance header appears exactly once (shared across groups).
        assert_eq!(
            out.matches("32 cores").count(),
            1,
            "header repeated per group: {out}"
        );
    }

    /// A codec run carrying a multi-core base row (`zoomies-lgz`), its
    /// single-thread `_st` variant (`zoomies-lgz_st`), and the format rival
    /// (`gzip`) — the znippy-zoomies "lens B" single-core-vs-multi-core shape.
    fn variant_run() -> BenchRun {
        let mk = |name: &str, decode: f64| {
            let mut m: Map<String, Value> = Map::new();
            m.insert("decompress_mbs".into(), Value::from(decode));
            nornir_bench::BenchResult {
                name: name.into(),
                metrics: m,
                ..Default::default()
            }
        };
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-08".into(),
            timestamp: None,
            version: "0.1.0".into(),
            machine: "test".into(),
            cores: 32,
            results: vec![
                mk("zoomies-lgz", 900.0),    // multi-core base
                mk("zoomies-lgz_st", 250.0), // single-thread variant
                mk("gzip", 500.0),           // format rival
            ],
            tests: vec![],
        }
    }

    /// VARIANT DIMENSION: `variant=st` keeps a single-thread (`_st`) bench a
    /// DISTINCT mashup row from its multi-core base, and (with `pairing=grouped`)
    /// both land as two rows under the SAME format group — the single-core and
    /// multi-core stories side by side vs the rival. Off by default the `_st`
    /// row collapses into its base system (one row).
    #[test]
    fn mashup_variant_keeps_st_as_distinct_grouped_row() {
        let r = variant_run();
        let c = ctx(Path::new("/tmp"), Some(&r));

        // OPT-IN: variant=st + grouped → base and `_st` are two distinct rows.
        let mut args = HashMap::new();
        args.insert("self".to_string(), "zoomies".to_string());
        args.insert("pairing".to_string(), "grouped".to_string());
        args.insert("variant".to_string(), "st".to_string());
        let out = render_mashup(&c, &args).unwrap();
        // One `gzip` format group holding BOTH of our variants + the rival.
        assert!(out.contains("**gzip**"), "missing gzip group header: {out}");
        assert_eq!(
            out.matches("**gzip**").count(),
            1,
            "variants must share ONE group: {out}"
        );
        for row in ["zoomies-lgz_st", "zoomies-lgz", "gzip"] {
            assert!(out.contains(row), "missing row {row}: {out}");
        }
        // Two DISTINCT nornir rows: the base appears as a row label AND the `_st`
        // variant appears as its own row label (a leading `| zoomies-lgz… |`).
        assert!(
            out.contains("| zoomies-lgz |"),
            "base row not rendered distinctly: {out}"
        );
        assert!(
            out.contains("| zoomies-lgz_st |"),
            "`_st` variant row not rendered distinctly: {out}"
        );

        // DEFAULT (no `variant=`): the `_st` row collapses into its base — a
        // single nornir row, no distinct `_st` row.
        let mut base_args = HashMap::new();
        base_args.insert("self".to_string(), "zoomies".to_string());
        base_args.insert("pairing".to_string(), "grouped".to_string());
        let base_out = render_mashup(&c, &base_args).unwrap();
        assert!(
            !base_out.contains("| zoomies-lgz_st |"),
            "without variant= the `_st` row must collapse, not render distinctly: {base_out}"
        );
    }

    /// The mashup's VARIANT `_st` notion is literally the core-saturation gate's:
    /// both route through the ONE shared helper in `nornir_bench`, so a name the
    /// mashup keeps distinct is exactly the one the gate exempts — they cannot
    /// drift apart.
    #[test]
    fn st_suffix_notion_is_shared_with_the_gate() {
        assert!(nornir_bench::is_single_thread("zoomies-lgz_st"));
        assert!(!nornir_bench::is_single_thread("zoomies-lgz"));
        assert_eq!(
            nornir_bench::strip_single_thread("zoomies-lgz_st"),
            "zoomies-lgz"
        );
        // Variant-aware token: distinct only when opted in.
        assert_eq!(
            system_token_variant("zoomies-lgz_st", true),
            "zoomies-lgz_st"
        );
        assert_eq!(system_token_variant("zoomies-lgz_st", false), "zoomies-lgz");
        assert_eq!(system_token_variant("zoomies-lgz", true), "zoomies-lgz");
    }

    /// Without `grouped`, the same run renders the original flat row-wise table
    /// (one table, no per-format sub-headers) — grouped pairing is opt-in.
    #[test]
    fn mashup_without_grouped_stays_flat() {
        let r = codec_run();
        let c = ctx(Path::new("/tmp"), Some(&r));
        let mut args = HashMap::new();
        args.insert("self".to_string(), "zoomie".to_string());
        let out = render_mashup(&c, &args).unwrap();
        // A single workload table: one header row, all four systems as rows.
        assert_eq!(
            out.matches("| workload |").count(),
            1,
            "expected one flat table: {out}"
        );
    }

    /// Rows-are-systems shape (the skade-katalog case): `winner=row` must bold
    /// the best cell *down each column*, not the smallest percentile per row.
    fn systems_run() -> BenchRun {
        let mk = |name: &str, ops: f64, p50: f64, p99: f64| {
            let mut m: Map<String, Value> = Map::new();
            m.insert("ops_sec".into(), Value::from(ops));
            m.insert("p50_us".into(), Value::from(p50));
            m.insert("p99_us".into(), Value::from(p99));
            nornir_bench::BenchResult {
                name: name.into(),
                metrics: m,
                ..Default::default()
            }
        };
        BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-06-08".into(),
            timestamp: None,
            version: "0.4.0".into(),
            machine: "oden".into(),
            cores: 32,
            results: vec![
                mk("nessie_table_exists", 5270.0, 156.51, 882.0),
                mk("nornir_embedded_table_exists", 2345144.0, 0.30, 0.40),
                mk("polaris_table_exists", 3282.0, 291.91, 457.0),
            ],
            tests: vec![],
        }
    }

    #[test]
    fn benches_winner_by_row_bolds_best_system_per_column() {
        let r = systems_run();
        let c = ctx(Path::new("/tmp"), Some(&r));
        let mut args = HashMap::new();
        args.insert("winner".to_string(), "row".to_string());
        let out = render_benches(&c, &args).unwrap();
        // nornir_embedded wins every column: highest ops/sec, lowest p50 + p99.
        // The ops/sec column is forced to a uniform M with enough decimals for the
        // smallest also-ran (polaris 0.00328M) to keep its digits, so the leader
        // renders at that same precision (2.34514M) rather than a lone "2.35M".
        assert!(
            out.contains("**2.34514M**"),
            "ops/sec winner not bolded: {out}"
        );
        assert!(
            out.contains("**0.3**") || out.contains("**0.30**"),
            "p50 winner not bolded: {out}"
        );
        assert!(
            out.contains("**0.4**") || out.contains("**0.40**"),
            "p99 winner not bolded: {out}"
        );
        // The losers' percentiles must NOT be bolded (the old bug bolded p50 per row).
        assert!(
            !out.contains("**156.51**"),
            "nessie p50 wrongly bolded: {out}"
        );
        assert!(
            !out.contains("**291.91**"),
            "polaris p50 wrongly bolded: {out}"
        );
    }

    /// Winner-tie must favour OURS (the znippy-zoomies bug): when ours ties a rival
    /// for the best value in a column, `self=` makes ours win the bold — and a
    /// single `self=` token claims its whole `-`-family (both `zoomies-*` rows).
    #[test]
    fn benches_winner_tie_favours_ours() {
        // compress_mbs: zoomies-lgz, pigz, gzip all tie at 256.39 (higher-better).
        // ratio: zoomies-lbz2, bzip2 tie at 7.50 (higher-better).
        let mk = |name: &str, compress: f64, ratio: f64| {
            let mut m: Map<String, Value> = Map::new();
            m.insert("compress_mbs".into(), Value::from(compress));
            m.insert("ratio".into(), Value::from(ratio));
            nornir_bench::BenchResult {
                name: name.into(),
                metrics: m,
                ..Default::default()
            }
        };
        let run = BenchRun {
            id: Default::default(),
            machine_facts: None,
            date: "2026-07-04".into(),
            timestamp: None,
            version: "0.1.15".into(),
            machine: "ryzen".into(),
            cores: 12,
            results: vec![
                mk("zoomies-lbz2", 22.84, 7.50),
                mk("zoomies-lgz", 256.39, 4.64),
                mk("pigz", 256.39, 4.64),
                mk("gzip", 256.39, 4.64),
                mk("bzip2", 22.84, 7.50),
            ],
            tests: vec![],
        };
        let c = ctx(Path::new("/tmp"), Some(&run));
        // With self= pinning zoomies-lbz2, BOTH zoomies rows count as ours.
        let mut args = HashMap::new();
        args.insert("winner".to_string(), "row".to_string());
        args.insert("self".to_string(), "zoomies-lbz2".to_string());
        args.insert(
            "best".to_string(),
            "ratio:high,compress_mbs:high".to_string(),
        );
        let out = render_benches(&c, &args).unwrap();
        // Ours wins each tie: exactly one bold per column, on a zoomies row.
        assert_eq!(
            out.matches("**256.39**").count(),
            1,
            "compress_mbs bold count: {out}"
        );
        assert_eq!(
            out.matches("**7.5**").count() + out.matches("**7.50**").count(),
            1,
            "ratio bold count: {out}"
        );
        let lgz = out
            .lines()
            .find(|l| l.starts_with("| zoomies-lgz |"))
            .unwrap();
        assert!(
            lgz.contains("**256.39**"),
            "zoomies-lgz should win compress_mbs tie: {out}"
        );
        let lbz2 = out
            .lines()
            .find(|l| l.starts_with("| zoomies-lbz2 |"))
            .unwrap();
        assert!(
            lbz2.contains("**7.5**") || lbz2.contains("**7.50**"),
            "zoomies-lbz2 should win ratio tie: {out}"
        );
        // The tied rivals must NOT steal the bold.
        let gzip = out.lines().find(|l| l.starts_with("| gzip |")).unwrap();
        assert!(
            !gzip.contains("**256.39**"),
            "gzip wrongly bolded (old bug): {out}"
        );
        let bzip2 = out.lines().find(|l| l.starts_with("| bzip2 |")).unwrap();
        assert!(
            !bzip2.contains("**7.5**") && !bzip2.contains("**7.50**"),
            "bzip2 wrongly bolded: {out}"
        );
    }

    /// K2 inject-assert: `mode=compact` must collapse the three rivals to a
    /// SINGLE synthetic best-of row whose every cell is the absurd-best value per
    /// column (max ops/sec, min p50/p99), drawn from whichever rival held it.
    #[test]
    fn benches_compact_mode_takes_best_per_column() {
        let r = systems_run(); // nessie / nornir_embedded / polaris
        let c = ctx(Path::new("/tmp"), Some(&r));
        let mut args = HashMap::new();
        args.insert("mode".to_string(), "compact".to_string());

The file goes on; the console shows all of it.