aprender-core 0.70.2

Next-generation machine learning library in pure Rust
//! The README's release-verification matrix, RENDERED from the ladder receipts.
//!
//! #3769, operator 2026-09-21 verbatim: *"ensure our post-release always updated
//! README.md and apr-cookbook with SHACL validated recipes"*.
//!
//! The matrix is data, not prose. Every cell comes from
//! `evidence/dogfood/models/<version>/<host>.json` — the receipts `scripts/model_ladder.sh`
//! writes and `scripts/check_model_ladder.sh` judges. Nothing here is typed by hand, because
//! a hand-maintained table is the leak the operator has ruled on twice: a claim nobody
//! re-derives drifts silently and then gets quoted. The same shape as
//! `docs/GPU-SUPPORT.md`, which is generated from `capability.rs` and gated the same way.
//!
//! ## The two guards, and why the second one is the one that matters
//!
//! `the_committed_readme_section_matches_the_receipts` proves the README equals the render.
//! On its own that is weak: a renderer that emitted a constant would satisfy it forever.
//!
//! `the_table_discriminates_rather_than_saying_yes_everywhere` is the anti-vacuity control.
//! It **mutates a receipt and requires the output to change**. A table that says the same
//! thing whatever the receipts say is not a report, and every "green that cannot go red" in
//! this repo's history has that shape.
//!
//! Asserting "some cell is red" would be the obvious anti-vacuity test and it is the WRONG
//! one: a clean release is legitimately all-green, so that assertion would fail for a good
//! reason and be deleted by whoever hit it. Mutation survives a perfect release.

use serde::Deserialize;

/// One model rung as the ladder receipt records it.
#[derive(Debug, Clone, Deserialize)]
pub struct Rung {
    /// Rung id, e.g. `qwen35-4b-q4km`.
    pub id: String,
    /// Whether this rung is required on this host.
    #[serde(default)]
    pub required: bool,
    /// Whether the model file was present on the host.
    #[serde(default)]
    pub present: bool,
    /// Whether every gate for this rung passed.
    #[serde(default)]
    pub green: bool,
}

/// One host's ladder receipt for one release.
#[derive(Debug, Clone, Deserialize)]
pub struct Receipt {
    /// Host the ladder ran on, e.g. `lambda`.
    pub host: String,
    /// Release version the receipt is for.
    pub version: String,
    /// The binary that ran, e.g. `apr 0.68.2 (5c04de82e)`.
    #[serde(default)]
    pub apr_version: String,
    /// Non-green rung count the receipt declares.
    #[serde(default)]
    pub red: u32,
    /// The rungs measured.
    #[serde(default)]
    pub rungs: Vec<Rung>,
}

/// Marker opening the generated block in `README.md`.
pub const BEGIN: &str =
    "<!-- RELEASE_MATRIX_START (generated by release_section.rs — do not edit) -->";
/// Marker closing the generated block in `README.md`.
pub const END: &str = "<!-- RELEASE_MATRIX_END -->";

