use anyhow::Context;
use varve_core::Store;
struct DocsRow {
format: String,
entry: Option<String>,
title: Option<String>,
documents: Option<String>,
}
fn realm_width(rows: &[Row]) -> Option<usize> {
let mut seen: std::collections::BTreeSet<&str> = std::collections::BTreeSet::new();
for r in rows {
seen.insert(r.realm.as_str());
}
if seen.len() < 2 {
return None;
}
Some(
seen.iter()
.map(|r| r.chars().count())
.chain(std::iter::once("REALM".len()))
.max()
.unwrap_or(5),
)
}
fn platform_cell(r: &Row) -> String {
match &r.target {
Some(t) => format!("{} -> {t}", r.platform),
None => r.platform.clone(),
}
}
struct Row {
name: String,
version: Option<String>,
kind: String,
known_kind: bool,
platform: String,
target: Option<String>,
digest: String,
dispatch: &'static str,
docs: Option<DocsRow>,
ingest_proof: String,
proof_signer: Option<String>,
present: bool,
layer: String,
realm: String,
}
const DISPATCHED: &str = "dispatched";
const HELD: &str = "held";
const UNKNOWN: &str = "unknown";
pub fn run(store: &Store, layer: Option<&str>, json: bool) -> anyhow::Result<()> {
let target = crate::export_target(store, layer)?;
let layers = crate::composition_for_export(&target)?;
let host = varve_core::host_platform();
let mut rows = Vec::new();
for l in &layers {
let payload = std::fs::read(l.entry.root.join("layer.json")).with_context(|| {
format!(
"cannot read the signed manifest of layer {} — the store entry is incomplete",
l.entry.layer
)
})?;
let manifest = varve_core::LayerManifest::parse(&payload)?;
for e in &manifest.entries {
let parsed = e.kind();
let kind = match &parsed {
Ok(k) => k.as_str().to_string(),
Err(varve_core::UnknownKind(raw)) => raw.clone(),
};
if parsed == Ok(varve_core::PayloadKind::Layer) {
continue;
}
let name = e
.annotations
.get("eu.pulseengine.tool")
.cloned()
.unwrap_or_else(|| "(unnamed entry)".to_string());
rows.push(Row {
version: e.annotations.get("eu.pulseengine.tool.version").cloned(),
kind,
known_kind: parsed.is_ok(),
target: e.annotations.get(varve_core::platform::ANN_TARGET).cloned(),
platform: e
.annotations
.get(varve_core::platform::ANN_PLATFORM)
.cloned()
.unwrap_or_else(|| "any".to_string()),
digest: e.digest.clone(),
dispatch: match parsed {
Ok(k) if k.is_dispatchable() => DISPATCHED,
Ok(_) => HELD,
Err(_) => UNKNOWN,
},
ingest_proof: match e.ingest_proof() {
Ok(p) => varve_core::IngestProof::label(p).to_string(),
Err(varve_core::UnknownProof(raw)) => raw,
},
proof_signer: e.annotations.get(varve_core::ANN_PROOF_SIGNER).cloned(),
docs: e
.annotations
.get(varve_core::deposit::ANN_DOCS_FORMAT)
.map(|format| DocsRow {
format: format.clone(),
entry: e
.annotations
.get(varve_core::deposit::ANN_DOCS_ENTRY)
.cloned(),
title: e
.annotations
.get(varve_core::deposit::ANN_DOCS_TITLE)
.cloned(),
documents: e
.annotations
.get(varve_core::deposit::ANN_DOCS_DOCUMENTS)
.cloned(),
}),
present: store_of(l).entry_path(&l.entry, e).is_some(),
layer: l.entry.layer.to_string(),
realm: l.realm.clone(),
name,
});
}
}
rows.sort_by(|a, b| {
(&a.layer, &a.kind, &a.name, &a.version, &a.platform).cmp(&(
&b.layer,
&b.kind,
&b.name,
&b.version,
&b.platform,
))
});
if json {
print_json(&target, &layers, &rows, &host);
} else {
print_text(&target, &layers, &rows, &host);
}
Ok(())
}
fn store_of(l: &varve_core::compose::ComposedLayer) -> &Store {
&l.store
}
fn print_json(
target: &crate::ExportTarget,
layers: &[varve_core::compose::ComposedLayer],
rows: &[Row],
host: &str,
) {
let composition: Vec<_> = layers
.iter()
.map(|l| {
serde_json::json!({
"layer": l.entry.layer.to_string(),
"manifest_digest": l.entry.digest,
"realm": l.realm,
"root": l.entry.digest == target.entry.digest,
})
})
.collect();
let payloads: Vec<_> = rows
.iter()
.map(|r| {
serde_json::json!({
"name": r.name,
"version": r.version,
"kind": r.kind,
"known_kind": r.known_kind,
"platform": r.platform,
"dispatch": r.dispatch,
"ingest_proof": r.ingest_proof,
"proof_signer": r.proof_signer,
"digest": r.digest,
"present": r.present,
"layer": r.layer,
"realm": r.realm,
"docs_format": r.docs.as_ref().map(|d| &d.format),
"docs_entry": r.docs.as_ref().and_then(|d| d.entry.as_ref()),
"docs_title": r.docs.as_ref().and_then(|d| d.title.as_ref()),
"docs_documents": r.docs.as_ref().and_then(|d| d.documents.as_ref()),
})
})
.collect();
let doc = serde_json::json!({
"command": "inspect",
"layer": target.entry.layer.to_string(),
"channel": target.entry.channel,
"realm": layers
.iter()
.find(|l| l.entry.digest == target.entry.digest)
.map(|l| l.realm.clone()),
"manifest_digest": target.entry.digest,
"host_platform": host,
"composition": composition,
"payloads": payloads,
"summary": {
"payloads": rows.len(),
"dispatched": rows.iter().filter(|r| r.dispatch == DISPATCHED).count(),
"held": rows.iter().filter(|r| r.dispatch == HELD).count(),
"layers": layers.len(),
"unverified": rows.iter().filter(|r| r.ingest_proof == "unverified").count(),
"unrecorded": rows.iter().filter(|r| r.ingest_proof == "unrecorded").count(),
},
});
println!(
"{}",
serde_json::to_string_pretty(&doc).expect("the inspect report serialises")
);
}
fn print_text(
target: &crate::ExportTarget,
layers: &[varve_core::compose::ComposedLayer],
rows: &[Row],
host: &str,
) {
let realm = layers
.iter()
.find(|l| l.entry.digest == target.entry.digest)
.map(|l| l.realm.as_str());
match realm {
Some(r) => println!(
"layer {} ({}) realm '{}' {}",
target.entry.layer, target.entry.channel, r, target.entry.digest
),
None => println!(
"layer {} ({}) {}",
target.entry.layer, target.entry.channel, target.entry.digest
),
}
if layers.len() > 1 {
println!("composition: {} layers —", layers.len());
for l in layers {
println!(
" {} {} (verified against realm '{}'){}",
l.entry.layer,
l.entry.digest,
l.realm,
if l.entry.digest == target.entry.digest {
" [pinned]"
} else {
""
}
);
}
}
if rows.is_empty() {
println!("\nno payloads — this layer carries no entries beyond its composition");
return;
}
let dispatched = rows.iter().filter(|r| r.dispatch == DISPATCHED).count();
let held = rows.len() - dispatched;
println!(
"\n{} payload(s): {dispatched} DISPATCHED, {held} HELD (platform {host})\n",
rows.len()
);
let w = |f: fn(&Row) -> &str, head: &str| {
rows.iter()
.map(|r| f(r).chars().count())
.chain(std::iter::once(head.chars().count()))
.max()
.unwrap_or(1)
};
let (wn, wk, wp) = (w(|r| &r.name, "NAME"), w(|r| &r.kind, "KIND"), {
rows.iter()
.map(|r| platform_cell(r).chars().count())
.chain(std::iter::once(8))
.max()
.unwrap_or(8)
});
let wv = rows
.iter()
.map(|r| r.version.as_deref().unwrap_or("-").chars().count())
.chain(std::iter::once(7))
.max()
.unwrap_or(7);
let wr = realm_width(rows);
let realms = wr.map(|w| (w, "REALM")).unwrap_or((0, ""));
println!(
" {:<12}{:<wk$} {:<wn$} {:<wv$} {:<wp$} {:<rw$}{}LAYER",
"",
"KIND",
"NAME",
"VERSION",
"PLATFORM",
realms.1,
if wr.is_some() { " " } else { "" },
rw = realms.0
);
for r in rows {
println!(
" {:<12}{:<wk$} {:<wn$} {:<wv$} {:<wp$} {:<rw$}{}{}{}",
r.dispatch.to_uppercase(),
r.kind,
r.name,
r.version.as_deref().unwrap_or("-"),
platform_cell(r),
if wr.is_some() { r.realm.as_str() } else { "" },
if wr.is_some() { " " } else { "" },
r.layer,
if r.present {
""
} else {
" (not laid down here)"
},
rw = realms.0,
);
}
if held > 0 {
println!(
"\nHELD payloads are stored and verified but NOT on your PATH — `varve which` will \
not find them, by design. Only a `tool` is dispatched by name. See \
`varve docs inspect`."
);
}
let docs: Vec<(&Row, &DocsRow)> = rows
.iter()
.filter_map(|r| r.docs.as_ref().map(|d| (r, d)))
.collect();
if !docs.is_empty() {
println!("\ndocumentation for the versions this layer pins:");
for (row, d) in &docs {
let label = d.title.as_deref().unwrap_or(&row.name);
println!(
" {label} {} ({})",
row.version.as_deref().unwrap_or("-"),
d.format
);
if let Some(entry) = &d.entry {
println!(" starts at {entry}");
}
if let Some(of) = &d.documents {
println!(" documents {of} (varve export-docs --for {of})");
}
}
match docs.as_slice() {
[(row, _)] => {
println!("\n read it, copying nothing: varve-serve");
println!(
" or write a copy: varve export-docs --out ./doc ({})",
row.name
);
}
many => {
println!(
"\n {} documents, so name one: varve-serve --select <NAME>",
many.len()
);
println!(
" or: varve export-docs --out ./doc --select <NAME>"
);
}
}
}
if rows.iter().any(|r| !r.known_kind) {
println!(
"\nAn entry above carries a payload kind this varve does not know. Its bytes still \
verify against the signed digest — only the adapters that must DO something \
kind-specific will refuse it. A newer varve may handle it."
);
}
}
#[cfg(test)]
mod tests {
use super::*;
fn row(name: &str, docs: Option<DocsRow>) -> Row {
Row {
name: name.into(),
version: Some("1.0.0".into()),
kind: if docs.is_some() {
"docs".into()
} else {
"tool".into()
},
known_kind: true,
platform: "any".into(),
digest: "sha256:0".into(),
dispatch: if docs.is_some() { HELD } else { DISPATCHED },
docs,
ingest_proof: "cosign-sums".into(),
proof_signer: None,
present: true,
layer: "2026.09.9".into(),
realm: "t".into(),
target: None,
}
}
#[test]
fn a_cross_toolchain_reports_the_pair_that_identifies_it() {
let sdk = |target: &str| {
let mut r = row("zephyr-sdk", None);
r.platform = "x86_64-unknown-linux-gnu".into();
r.target = Some(target.into());
r
};
let rows = [
sdk("arm-zephyr-eabi"),
sdk("riscv64-zephyr-elf"),
row("rivet", None),
];
let cells: Vec<String> = rows.iter().map(platform_cell).collect();
assert_eq!(
cells,
vec![
"x86_64-unknown-linux-gnu -> arm-zephyr-eabi",
"x86_64-unknown-linux-gnu -> riscv64-zephyr-elf",
"any",
]
);
assert_ne!(
cells[0], cells[1],
"two toolchains a realm installs side by side must be \
distinguishable in the one place that reports what a layer holds"
);
}
#[test]
fn both_renderings_report_the_same_documents() {
let rows = [
row("rivet", None),
row(
"handbook",
Some(DocsRow {
format: "pdf".into(),
entry: None,
title: Some("The handbook".into()),
documents: None,
}),
),
];
let in_text: Vec<&str> = rows
.iter()
.filter(|r| r.docs.is_some())
.map(|r| r.name.as_str())
.collect();
let in_json: Vec<&str> = rows
.iter()
.filter(|r| r.docs.as_ref().map(|d| !d.format.is_empty()) == Some(true))
.map(|r| r.name.as_str())
.collect();
assert_eq!(in_text, in_json, "the two renderings disagree");
assert_eq!(in_text, vec!["handbook"]);
}
#[test]
fn the_realm_is_shown_when_a_composition_spans_more_than_one() {
let mut a = row("rivet", None);
a.realm = "pulseengine".into();
let mut b = row("wit-bindgen-wrpc", None);
b.realm = "ulinc".into();
let w = realm_width(&[a, b]).expect("a multi-realm composition needs the column");
assert!(
w >= "pulseengine".len(),
"the column truncates the realm name: {w}"
);
}
#[test]
fn a_single_realm_layer_gets_no_realm_column() {
let a = row("rivet", None);
let b = row("spar", None);
assert_eq!(realm_width(&[a, b]), None);
}
#[test]
fn the_column_is_never_narrower_than_its_heading() {
let mut a = row("rivet", None);
a.realm = "ul".into();
let mut b = row("spar", None);
b.realm = "pe".into();
assert_eq!(realm_width(&[a, b]), Some("REALM".len()));
}
#[test]
fn two_realms_shipping_one_name_are_distinguishable() {
let mut a = row("wasm-tools", None);
a.realm = "pulseengine".into();
a.layer = "2026.09.5".into();
let mut b = row("wasm-tools", None);
b.realm = "pulseengine-wasm".into();
b.layer = "2026.09.5".into();
assert_eq!(a.name, b.name);
assert_eq!(a.version, b.version);
assert_eq!(
a.layer, b.layer,
"same id in two realms — only the realm separates them"
);
assert!(
realm_width(&[a, b]).is_some(),
"the one case where every other column is identical shows no realm"
);
}
#[test]
fn a_document_is_never_reported_as_dispatched() {
let d = row(
"handbook",
Some(DocsRow {
format: "html".into(),
entry: Some("index.html".into()),
title: None,
documents: None,
}),
);
assert_eq!(d.dispatch, HELD);
assert!(!varve_core::PayloadKind::Docs.is_dispatchable());
}
}