use crate::ops::health::HEALTH_INCLUDE_KEYS;
pub const EXTRA_VERDICT_AXES: &[&str] = &["projection", "mounts"];
pub fn verdict_axes() -> Vec<&'static str> {
let mut axes: Vec<&'static str> = HEALTH_INCLUDE_KEYS.to_vec();
axes.extend_from_slice(EXTRA_VERDICT_AXES);
axes
}
#[derive(Debug, Clone, Copy)]
pub struct AxisCoverage {
pub examined: &'static [&'static str],
pub excluded: &'static [(&'static str, &'static str)],
}
#[derive(Debug, Clone, Copy)]
pub enum CoverageDisposition {
Verdict(AxisCoverage),
NoVerdict(&'static str),
}
#[derive(Debug, Clone, Copy)]
pub struct SurfaceCoverage {
pub surface: &'static str,
pub disposition: CoverageDisposition,
}
impl AxisCoverage {
pub fn examined_wire(&self) -> Vec<&'static str> {
self.examined.to_vec()
}
pub fn excluded_wire(&self) -> Vec<(&'static str, &'static str)> {
self.excluded.to_vec()
}
pub fn wire_line(&self) -> String {
let not_examined: Vec<&str> = self.excluded.iter().map(|(a, _)| *a).collect();
format!(
"examined={}; not_examined={}",
self.examined.join(","),
not_examined.join(",")
)
}
}
impl SurfaceCoverage {
pub fn axis_coverage(&self) -> Option<&AxisCoverage> {
match &self.disposition {
CoverageDisposition::Verdict(c) => Some(c),
CoverageDisposition::NoVerdict(_) => None,
}
}
}
pub const HEALTH_COVERAGE: AxisCoverage = AxisCoverage {
examined: &[
"dangling_links",
"missing_required_outgoing",
"constraints",
"signals",
"integrity",
"config",
"mounts",
],
excluded: &[
(
"orphans",
"descriptive list; the defect verdict polices orphan stubs through the integrity findings",
),
(
"stubs",
"descriptive list; the defect verdict polices orphan stubs through the integrity findings",
),
(
"most_connected",
"descriptive ranking with no pass/fail semantics",
),
(
"missing_fields",
"advisory count, never part of the defect verdict",
),
(
"stale",
"advisory freshness, never part of the defect verdict",
),
(
"tags",
"descriptive distribution with no pass/fail semantics",
),
(
"labelling",
"advisory audit, never part of the defect verdict",
),
(
"conformance",
"reported per entity beside the verdict, never folded into it",
),
(
"anchors",
"drifted anchors stay advisory; the verify surfaces carry the drift statement",
),
("friction", "descriptive ledger counts"),
("open_questions", "descriptive listing of open questions"),
(
"stale_derivations",
"advisory freshness of derived artifacts",
),
(
"checks",
"check states are derived views; the verdicts in them belong to their recording callers",
),
("ledger", "descriptive view of the check ledger"),
(
"projection",
"projection fidelity is answered by status and projection verify",
),
],
};
pub const OVERVIEW_COVERAGE: AxisCoverage = AxisCoverage {
examined: &["mounts", "config"],
excluded: &[
("orphans", OVERVIEW_SCOPE),
("stubs", OVERVIEW_SCOPE),
("most_connected", OVERVIEW_SCOPE),
("missing_fields", OVERVIEW_SCOPE),
("stale", OVERVIEW_SCOPE),
(
"dangling_links",
"rendered on request as a listing; the verdict over them is health's",
),
("tags", OVERVIEW_SCOPE),
("missing_required_outgoing", OVERVIEW_SCOPE),
("constraints", OVERVIEW_SCOPE),
("signals", OVERVIEW_SCOPE),
("labelling", OVERVIEW_SCOPE),
("conformance", OVERVIEW_SCOPE),
("integrity", OVERVIEW_SCOPE),
("anchors", OVERVIEW_SCOPE),
("friction", OVERVIEW_SCOPE),
("open_questions", OVERVIEW_SCOPE),
("stale_derivations", OVERVIEW_SCOPE),
("checks", OVERVIEW_SCOPE),
("ledger", OVERVIEW_SCOPE),
("projection", OVERVIEW_SCOPE),
],
};
const OVERVIEW_SCOPE: &str = "overview is a descriptive composition; its only \
all-clear claim is that the roster it renders is complete and its mounts serve";
pub fn validate_coverage(
vocab: &[&str],
registry: &[SurfaceCoverage],
discovered: &[&str],
) -> Vec<String> {
let mut findings = Vec::new();
for d in discovered {
if !registry.iter().any(|r| r.surface == *d) {
findings.push(format!(
"surface `{d}` is discoverable and has no coverage declaration: \
declare its verdict axes, or declare why it emits no verdict"
));
}
}
let mut seen: Vec<&str> = Vec::new();
for row in registry {
if seen.contains(&row.surface) {
findings.push(format!(
"surface `{}` is declared more than once",
row.surface
));
continue;
}
seen.push(row.surface);
if !discovered.contains(&row.surface) {
findings.push(format!(
"declared surface `{}` is not discoverable: a stale declaration \
reads as coverage, remove it or fix the walk",
row.surface
));
}
match row.disposition {
CoverageDisposition::NoVerdict(reason) => {
if reason.trim().is_empty() {
findings.push(format!(
"surface `{}` declares no verdict without a reason",
row.surface
));
}
}
CoverageDisposition::Verdict(cov) => {
for axis in cov.examined {
if !vocab.contains(axis) {
findings.push(format!(
"surface `{}` examines axis `{axis}`, which the \
vocabulary does not carry",
row.surface
));
}
if cov.excluded.iter().any(|(a, _)| a == axis) {
findings.push(format!(
"surface `{}` both examines and excludes axis `{axis}`",
row.surface
));
}
}
for (axis, reason) in cov.excluded {
if !vocab.contains(axis) {
findings.push(format!(
"surface `{}` excludes axis `{axis}`, which the \
vocabulary does not carry",
row.surface
));
}
if reason.trim().is_empty() {
findings.push(format!(
"surface `{}` excludes axis `{axis}` without a reason",
row.surface
));
}
}
for axis in vocab {
let examined = cov.examined.contains(axis);
let excluded = cov.excluded.iter().any(|(a, _)| a == axis);
if !examined && !excluded {
findings.push(format!(
"surface `{}` declares nothing for axis `{axis}`: \
its clean verdict would cover the axis by omission, \
examine it or exclude it with a reason",
row.surface
));
}
}
}
}
}
findings
}
#[cfg(test)]
mod tests {
use super::*;
const VOCAB: &[&str] = &["anchors", "mounts"];
fn full() -> SurfaceCoverage {
SurfaceCoverage {
surface: "verify",
disposition: CoverageDisposition::Verdict(AxisCoverage {
examined: &["anchors"],
excluded: &[("mounts", "the roster surface answers for mounts")],
}),
}
}
fn ledger() -> SurfaceCoverage {
SurfaceCoverage {
surface: "check",
disposition: CoverageDisposition::NoVerdict(
"records the caller's verdict about the caller's own work",
),
}
}
#[test]
fn complete_registry_is_clean() {
let findings = validate_coverage(VOCAB, &[full(), ledger()], &["verify", "check"]);
assert!(findings.is_empty(), "{findings:?}");
}
#[test]
fn clean_over_an_unexamined_axis_fails() {
let silent = SurfaceCoverage {
surface: "verify",
disposition: CoverageDisposition::Verdict(AxisCoverage {
examined: &["anchors"],
excluded: &[],
}),
};
let findings = validate_coverage(VOCAB, &[silent, ledger()], &["verify", "check"]);
assert!(
findings.iter().any(|f| f.contains("`verify`")
&& f.contains("`mounts`")
&& f.contains("by omission")),
"{findings:?}"
);
}
#[test]
fn axis_added_without_declaration_update_fails() {
let grown: &[&str] = &["anchors", "mounts", "fences"];
let findings = validate_coverage(grown, &[full(), ledger()], &["verify", "check"]);
assert!(
findings
.iter()
.any(|f| f.contains("`verify`") && f.contains("`fences`")),
"{findings:?}"
);
}
#[test]
fn undeclared_surface_fails() {
let findings = validate_coverage(VOCAB, &[full(), ledger()], &["verify", "check", "dump"]);
assert!(
findings
.iter()
.any(|f| f.contains("`dump`") && f.contains("no coverage declaration")),
"{findings:?}"
);
}
#[test]
fn stale_surface_declaration_fails() {
let findings = validate_coverage(VOCAB, &[full(), ledger()], &["check"]);
assert!(
findings
.iter()
.any(|f| f.contains("`verify`") && f.contains("not discoverable")),
"{findings:?}"
);
}
#[test]
fn stale_axis_in_declaration_fails() {
let shrunk: &[&str] = &["anchors"];
let findings = validate_coverage(shrunk, &[full(), ledger()], &["verify", "check"]);
assert!(
findings
.iter()
.any(|f| f.contains("`mounts`") && f.contains("does not carry")),
"{findings:?}"
);
}
#[test]
fn exclusion_without_reason_fails() {
let bare = SurfaceCoverage {
surface: "verify",
disposition: CoverageDisposition::Verdict(AxisCoverage {
examined: &["anchors"],
excluded: &[("mounts", " ")],
}),
};
let findings = validate_coverage(VOCAB, &[bare, ledger()], &["verify", "check"]);
assert!(
findings.iter().any(|f| f.contains("without a reason")),
"{findings:?}"
);
}
#[test]
fn examined_and_excluded_fails() {
let both = SurfaceCoverage {
surface: "verify",
disposition: CoverageDisposition::Verdict(AxisCoverage {
examined: &["anchors", "mounts"],
excluded: &[("mounts", "also excluded")],
}),
};
let findings = validate_coverage(VOCAB, &[both, ledger()], &["verify", "check"]);
assert!(
findings
.iter()
.any(|f| f.contains("both examines and excludes")),
"{findings:?}"
);
}
#[test]
fn duplicate_declaration_fails() {
let findings = validate_coverage(VOCAB, &[full(), full(), ledger()], &["verify", "check"]);
assert!(
findings
.iter()
.any(|f| f.contains("declared more than once")),
"{findings:?}"
);
}
#[test]
fn vocabulary_composes_health_roster() {
let axes = verdict_axes();
for key in HEALTH_INCLUDE_KEYS {
assert!(axes.contains(key), "health include `{key}` missing");
}
for key in EXTRA_VERDICT_AXES {
assert!(axes.contains(key), "extra axis `{key}` missing");
}
assert_eq!(
axes.len(),
HEALTH_INCLUDE_KEYS.len() + EXTRA_VERDICT_AXES.len()
);
}
}