/// Render the matrix for `receipts`, which must all be for the same version.
///
/// Rows are rungs, columns are hosts, so a rung that is green on one host and not on
/// another is visible as a disagreement rather than averaged away.
#[must_use]
pub fn render(receipts: &[Receipt]) -> String {
    let mut hosts: Vec<&Receipt> = receipts.iter().collect();
    hosts.sort_by(|a, b| a.host.cmp(&b.host));

    let mut out = String::new();
    out.push_str(BEGIN);
    out.push('\n');

    if hosts.is_empty() {
        out.push_str("\n_No ladder receipt for this release yet._\n\n");
        out.push_str(END);
        out.push('\n');
        return out;
    }

    let version = &hosts[0].version;
    out.push_str(&format!(
        "\nVerified matrix for **{version}**, from the ladder receipts:\n\n"
    ));
    // What a cell MEANS, stated in the output rather than left to the reader. The
    // ladder's `green` derives from `ran`/`fallback`/`escaped_special`, all from
    // `apr run` — it never reads the receipt's `verbs`. So `chat`, `code` and `serve`
    // are RECORDED in the receipt and not ENFORCED by it (d8 demonstrated a failed
    // serve probe on a row still marked green). A generated table is trusted more
    // than a hand-typed one, so an overclaim here is worse: say what was checked.
    out.push_str(
        "A `pass` cell means `apr run` completed on that host without falling back and \
         its golden output matched. It does **not** mean `chat`, `code` and `serve` \
         passed: the ladder records those verbs but its `green` does not read them.\n\n",
    );
    // A NON-pass cell names the gates the RECEIPT RECORDS, which is not always the cause.
    //
    // Deliberately not "…is not always `tensor_contract`". Naming one gate reproduces the
    // defect at n+1 the moment a different gate matters — which is why c7's producer-side
    // fix (faecacee4) records `gates`/`gates_failed`/`gates_reported` and names none, with
    // `gates_account_for_rc` as the invariant. That invariant is false for WHICHEVER cause
    // goes missing, not for one listed in advance.
    //
    // Measured instance: aprender-55 traced the `-st.apr` row to a corrupt file — 27
    // tensors failing data-quality, the same 27 on a Q4_K re-quantisation built to break
    // the naming-vs-precision confound, so the damage is in the source bytes. `apr qa`
    // computed that in the same process; the receipt kept the symptom (`gibberish
    // (fragment "NavController")`) and dropped the diagnosis.
    //
    // Stated in the rendered output for the same reason as the caveat above: a generated
    // table is trusted more than a hand-typed one, so publishing an incomplete reason from
    // one is worse. Remove when every receipt in the rendered set accounts for its rc.
    out.push_str(
        "A non-`pass` cell names the gates the receipt records, which is not always the \
         cause: a reason `apr qa` computed in the same run is not carried here unless the \
         receipt accounts for it (`qa_rc` is the tell).\n\n",
    );

    // Rung order: the union across hosts, first-seen order preserved so the table is
    // stable under receipt reordering.
    let mut ids: Vec<String> = Vec::new();
    for r in &hosts {
        for rung in &r.rungs {
            if !ids.contains(&rung.id) {
                ids.push(rung.id.clone());
            }
        }
    }

    out.push_str("| Model rung |");
    for h in &hosts {
        out.push_str(&format!(" {} |", h.host));
    }
    out.push_str("\n|---|");
    for _ in &hosts {
        out.push_str("---|");
    }
    out.push('\n');

    for id in &ids {
        out.push_str(&format!("| `{id}` |"));
        for h in &hosts {
            let cell = h.rungs.iter().find(|x| &x.id == id).map_or(" — |", |r| {
                if !r.present {
                    " absent |"
                } else if r.green {
                    " pass |"
                } else if r.required {
                    " **FAIL** |"
                } else {
                    " fail (optional) |"
                }
            });
            out.push_str(cell);
        }
        out.push('\n');
    }

    out.push('\n');
    for h in &hosts {
        let req = h.rungs.iter().filter(|r| r.required).count();
        out.push_str(&format!(
            "- **{}**: {} rung(s), {} required, {} not green — `{}`\n",
            h.host,
            h.rungs.len(),
            req,
            h.red,
            h.apr_version
        ));
    }

    out.push('\n');
    out.push_str(END);
    out.push('\n');
    out
}

#[cfg(test)]
mod release_section_doc {
    use super::{render, Receipt, BEGIN, END};

    fn repo_root() -> std::path::PathBuf {
        std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
            .canonicalize()
            .expect("repo root")
    }

    /// The version directories under `evidence/dogfood/models`, sorted.
    fn version_dirs(base: &std::path::Path) -> Vec<String> {
        let Ok(rd) = std::fs::read_dir(base) else {
            return Vec::new();
        };
        let mut v: Vec<String> = rd
            .filter_map(Result::ok)
            .filter(|e| e.path().is_dir())
            .map(|e| e.file_name().to_string_lossy().into_owned())
            .collect();
        v.sort();
        v
    }

    /// Every parseable receipt in one version directory.
    ///
    /// A `filter_map` chain rather than a nest. Cognitive complexity charges for
    /// DEPTH, not branch count: the original was six levels
    /// (`for` → `if let` → `for` → `if` → `if let` → `if let`) and scored cognitive
    /// 26 against cyclomatic 8 — the gap between those two numbers *is* the nesting.
    /// Flattening the same eight branches into chained combinators and a `let … else`
    /// costs the same work and almost no depth.
    ///
    /// Unreadable or unparseable files are skipped rather than failing the load: a
    /// receipt directory is written by `scripts/model_ladder.sh` on several hosts and
    /// a partial write must not make the whole version invisible. The *caller* decides
    /// what an empty result means, and `the_table_discriminates_…` asserts that an
    /// empty set renders as "no receipt" rather than as a pass.
    fn receipts_in(dir: &std::path::Path) -> Vec<Receipt> {
        let Ok(rd) = std::fs::read_dir(dir) else {
            return Vec::new();
        };
        rd.filter_map(Result::ok)
            .map(|e| e.path())
            .filter(|p| p.extension().is_some_and(|x| x == "json"))
            .filter_map(|p| std::fs::read_to_string(p).ok())
            .filter_map(|txt| serde_json::from_str::<Receipt>(&txt).ok())
            .collect()
    }

