use std::path::{Path, PathBuf};
use std::process::Command;
fn repository() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../..")
.canonicalize()
.expect("the repository root resolves")
}
fn fixtures() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("fixtures")
}
struct Root {
at: PathBuf,
}
impl Drop for Root {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.at);
}
}
impl Root {
fn over(case: &str, label: &str) -> Root {
let at = std::env::temp_dir().join(format!(
"headwater-cli-wiring-{}-{label}",
std::process::id()
));
let _ = std::fs::remove_dir_all(&at);
copy(&fixtures().join(case), &at);
let headwater = at.join(".headwater");
std::fs::create_dir_all(&headwater).expect("the declaration directory is there");
for name in ["taxonomy.lock", "taxonomy.yml"] {
std::fs::copy(
repository().join(".headwater").join(name),
headwater.join(name),
)
.expect("the declaration copies");
}
Root { at }
}
fn path(&self, relative: &str) -> PathBuf {
self.at.join(relative)
}
fn run(&self, arguments: &[&str]) -> Ran {
let output = Command::new(env!("CARGO_BIN_EXE_headwater"))
.args(arguments)
.arg("--root")
.arg(&self.at)
.output()
.expect("the binary runs");
Ran {
code: output.status.code(),
out: String::from_utf8_lossy(&output.stdout).into_owned(),
err: String::from_utf8_lossy(&output.stderr).into_owned(),
}
}
}
struct Ran {
code: Option<i32>,
out: String,
err: String,
}
impl Ran {
fn says(&self, text: &str) -> bool {
self.out.contains(text)
}
}
fn copy(from: &Path, to: &Path) {
std::fs::create_dir_all(to).expect("the directory is there");
for entry in std::fs::read_dir(from).expect("the fixture directory reads") {
let entry = entry.expect("the entry reads");
let target = to.join(entry.file_name());
match entry.file_type().expect("the file type reads").is_dir() {
true => copy(&entry.path(), &target),
false => {
std::fs::copy(entry.path(), &target).expect("the fixture copies");
}
}
}
}
fn git(dir: &Path, arguments: &[&str]) -> String {
let output = Command::new("git")
.arg("-C")
.arg(dir)
.args(arguments)
.output()
.expect("git runs");
assert!(
output.status.success(),
"git {arguments:?} failed: {}",
String::from_utf8_lossy(&output.stderr)
);
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
struct Scratch(PathBuf);
impl Drop for Scratch {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.0);
}
}
impl std::ops::Deref for Scratch {
type Target = Path;
fn deref(&self) -> &Path {
&self.0
}
}
impl AsRef<Path> for Scratch {
fn as_ref(&self) -> &Path {
&self.0
}
}
impl AsRef<std::ffi::OsStr> for Scratch {
fn as_ref(&self) -> &std::ffi::OsStr {
self.0.as_os_str()
}
}
fn out_dir(label: &str) -> Scratch {
let at = std::env::temp_dir().join(format!(
"headwater-cli-wiring-change-out-{}-{label}",
std::process::id()
));
let _ = std::fs::remove_dir_all(&at);
Scratch(at)
}
#[test]
fn a_change_the_flag_named_reaches_the_verdict_and_not_only_the_parser() {
let root = Root::over("change", "change-reaches-the-verdict");
let manifest = root.path("manifest.txt");
let prior = fixtures().join("change-prior/0001-the-warrant-a-person-set.md");
std::fs::write(
&manifest,
format!(
"headwater change 1\nprior\tdocs/decisions/0001-the-warrant-a-person-set.md\t{}\n",
prior.display()
),
)
.expect("the manifest writes");
let unscoped = root.run(&["check", "--no-cache", "--now", "2026-08-01"]);
assert_eq!(unscoped.code, Some(0), "{}{}", unscoped.out, unscoped.err);
assert!(
unscoped.says("change-scoped-only"),
"a run carrying no change reports the promotion instance as skipped:\n{}",
unscoped.out
);
let scoped = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--change",
&manifest.display().to_string(),
]);
assert_eq!(scoped.code, Some(0), "{}{}", scoped.out, scoped.err);
assert!(
scoped.says("scoped to a change: 1 documents named, 0 added, 1 with a prior version"),
"the report states the change this run was scoped to:\n{}",
scoped.out
);
assert!(
scoped.says("1 promoted from `asserted` to `accepted`"),
"the run counts the promotion the change carried:\n{}",
scoped.out
);
assert!(
scoped.out != unscoped.out,
"a run scoped to a change reports something a full-corpus run does not"
);
let target = "docs/decisions/0001-the-warrant-a-person-set.md";
let accepted = std::fs::read_to_string(root.path(target)).expect("the accepted text reads");
std::fs::copy(&prior, root.path(target)).expect("the asserted text lands as the base version");
git(&root.at, &["init", "-q"]);
git(&root.at, &["config", "user.email", "fixtures@invalid"]);
git(&root.at, &["config", "user.name", "fixtures"]);
git(&root.at, &["add", "-A"]);
git(&root.at, &["commit", "-q", "-m", "base"]);
let base = git(&root.at, &["rev-parse", "HEAD"]);
std::fs::write(root.path(target), &accepted).expect("the accepted text returns");
std::fs::write(
root.path("docs/decisions/0002-added-by-the-verb-case.md"),
"the change this verb describes adds this file. Its own content plays no further part.\n",
)
.expect("the added file writes");
let out = out_dir("known-add-and-modify");
let produced = root.run(&["change", &base, &out.display().to_string()]);
assert_eq!(produced.code, Some(0), "{}{}", produced.out, produced.err);
let produced_manifest = out.join("manifest");
assert_eq!(
produced.out.trim(),
produced_manifest.display().to_string(),
"the verb prints the manifest's own path"
);
let manifest_text =
std::fs::read_to_string(&produced_manifest).expect("the produced manifest reads");
let mut lines: Vec<&str> = manifest_text.lines().collect();
lines.sort_unstable();
assert_eq!(
lines.len(),
3,
"one header line, one `added` line and one `prior` line:\n{manifest_text}"
);
assert_eq!(
lines[0],
"added\tdocs/decisions/0002-added-by-the-verb-case.md"
);
assert_eq!(lines[1], "headwater change 1");
let prior_line = lines[2];
let mut fields = prior_line.split('\t');
assert_eq!(fields.next(), Some("prior"));
assert_eq!(fields.next(), Some(target));
let prior_file = fields.next().expect("a third field");
assert_eq!(fields.next(), None, "a fourth field: {prior_line}");
assert_eq!(
std::fs::read_to_string(prior_file).expect("the prior file reads"),
std::fs::read_to_string(&prior).expect("the fixture's asserted text reads"),
"the prior file the verb wrote holds the asserted bytes, not the accepted ones"
);
let via_verb = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--change",
&produced_manifest.display().to_string(),
]);
assert_eq!(via_verb.code, Some(0), "{}{}", via_verb.out, via_verb.err);
assert!(
via_verb.says("1 promoted from `asserted` to `accepted`"),
"the manifest the verb produced reaches the same verdict as the hand-written one:\n{}",
via_verb.out
);
}
#[test]
fn a_shell_script_free_corpus_reaches_the_rule_through_the_verb_alone() {
let root = Root::over("change", "decisive-fixture-no-githooks");
assert!(
!root.path(".githooks").exists(),
"the decisive fixture carries no shell script of any kind: {}",
root.path(".githooks").display()
);
let target = "docs/decisions/0001-the-warrant-a-person-set.md";
let prior = fixtures().join("change-prior/0001-the-warrant-a-person-set.md");
let accepted = std::fs::read_to_string(root.path(target)).expect("the accepted text reads");
std::fs::copy(&prior, root.path(target)).expect("the asserted text lands as the base version");
git(&root.at, &["init", "-q"]);
git(&root.at, &["config", "user.email", "fixtures@invalid"]);
git(&root.at, &["config", "user.name", "fixtures"]);
git(&root.at, &["add", "-A"]);
git(&root.at, &["commit", "-q", "-m", "base"]);
let base = git(&root.at, &["rev-parse", "HEAD"]);
std::fs::write(root.path(target), &accepted).expect("the accepted text returns");
let unscoped = root.run(&["check", "--no-cache", "--now", "2026-08-01"]);
assert_eq!(unscoped.code, Some(0), "{}{}", unscoped.out, unscoped.err);
let before = unscoped.out.matches("change-scoped-only").count();
assert!(
before >= 1,
"the rule reports at least one skip with no change described:\n{}",
unscoped.out
);
let out = out_dir("decisive-fixture");
let produced = root.run(&["change", &base, &out.display().to_string()]);
assert_eq!(produced.code, Some(0), "{}{}", produced.out, produced.err);
let manifest = out.join("manifest");
let scoped = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--change",
&manifest.display().to_string(),
]);
assert_eq!(scoped.code, Some(0), "{}{}", scoped.out, scoped.err);
let after = scoped.out.matches("change-scoped-only").count();
assert!(
after < before,
"the change-scoped-only count did not fall: {before} before, {after} after\nunscoped:\n{}\nscoped:\n{}",
unscoped.out,
scoped.out
);
assert!(
scoped.says("1 promoted from `asserted` to `accepted`"),
"the promotion this corpus carries is evaluated, not skipped:\n{}",
scoped.out
);
}
#[test]
fn a_plan_that_stopped_partway_grades_nothing_through_the_verb() {
let root = Root::over("probes", "grade-reads-gradable");
let planned = root.run(&["probe", "plan"]);
assert_eq!(planned.code, Some(0), "{}{}", planned.out, planned.err);
assert!(
planned.says("over 1 of the 3 classified documents"),
"the plan stops partway and leaves a selection of one:\n{}",
planned.out
);
assert!(
planned.says("This run does not start"),
"the plan refuses this corpus:\n{}",
planned.out
);
let graded = root.run(&[
"probe",
"grade",
&root
.path("docs/probe-runs/first-regression.md")
.display()
.to_string(),
]);
assert_eq!(graded.code, Some(0), "{}{}", graded.out, graded.err);
assert!(
graded.says("Nothing was graded. `headwater probe plan` refuses this corpus: the probe at docs/probes/0002-the-category-is-outside-the-closed-set.md"),
"the verb reports the refusal the plan composed, which only `gradable` hands it:\n{}",
graded.out
);
assert!(
!graded.says("This transcript reached no grader"),
"the refusal stopped this verb before it read the transcript at all:\n{}",
graded.out
);
}
#[test]
fn the_generator_is_handed_the_refusal_beside_the_selection() {
let root = Root::over("probes", "generate-carries-the-refusal");
let generated = root.run(&["generate"]);
assert_eq!(
generated.code,
Some(0),
"{}{}",
generated.out,
generated.err
);
assert!(
generated.says("probe_result docs/probe-results/"),
"the probe_result declaration reaches this corpus:\n{}",
generated.out
);
assert!(
generated.says("it does not compose them over this corpus: the probe at docs/probes/0002-the-category-is-outside-the-closed-set.md"),
"the projection names the refusal the plan composed:\n{}",
generated.out
);
assert!(
!generated.says("nothing composed a probe selection and nothing said why"),
"a refusal reached the generator, so the caller that composed nothing is not this one:\n{}",
generated.out
);
}
fn flattened(help: &str) -> String {
help.split_whitespace().collect::<Vec<_>>().join(" ")
}
fn outside_a_corpus(label: &str, arguments: &[&str]) -> Ran {
let at = Scratch(std::env::temp_dir().join(format!(
"headwater-cli-wiring-{}-{label}",
std::process::id()
)));
let _ = std::fs::remove_dir_all(&at);
std::fs::create_dir_all(&at).expect("the directory is there");
let output = Command::new(env!("CARGO_BIN_EXE_headwater"))
.args(arguments)
.current_dir(&at)
.output()
.expect("the binary runs");
Ran {
code: output.status.code(),
out: String::from_utf8_lossy(&output.stdout).into_owned(),
err: String::from_utf8_lossy(&output.stderr).into_owned(),
}
}
#[test]
fn the_version_flag_prints_the_engine_constant_outside_a_corpus() {
for (label, flag) in [("version-long", "--version"), ("version-short", "-V")] {
let ran = outside_a_corpus(label, &[flag]);
assert_eq!(
ran.code,
Some(0),
"`{flag}` is a question rather than a mistake:\n{}{}",
ran.out,
ran.err
);
assert_eq!(
ran.err, "",
"`{flag}` writes nothing to standard error, so a caller may read the answer with the streams apart"
);
assert_eq!(
ran.out.lines().count(),
1,
"`{flag}` prints one line and nothing else:\n{}",
ran.out
);
assert_eq!(
ran.out.trim_end(),
headwater_resolve::release::ENGINE,
"`{flag}` prints the version a `requires_engine` range is read against"
);
}
}
#[test]
fn the_version_flag_reads_the_named_constant_and_not_a_local_env_read() {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/main.rs");
let text = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("{}: {e}", path.display()));
let (_, after) = text.split_once("if cli.version {").unwrap_or_else(|| {
panic!("`if cli.version` is no longer the shape of the version arm in main.rs")
});
let (arm, _) = after.split_once("\n }").unwrap_or_else(|| {
panic!("no closing brace found for the `if cli.version` arm in main.rs")
});
assert!(
arm.contains("headwater_resolve::release::ENGINE"),
"the version arm no longer names the shared constant:\n{arm}"
);
assert!(
!arm.contains("env!(\"CARGO_PKG_VERSION\")"),
"the version arm reads env!(\"CARGO_PKG_VERSION\") directly, which is the crate main.rs \
happens to sit in and not the number a `requires_engine` range is read against:\n{arm}"
);
}
fn source_files(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
if path.file_name().and_then(|name| name.to_str()) == Some("target") {
continue;
}
source_files(&path, out);
} else if path.extension().and_then(|ext| ext.to_str()) == Some("rs") {
out.push(path);
}
}
}
#[test]
fn exactly_one_site_defines_the_engine_version_constant() {
let needle = "env!(\"CARGO_PKG_VERSION\")";
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let mut files = Vec::new();
source_files(&root, &mut files);
let mut sites: Vec<(PathBuf, usize)> = Vec::new();
for path in files {
let Ok(text) = std::fs::read_to_string(&path) else {
continue;
};
for (index, line) in text.lines().enumerate() {
if line.trim_start().starts_with("//") {
continue;
}
if line.contains(needle) {
sites.push((path.clone(), index + 1));
}
}
}
assert_eq!(
sites.len(),
1,
"a second env!(\"CARGO_PKG_VERSION\") read appeared outside the one site that defines \
the constant: {sites:?}"
);
let defined_in = root.join("crates/resolve/src/release.rs");
assert_eq!(
sites[0].0.canonicalize().unwrap(),
defined_in.canonicalize().unwrap(),
"the one site reading CARGO_PKG_VERSION is not release.rs's own definition: {sites:?}"
);
}
#[test]
fn a_refused_command_line_names_the_grammar_rather_than_printing_it() {
for (label, arguments, offender) in [
(
"unknown-flag",
["check", "--nonsense"].as_slice(),
"--nonsense",
),
("unknown-verb", ["versoin"].as_slice(), "versoin"),
] {
let ran = outside_a_corpus(label, arguments);
assert_eq!(
ran.code,
Some(1),
"`headwater {}` is refused with the one failing status this binary has:\n{}",
arguments.join(" "),
ran.err
);
assert_eq!(
ran.out, "",
"a refusal writes nothing to standard output, so a caller reading a report by pipe reads a report or nothing"
);
assert!(
!ran.err.contains("--root <path>"),
"`headwater {}` printed the usage body: `--root <path>` is a line of it and it is on standard error:\n{}",
arguments.join(" "),
ran.err
);
assert!(
ran.err.contains(offender),
"`headwater {}` says `{offender}` back to the caller, so the refusal names what was wrong:\n{}",
arguments.join(" "),
ran.err
);
assert!(
ran.err.contains("headwater --help"),
"`headwater {}` names where the grammar is:\n{}",
arguments.join(" "),
ran.err
);
assert!(
ran.err.lines().count() <= 5,
"`headwater {}` refuses in five lines or fewer, and it wrote {}:\n{}",
arguments.join(" "),
ran.err.lines().count(),
ran.err
);
}
}
#[test]
fn a_refusal_about_the_corpus_does_not_name_the_grammar() {
let root = Root::over("change", "corpus-fact-no-grammar-pointer");
let ran = root.run(&["init"]);
assert_eq!(
ran.code,
Some(1),
"`headwater init` over an already-bound root fails:\n{}",
ran.err
);
assert!(
ran.err.contains(headwater_resolve::package::CONSUMER),
"the refusal names the file that is already there:\n{}",
ran.err
);
assert!(
!ran.err.contains("headwater --help"),
"a corpus fact reached through a correct command line names the grammar, and should not:\n{}",
ran.err
);
}
#[test]
fn the_help_flag_answers_on_standard_output_outside_a_corpus() {
for (label, flag) in [("help-long", "--help"), ("help-short", "-h")] {
let ran = outside_a_corpus(label, &[flag]);
assert_eq!(
ran.code,
Some(0),
"`{flag}` is a question rather than a mistake:\n{}{}",
ran.out,
ran.err
);
assert_eq!(
ran.err, "",
"`{flag}` writes nothing to standard error, so a caller may read the answer with the streams apart"
);
assert!(
ran.out.contains("--root <path>"),
"`{flag}` is where the grammar is, and `--root <path>` is a line of it:\n{}",
ran.out
);
for verb in headwater_verbs::VERBS {
assert!(
ran.out.contains(verb.name),
"`{flag}` is where a caller finds a verb, and it does not name `{}`:\n{}",
verb.name,
ran.out
);
}
}
}
#[test]
fn a_flag_that_belongs_to_another_verb_is_refused_rather_than_ignored() {
let root = Root::over("change", "level-belongs-to-conformance");
let ran = root.run(&["check", "--no-cache", "--now", "2026-08-01"]);
assert_eq!(
ran.code,
Some(0),
"over this root the verb succeeds, which is what makes the refusal below the only route to a 1:\n{}{}",
ran.out,
ran.err
);
assert!(
!ran.out.is_empty(),
"over this root the verb writes a report, which is what makes an empty standard output below decisive"
);
let refused = root.run(&[
"check",
"--level",
"L0",
"--no-cache",
"--now",
"2026-08-01",
]);
assert_eq!(
refused.code,
Some(1),
"`--level` is not a flag `check` reads, and this binary has one failing status:\n{}{}",
refused.out,
refused.err
);
assert_eq!(
refused.out, "",
"a refused command line writes no report, so a caller reading by pipe reads a report or nothing"
);
assert!(
refused.err.contains("--level"),
"the refusal names the flag the caller wrote:\n{}",
refused.err
);
let read = root.run(&["conformance", "--level", "L0", "--now", "2026-08-01"]);
assert!(
!read.err.contains("--level"),
"`--level` reaches the verb that declares it, whatever that verb then reports:\n{}",
read.err
);
}
#[test]
fn a_verb_this_engine_never_implemented_does_not_name_the_grammar() {
let ran = outside_a_corpus("query-states-a-wait", &["query", "anything"]);
assert_eq!(
ran.code,
Some(1),
"`headwater query` is refused with the one failing status this binary has:\n{}",
ran.err
);
assert_eq!(
ran.out, "",
"a refusal writes nothing to standard output, so a caller reading by pipe reads a report or nothing"
);
assert!(
ran.err.contains("no document states what an expression is"),
"the refusal states the wait rather than a fault:\n{}",
ran.err
);
assert!(
!ran.err.contains("headwater --help"),
"the grammar lists `query` and says the same thing, so this points the caller at a repeat of the sentence above it:\n{}",
ran.err
);
}
#[test]
fn a_refusal_a_flag_repairs_still_names_the_grammar() {
let root = Root::over("change", "vendor-pin-names-the-grammar");
let at = root.path(".headwater/taxonomy.yml");
let text = std::fs::read_to_string(&at).expect("the declaration reads");
let without: String = text
.lines()
.filter(|line| !line.trim_start().starts_with("digest:"))
.map(|line| format!("{line}\n"))
.collect();
std::fs::write(&at, without).expect("the declaration writes");
let fetched = root.path("fetched");
std::fs::create_dir_all(&fetched).expect("the directory is there");
let fetched = fetched.to_str().expect("the path is utf-8").to_string();
let ran = root.run(&["taxonomy", "vendor", &fetched]);
assert_eq!(
ran.code,
Some(1),
"an unpinned artifact is refused:\n{}",
ran.err
);
assert!(
ran.err.contains("nothing pins this artifact"),
"the refusal is the pin site and not something earlier:\n{}",
ran.err
);
assert!(
ran.err.contains("headwater --help"),
"a refusal a flag repairs names where that flag is written down:\n{}",
ran.err
);
let ran = root.run(&[
"taxonomy",
"vendor",
&fetched,
"--expect",
"sha256:0000000000000000000000000000000000000000000000000000000000000000",
]);
assert!(
!ran.err.contains("nothing pins this artifact"),
"`--expect` is a complete route past the pin, which is why the site stays at `fail`:\n{}",
ran.err
);
}
#[test]
fn every_refusal_about_a_value_this_run_built_goes_out_through_defect() {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/main.rs");
let text = std::fs::read_to_string(&path).expect("main.rs reads");
for needle in [
"the payload this run built is not a mapping",
"the payload this run built does not load",
] {
let (before, _) = text
.split_once(needle)
.unwrap_or_else(|| panic!("`{needle}` is no longer a message in main.rs"));
let (_, helper) = ["fail(", "refuse(", "defect("]
.iter()
.filter_map(|opener| before.rfind(opener).map(|at| (at, *opener)))
.max()
.expect("a refusal helper opens the call");
assert_eq!(
helper, "defect(",
"`{needle}` goes out through `{helper}`. A value this run's own code built is a \
defect of this engine rather than a fact about the caller or the corpus"
);
}
}
#[test]
fn the_defect_helper_names_the_engine_version_and_no_address() {
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/main.rs");
let text = std::fs::read_to_string(&path).expect("main.rs reads");
let (_, after) = text
.split_once("fn defect(message: &str) -> ExitCode {")
.expect("`fn defect` is no longer the shape of the helper in main.rs");
let (body, _) = after
.split_once("\n}")
.expect("no closing brace found for `fn defect` in main.rs");
assert!(
body.contains("headwater_resolve::release::ENGINE"),
"a report of a defect needs the version it was found in, and this names no version:\n{body}"
);
for address in ["http://", "https://", "github.com"] {
assert!(
!body.contains(address),
"`defect` writes `{address}` to a caller. This repository has no published home, so \
the address would answer nothing:\n{body}"
);
}
assert!(
body.contains("ExitCode::FAILURE"),
"this binary has one failing status and `defect` returns it:\n{body}"
);
}
#[test]
fn a_refusal_the_consumer_declaration_caused_does_not_name_the_grammar() {
let root = Root::over("change", "import-declaration-no-grammar-pointer");
let at = root.path(".headwater/taxonomy.yml");
let mut text = std::fs::read_to_string(&at).expect("the declaration reads");
text.push_str("\nimports:\n upstream:\n channel: stable\n");
std::fs::write(&at, text).expect("the declaration writes");
let ran = root.run(&["import"]);
assert_eq!(
ran.code,
Some(1),
"an import declaration this engine cannot read is refused:\n{}",
ran.err
);
assert!(
ran.err.contains("`imports.upstream` names no `at`"),
"the refusal names the entry that is incomplete:\n{}",
ran.err
);
assert!(
!ran.err.contains("headwater --help"),
"the consumer declaration is a fixed location this engine reads on every run, and no \
command line reaches past what it says:\n{}",
ran.err
);
}
#[test]
fn a_payload_this_verb_writes_loads_whatever_a_path_or_an_owner_holds() {
let root = Root::over("change", "infer-quotes-every-scalar");
copy(
&repository().join(headwater_resolve::package::PACKAGES),
&root.path(headwater_resolve::package::PACKAGES),
);
std::fs::copy(
repository().join(".headwater/overlay.yml"),
root.path(".headwater/overlay.yml"),
)
.expect("the overlay copies");
for (label, name) in [
("a closing brace", "91-brace}here.md"),
("a comma", "91-comma,here.md"),
("a quotation mark", "91-quote\"here.md"),
] {
let from = root.path("docs/decisions/0001-the-warrant-a-person-set.md");
let to = root.path(&format!("docs/decisions/{name}"));
std::fs::copy(&from, &to).unwrap_or_else(|why| panic!("the {label} case copies: {why}"));
}
let ran = root.run(&[
"infer",
"--write",
"--owner",
"alice\nbob\r\tcarol",
"--now",
"2026-08-01",
]);
assert!(
!ran.err.contains("does not load"),
"the payload loads back, so no scalar this run wrote broke it:\n{}",
ran.err
);
assert!(
!ran.err.contains("this is a defect in engine"),
"no input reaches the defect helper, which is what makes that helper's population empty:\n{}",
ran.err
);
assert_eq!(
ran.code,
Some(0),
"the run completes:\n{}{}",
ran.out,
ran.err
);
let lock = std::fs::read_to_string(root.path(".headwater/taxonomy.lock"))
.expect("the lock reads back");
assert!(
lock.contains("91-comma,here.md"),
"a comma in a path used to truncate the value silently, and the lock declared debt \
against a document that does not exist:\n{lock}"
);
assert!(
lock.contains("91-brace}here.md"),
"a closing brace in a path used to break the payload:\n{lock}"
);
let read = root.run(&["check", "--no-cache", "--now", "2026-08-01"]);
assert!(
!read.err.contains("the lock cannot be read"),
"the lock this run wrote loads again. A carriage return in an owner used to write a lock \
no later command could read, with this run still exiting 0:\n{}",
read.err
);
assert_eq!(
read.code,
Some(0),
"and the corpus still checks over it:\n{}{}",
read.out,
read.err
);
}
#[test]
fn a_discriminator_stated_on_the_command_line_refuses_and_writes_nothing() {
let root = Root::over("change", "facet-names-the-discriminator");
let refused = root.run(&[
"new",
"design_spec",
"--title",
"A part the caller renamed",
"--facet",
"doc_type=review_record",
]);
assert_eq!(
refused.code,
Some(1),
"a value for the discriminator refuses:\n{}{}",
refused.out,
refused.err
);
assert!(
refused.err.contains("review_record") && refused.err.contains("design_spec"),
"the refusal names the value stated and the kind that decides it:\n{}",
refused.err
);
assert!(
!refused.out.contains("wrote"),
"nothing is reported as written:\n{}",
refused.out
);
let shelf = root.path("docs/spec");
assert!(
!shelf.exists(),
"and nothing is on the shelf: {}",
shelf.display()
);
let wrote = root.run(&["new", "design_spec", "--title", "A part the caller renamed"]);
assert_eq!(
wrote.code,
Some(0),
"the same run with no stated facet writes:\n{}{}",
wrote.out,
wrote.err
);
let written = root.path("docs/spec/01-a-part-the-caller-renamed.md");
let text = std::fs::read_to_string(&written).expect("the document reads");
assert!(
text.contains("doc_type: design_spec"),
"and the discriminator it writes is the kind:\n{text}"
);
}
#[test]
fn the_change_help_names_the_header_a_manifest_must_open_with() {
let help = outside_a_corpus("change-help", &["check", "--help"]);
assert_eq!(
help.code,
Some(0),
"`check --help` is a question rather than a mistake:\n{}{}",
help.out,
help.err
);
assert!(
flattened(&help.out).contains("headwater change 1"),
"the `--change` help names the header a manifest opens with:\n{}",
help.out
);
let root = Root::over("change", "change-help-header");
let prior = fixtures().join("change-prior/0001-the-warrant-a-person-set.md");
let body = format!(
"prior\tdocs/decisions/0001-the-warrant-a-person-set.md\t{}\n",
prior.display()
);
let headless = root.path("headless.txt");
std::fs::write(&headless, &body).expect("the manifest writes");
let refused = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--change",
&headless.display().to_string(),
]);
assert_eq!(
refused.code,
Some(1),
"a manifest with no header is refused rather than read:\n{}{}",
refused.out,
refused.err
);
assert!(
refused.err.contains("headwater change 1"),
"and the refusal names the line that is missing:\n{}",
refused.err
);
let headed = root.path("headed.txt");
std::fs::write(
&headed,
format!("{}\n{body}", headwater_check::change::FORMAT),
)
.expect("the manifest writes");
let read = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--change",
&headed.display().to_string(),
]);
assert_eq!(
read.code,
Some(0),
"the same manifest under that header reads:\n{}{}",
read.out,
read.err
);
assert!(
read.says("scoped to a change"),
"and the run is scoped to it:\n{}",
read.out
);
}
#[test]
fn route_promises_no_silence_and_is_never_silent() {
let help = outside_a_corpus("route-help", &["route", "--help"]);
assert_eq!(
help.code,
Some(0),
"`route --help` is a question rather than a mistake:\n{}{}",
help.out,
help.err
);
assert!(
!flattened(&help.out).contains("silent when nothing matches"),
"the description does not promise a silence this verb never keeps:\n{}",
help.out
);
let root = Root::over("change", "route-is-never-silent");
let ran = root.run(&["route", "a task no purpose of this corpus answers"]);
assert_eq!(
ran.code,
Some(0),
"a route that matches nothing is a result rather than a mistake:\n{}{}",
ran.out,
ran.err
);
assert_eq!(
ran.err, "",
"and it writes nothing to standard error:\n{}",
ran.err
);
assert!(
ran.out.lines().count() >= 3,
"a route that matches nothing still writes its report:\n{}",
ran.out
);
assert!(
ran.out.contains("no purpose") || ran.out.contains("declares no purpose"),
"and it says which of the two reasons applies:\n{}",
ran.out
);
}
#[test]
fn only_the_sarif_artifact_declares_its_own_loss_set() {
let help = outside_a_corpus("format-help", &["check", "--help"]);
assert_eq!(help.code, Some(0), "{}{}", help.out, help.err);
assert!(
!flattened(&help.out).contains("Each names what it could not carry"),
"the help does not claim a loss set every target writes:\n{}",
help.out
);
let root = Root::over("change", "loss-set-per-target");
let mut carries = Vec::new();
for target in ["text", "json", "sarif", "markdown"] {
let ran = root.run(&[
"check",
"--no-cache",
"--now",
"2026-08-01",
"--format",
target,
]);
assert_eq!(
ran.code,
Some(0),
"`--format {target}` writes an artifact:\n{}{}",
ran.out,
ran.err
);
carries.push((target, ran.out.contains("loss_set")));
}
assert_eq!(
carries,
vec![
("text", false),
("json", false),
("sarif", true),
("markdown", false)
],
"only the SARIF artifact carries its own loss set"
);
}
#[test]
fn capture_pools_across_taxonomies_and_names_every_one() {
let help = outside_a_corpus("capture-help", &["capture", "--help"]);
assert_eq!(help.code, Some(0), "{}{}", help.out, help.err);
assert!(
!flattened(&help.out).contains("never averages readings taken under two taxonomies"),
"the description does not claim a refusal this verb never makes:\n{}",
help.out
);
let root = Root::over("change", "capture-pools-across-locks");
let store = root.path(".headwater/capture-cost.jsonl");
std::fs::write(
&store,
"{\"lock\":\"sha256:aaaa\",\"date\":\"2026-08-01\",\"kind\":\"decision\",\
\"document\":\"docs/decisions/0001-the-warrant-a-person-set.md\",\"id\":\"DR-ONE\",\
\"fields\":[4,5],\"sections\":[3,3],\"identifier\":[1,1],\"edge_halves\":[0,0]}\n\
{\"lock\":\"sha256:bbbb\",\"date\":\"2026-08-02\",\"kind\":\"decision\",\
\"document\":\"docs/decisions/0001-the-warrant-a-person-set.md\",\"id\":\"DR-TWO\",\
\"fields\":[2,5],\"sections\":[3,3],\"identifier\":[1,1],\"edge_halves\":[0,0]}\n",
)
.expect("the store writes");
let ran = root.run(&["capture"]);
assert_eq!(
ran.code,
Some(0),
"`capture` reads the store back:\n{}{}",
ran.out,
ran.err
);
assert!(
ran.says("2 readings"),
"it read both readings:\n{}",
ran.out
);
assert!(
ran.says("14 of 18"),
"it pools the two readings into one fraction:\n{}",
ran.out
);
assert!(
ran.says("2 taxonomies produced these readings"),
"and it names the count of taxonomies it pooled across:\n{}",
ran.out
);
for lock in ["sha256:aaaa", "sha256:bbbb"] {
assert!(ran.says(lock), "and it names {lock}:\n{}", ran.out);
}
}
#[test]
fn a_check_rule_this_engine_ships_is_an_edge_endpoint_and_a_typo_is_not() {
let root = Root::over("check-rule-anchor", "check-rule-binds-and-refuses");
let ran = root.run(&["check", "--no-cache", "--now", "2026-09-06"]);
assert_eq!(ran.code, Some(0), "{}{}", ran.out, ran.err);
assert!(
ran.says("check_rule `section.required.missing` via check-rule"),
"a rule this engine ships is a bound target:\n{}",
ran.out
);
assert!(
ran.says("this engine implements no rule `no.such.rule`"),
"a rule this engine does not ship is refused by name:\n{}",
ran.out
);
assert!(
!ran.says("check_rule `no.such.rule` via check-rule"),
"nothing guessed a binding for it:\n{}",
ran.out
);
let overdue = root.run(&["check", "--no-cache", "--now", "2026-12-31"]);
assert_eq!(overdue.code, Some(0), "{}{}", overdue.out, overdue.err);
assert!(
!overdue.says("`requirement-verified`: 116 days"),
"a bound check-rule anchor now settles the participation expectation:\n{}",
overdue.out
);
}