use std::path::PathBuf;
mod common;
use common::{Ran, Root};
impl Root {
fn publish(&self, name: &str) -> PathBuf {
let out = self.at.join("released").join(name);
let ran = self.run(&["taxonomy", "publish", "--out", out.to_str().expect("utf-8")]);
assert_eq!(ran.code, Some(0), "the artifact publishes: {ran:?}");
out
}
fn edit(&self, version: &str, edits: &[(&str, &str)]) {
let taxonomy = self.at.join("packages/headwater-standard/taxonomy.yml");
let mut text = std::fs::read_to_string(&taxonomy).expect("the taxonomy reads");
for (from, to) in edits {
assert!(text.contains(from), "the fixture still carries `{from}`");
text = text.replacen(from, to, 1);
}
assert!(text.contains("version: 1.0.0"), "the source is at 1.0.0");
std::fs::write(&taxonomy, text.replacen("version: 1.0.0", version, 1))
.expect("the taxonomy writes");
let manifest = self.at.join("packages/headwater-standard/package.yml");
let text = std::fs::read_to_string(&manifest).expect("the manifest reads");
assert!(text.contains("version: 1.0.0"), "the fixture is at 1.0.0");
std::fs::write(&manifest, text.replacen("version: 1.0.0", version, 1))
.expect("the manifest writes");
}
}
impl Ran {
fn dimension(&self, name: &str) -> String {
self.out
.lines()
.find_map(|line| line.trim_start().strip_prefix(name))
.map(|rest| rest.trim().to_string())
.unwrap_or_else(|| panic!("the report names `{name}`: {self:?}"))
}
fn states_no_contradiction(&self) -> &Ran {
assert!(
!self.out.contains("this run cannot settle it"),
"the lock of this case is honest, so nothing here contradicts itself: {self:?}"
);
self
}
}
#[test]
fn a_version_bump_alone_moves_no_dimension() {
let root = Root::new("version-bump-alone");
let first = root.publish("1.0.0");
root.edit(
"version: 1.1.0",
&[
(
"# The base package of headwater/standard, as a file.",
"# The base package of headwater/standard, as a file. Reworded.",
),
(
"intent: explain why a choice was made and what it forecloses",
"intent: explain the choice that was made and what it rules out",
),
],
);
let second = root.publish("1.1.0");
assert_ne!(
std::fs::read_to_string(first.join("taxonomy.yml")).expect("the first reads"),
std::fs::read_to_string(second.join("taxonomy.yml")).expect("the second reads"),
"the two artifacts differ, or this case compares one package with itself"
);
let ran = root.run(&[
"taxonomy",
"diff",
second.to_str().expect("utf-8"),
"--to",
"1.1.0",
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
assert!(
ran.out.contains("the base resolved to different text"),
"the taxonomy did move, and this case is about a diff that stays silent \
anyway: {ran:?}"
);
assert!(
ran.out
.contains("the previous side was read from a lock whose sources have moved"),
"{ran:?}"
);
assert!(
ran.out
.contains("moved packages/headwater-standard/taxonomy.yml"),
"the caveat names the file: {ran:?}"
);
for dimension in [
"classification",
"instance_validity",
"consequence",
"projection",
"identifier",
"addressability",
] {
assert_eq!(
ran.dimension(dimension),
"preserved",
"`{dimension}` moved on a change no document can see: {ran:?}"
);
}
assert!(
ran.out.contains("nothing here requires a major version"),
"{ran:?}"
);
}
#[test]
fn a_founding_the_previous_release_already_carried_is_not_a_break() {
let root = Root::founding("founding-carried");
let validated = root.run(&["taxonomy", "validate"]);
assert_eq!(validated.code, Some(0), "{validated:?}");
assert!(
validated
.out
.contains("operations that make what they address: 1"),
"the bundle order founds a key, or this case is about nothing: {validated:?}"
);
let first = root.publish("1.0.0");
root.edit("version: 1.1.0", &[]);
let second = root.publish("1.1.0");
assert_eq!(
std::fs::read_to_string(first.join("taxonomy.yml"))
.expect("the first reads")
.replacen("version: 1.0.0", "version: 1.1.0", 1),
std::fs::read_to_string(second.join("taxonomy.yml")).expect("the second reads"),
"nothing but the version moved between the two artifacts"
);
let ran = root.run(&[
"taxonomy",
"diff",
second.to_str().expect("utf-8"),
"--to",
"1.1.0",
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
assert_eq!(
ran.dimension("addressability"),
"preserved",
"a founding the release the lock names already carried is not a break this \
release introduced: {ran:?}"
);
assert!(
ran.out.contains("nothing here requires a major version"),
"{ran:?}"
);
}
#[test]
fn a_lock_whose_founding_record_was_stripped_says_it_cannot_settle_the_answer() {
let root = Root::founding("founding-stripped");
let artifact = root.publish("1.0.0");
let lock = root.at.join(".headwater/taxonomy.lock");
let text = std::fs::read_to_string(&lock).expect("the lock reads");
let start = text
.find("\nfounded:")
.expect("this root resolves with a founding, so its lock records one")
+ 1;
let end = text[start..]
.match_indices('\n')
.find(|(offset, _)| {
text[start + offset + 1..]
.chars()
.next()
.is_some_and(|first| !first.is_whitespace())
})
.map(|(offset, _)| start + offset + 1)
.unwrap_or(text.len());
let stripped = format!("{}{}", &text[..start], &text[end..]);
assert!(
!stripped.contains("\nfounded:"),
"the whole block goes, and not its first line"
);
assert!(
stripped.len() < text.len(),
"the strip removed something: {}",
text.len()
);
std::fs::write(&lock, stripped).expect("the lock writes");
let ran = root.run(&[
"taxonomy",
"diff",
artifact.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
assert!(
ran.out.contains("the base resolved to the same text"),
"the artifact is the one this lock was written from: {ran:?}"
);
assert!(
ran.dimension("addressability").starts_with("BROKEN"),
"the stripped block reads back as a founding this release introduced: {ran:?}"
);
assert!(
ran.out.contains("this run cannot settle it"),
"the report names its own contradiction: {ran:?}"
);
assert!(
ran.out.contains("`headwater taxonomy resolve` rewrites"),
"and names the one remedy it can name: {ran:?}"
);
assert!(
!ran.out.contains("whose sources have moved"),
"the sources are untouched: {ran:?}"
);
let resolved = root.run(&["taxonomy", "resolve"]);
assert_eq!(resolved.code, Some(0), "{resolved:?}");
let ran = root.run(&[
"taxonomy",
"diff",
artifact.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
assert_eq!(ran.dimension("addressability"), "preserved", "{ran:?}");
assert!(
ran.out.contains("nothing here requires a major version"),
"the release that changed nothing changed nothing: {ran:?}"
);
}
#[test]
fn a_declaration_that_breaks_a_document_names_that_document() {
let root = Root::new("breaks-a-document");
root.publish("1.0.0");
root.edit(
"version: 2.0.0",
&[
(
"facets: {require: [status, status_since, last_verified, summary]}",
"facets: {require: [status, status_since, last_verified, summary, owner]}",
),
(
" summary:\n role: scent",
" owner:\n type: string\n required: true\n volatility: mutable\n \
summary:\n role: scent",
),
],
);
let candidate = root.publish("2.0.0");
let ran = root.run(&[
"taxonomy",
"diff",
candidate.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "a measured break is a report: {ran:?}");
ran.states_no_contradiction();
assert!(
ran.dimension("instance_validity").starts_with("BROKEN"),
"{ran:?}"
);
assert!(
ran.dimension("consequence").starts_with("BROKEN"),
"{ran:?}"
);
assert!(
ran.out
.contains("facet.required.missing at docs/decisions/0001-the-warrant-a-person-set.md"),
"the report names the document that stopped validating: {ran:?}"
);
assert!(
ran.out.contains("requires the facet `owner`"),
"and what it now fails: {ran:?}"
);
assert!(
ran.out.contains("this change requires a major version"),
"spec 2: any dimension broken forces a major: {ran:?}"
);
assert_eq!(ran.dimension("classification"), "preserved", "{ran:?}");
assert_eq!(ran.dimension("identifier"), "preserved", "{ran:?}");
}
#[test]
fn an_overlay_address_the_new_base_takes_is_the_addressability_dimension() {
let root = Root::new("addressability");
root.publish("1.0.0");
root.edit(
"version: 2.0.0",
&[(
"identifier_schemes:\n decision_id:",
"identifier_schemes:\n spec_id: {pattern: \"SPEC-{namespace}-{slug}\", \
namespace: HW, allocation: reconcile-first}\n decision_id:",
)],
);
let candidate = root.publish("2.0.0");
let ran = root.run(&[
"taxonomy",
"diff",
candidate.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(
ran.code,
Some(1),
"a run that could not measure fails: {ran:?}"
);
ran.states_no_contradiction();
assert!(
ran.dimension("addressability").starts_with("BROKEN"),
"{ran:?}"
);
assert!(
ran.out
.contains("add.identifier_schemes.spec_id in .headwater/overlay.yml"),
"the report names the overlay operation and the file that carries it: {ran:?}"
);
for dimension in [
"classification",
"instance_validity",
"consequence",
"projection",
"identifier",
] {
assert!(
ran.dimension(dimension).starts_with("not measured"),
"`{dimension}` claims a reading out of a candidate that did not resolve: {ran:?}"
);
}
assert!(
ran.err
.contains("five of the six dimensions were not measured"),
"{ran:?}"
);
assert!(
ran.out
.contains("the base did not resolve, so there is no second text to compare"),
"{ran:?}"
);
let (base_half, overlay_half) = ran
.out
.split_once(".headwater/overlay.yml adds it")
.unwrap_or_else(|| panic!("the report names the overlay side: {ran:?}"));
assert!(
base_half.contains("released/2.0.0"),
"the report names the base file: {ran:?}"
);
assert!(
base_half.contains(r#"pattern: "SPEC-{namespace}-{slug}""#),
"the base's pattern is not on the base's side: {ran:?}"
);
assert!(base_half.contains("allocation: reconcile-first"), "{ran:?}");
assert!(
overlay_half.contains(r#"pattern: "{namespace}-SPEC-{slug}""#),
"the overlay's pattern is not on the overlay's side: {ran:?}"
);
assert!(overlay_half.contains("allocation: minted-once"), "{ran:?}");
assert!(
overlay_half.contains("at add.identifier_schemes.spec_id"),
"{ran:?}"
);
assert!(
ran.out
.contains("the two declarations differ, so what this repository inherits is a choice"),
"{ran:?}"
);
assert!(
ran.out.contains("inherit the base declaration whole"),
"{ran:?}"
);
assert!(ran.out.contains("restate it as an `override`"), "{ran:?}");
assert!(
ran.out
.find("1 `add` collision")
.zip(ran.out.find("addressability BROKEN"))
.is_some_and(|(task, table)| task > table),
"the judgment task is inside the dimension table: {ran:?}"
);
}
#[test]
fn the_version_flag_refuses_an_artifact_that_is_not_that_version() {
let root = Root::new("version-flag");
let first = root.publish("1.0.0");
let ran = root.run(&[
"taxonomy",
"diff",
first.to_str().expect("utf-8"),
"--to",
"2.0.0",
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(1), "{ran:?}");
assert!(ran.err.contains("the artifact declares 1.0.0"), "{ran:?}");
assert!(
!ran.out.contains("classification"),
"nothing is measured after the refusal: {ran:?}"
);
let ran = root.run(&[
"taxonomy",
"diff",
first.to_str().expect("utf-8"),
"--to",
">=1 <2",
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
assert_eq!(ran.dimension("classification"), "preserved", "{ran:?}");
}
#[test]
fn an_artifact_that_left_its_own_release_record_is_refused() {
let root = Root::new("edited-artifact");
let first = root.publish("1.0.0");
let taxonomy = first.join("taxonomy.yml");
let text = std::fs::read_to_string(&taxonomy).expect("the artifact reads");
std::fs::write(&taxonomy, format!("{text}\n# edited after publication\n"))
.expect("the artifact writes");
let ran = root.run(&[
"taxonomy",
"diff",
first.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(1), "{ran:?}");
assert!(
ran.err
.contains("not what its own release record says it is"),
"{ran:?}"
);
}
#[test]
fn a_finding_about_the_taxonomy_alone_is_consequence_and_not_instance_validity() {
let root = Root::new("taxonomy-grained");
root.publish("1.0.0");
root.edit(
"version: 2.0.0",
&[(
"controls:\n\n CT-COV-1:",
"controls:\n\n CT-NEW-1:\n mechanism: phase:runner.telepathy\n \
discharges: [OB-COV-1]\n trigger: pull_request\n posture: advisory\n \
acts: detective\n\n CT-COV-1:",
)],
);
let candidate = root.publish("2.0.0");
let ran = root.run(&[
"taxonomy",
"diff",
candidate.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
assert!(
ran.dimension("consequence").starts_with("BROKEN"),
"a rule the new base breaks is a consequence: {ran:?}"
);
assert_eq!(
ran.dimension("instance_validity"),
"preserved",
"no document stopped validating, so the two populations are not one: {ran:?}"
);
assert!(
ran.out.contains("control.mechanism.unimplemented"),
"and the report names the rule: {ran:?}"
);
}
#[test]
fn a_shelf_that_moves_reaches_classification_identifier_and_projection() {
let root = Root::new("shelf-moves");
root.publish("1.0.0");
root.edit(
"version: 2.0.0",
&[("path: docs/decisions/**", "path: docs/rulings/**")],
);
let candidate = root.publish("2.0.0");
let ran = root.run(&[
"taxonomy",
"diff",
candidate.to_str().expect("utf-8"),
"--now",
"2026-08-01",
]);
assert_eq!(ran.code, Some(0), "{ran:?}");
ran.states_no_contradiction();
for dimension in ["classification", "identifier", "projection"] {
assert!(
ran.dimension(dimension).starts_with("BROKEN"),
"`{dimension}` cannot go red, so no case above measures it: {ran:?}"
);
}
assert!(
ran.out
.contains("docs/decisions/0001-the-warrant-a-person-set.md"),
"the report names the document that changed kind: {ran:?}"
);
assert!(
ran.out.contains("HW-DR-0001"),
"and the identifier that stopped resolving: {ran:?}"
);
assert_eq!(
ran.dimension("instance_validity"),
"BROKEN, 15 no longer measured",
"no document failed here, so no count of failures may be printed: {ran:?}"
);
assert_eq!(
ran.dimension("consequence"),
"BROKEN, 15 no longer measured / 1 now passing",
"a check that started passing is not a failure: {ran:?}"
);
assert!(
ran.out.contains("this change requires a major version"),
"{ran:?}"
);
}