    /// Every `evidence/dogfood/models/<v>/*.json`, newest version that has any.
    fn load_newest() -> (String, Vec<Receipt>) {
        let base = repo_root().join("evidence/dogfood/models");
        version_dirs(&base)
            .iter()
            .rev()
            .map(|v| (v.clone(), receipts_in(&base.join(v))))
            .find(|(_, rs)| !rs.is_empty())
            .unwrap_or_default()
    }

    /// THE ANTI-VACUITY CONTROL. Written before the renderer, and the reason the
    /// byte-equality test below is worth anything.
    ///
    /// A renderer that ignored its input would satisfy "README == render()" forever. So:
    /// mutate a receipt and require the output to change. Three independent mutations,
    /// because one could be absorbed by a coincidence of formatting.
    ///
    /// Deliberately NOT "assert some cell is red": a clean release is legitimately
    /// all-green, that assertion would fail for a good reason, and the person who hit it
    /// would delete it.
    #[test]
    fn the_table_discriminates_rather_than_saying_yes_everywhere() {
        let (_v, receipts) = load_newest();
        assert!(
            !receipts.is_empty(),
            "no ladder receipts under evidence/dogfood/models — the matrix would be vacuous"
        );
        let base = render(&receipts);

        // 1. flipping one rung's `green` must change the table
        let mut m1 = receipts.clone();
        assert!(!m1[0].rungs.is_empty(), "receipt has no rungs to mutate");
        m1[0].rungs[0].green = !m1[0].rungs[0].green;
        assert_ne!(
            base,
            render(&m1),
            "flipping rung '{}' on host '{}' did not change the render — \
             the table is not reading `green`",
            m1[0].rungs[0].id,
            m1[0].host
        );

        // 2. dropping a host must change the table
        if receipts.len() > 1 {
            let m2 = receipts[1..].to_vec();
            assert_ne!(
                base,
                render(&m2),
                "dropping a host did not change the render"
            );
        }

        // 3. changing the declared not-green count must change the summary
        let mut m3 = receipts.clone();
        m3[0].red = m3[0].red.wrapping_add(1);
        assert_ne!(
            base,
            render(&m3),
            "changing a receipt's `red` count did not change the render"
        );

        // and the empty case must not silently render a plausible-looking table
        let empty = render(&[]);
        assert!(
            empty.contains("No ladder receipt"),
            "an empty receipt set must say so, not render an empty matrix that reads as a pass"
        );
    }

    #[test]
    fn the_committed_readme_section_matches_the_receipts() {
        let (_v, receipts) = load_newest();
        let rendered = render(&receipts);
        let path = repo_root().join("README.md");
        let readme = std::fs::read_to_string(&path).expect("read README.md");

        let Some(start) = readme.find(BEGIN) else {
            panic!(
                "README.md has no {BEGIN} marker. Add the block, then regenerate with \
                 APR_WRITE_RELEASE_MATRIX=1 cargo test -p aprender-core --lib release_section_doc"
            );
        };
        let end = readme[start..]
            .find(END)
            .map(|i| start + i + END.len())
            .expect("README.md has a START marker with no END marker");
        let committed = &readme[start..end];

        if std::env::var("APR_WRITE_RELEASE_MATRIX").is_ok() {
            let updated = format!(
                "{}{}{}",
                &readme[..start],
                rendered.trim_end(),
                &readme[end..]
            );
            std::fs::write(&path, updated).expect("write README.md");
            return;
        }
        assert_eq!(
            committed.trim_end(),
            rendered.trim_end(),
            "README.md's release matrix has drifted from the ladder receipts. Regenerate: \
             APR_WRITE_RELEASE_MATRIX=1 cargo test -p aprender-core --lib release_section_doc"
        );
    }
}