use assert_cmd::Command;
fn skill(name: &str) -> String {
let output = Command::cargo_bin("provenance")
.unwrap()
.args(["skills", "show", name])
.assert()
.success()
.get_output()
.stdout
.clone();
String::from_utf8(output).unwrap()
}
fn normalized(text: &str) -> String {
text.split_whitespace().collect::<Vec<_>>().join(" ")
}
#[test]
fn shaping_guidance_audits_a_rule_against_its_grounding_and_not_against_code() {
let shaping = skill("provenance-shaping");
let prose = normalized(&shaping);
assert!(shaping.contains("## Auditing a Rule"), "{shaping}");
assert!(shaping.contains("Decision fidelity"), "{shaping}");
assert!(shaping.contains("Implementation fidelity"), "{shaping}");
assert!(
prose.contains(
"Audit the Rule against its sources, the Requirement it refines, and the ratified \
decisions that produced it."
),
"{shaping}"
);
assert!(
prose.contains(
"Never report a Rule as invented, invalid, or unsupported because no code \
implements it."
),
"{shaping}"
);
}
#[test]
fn shaping_guidance_keeps_rule_facts_independent_and_scanning_explicit() {
let shaping = skill("provenance-shaping");
let prose = normalized(&shaping);
for fact in [
"Rule lifecycle",
"decision grounding",
"implementation binding",
"verification binding",
] {
assert!(
prose.contains(fact),
"shaping guidance does not name {fact}: {shaping}"
);
}
assert!(
prose.contains(
"Source evidence, a Requirement, a ratified Resolution, or explicit human \
ratification can support a Rule."
),
"{shaping}"
);
assert!(
prose.contains("Prime and traceability are graph reads. They do not scan code"),
"{shaping}"
);
assert!(
prose.contains("provenance coverage scan --path . --scope <scope> --validate-rules"),
"{shaping}"
);
}
#[test]
fn shaping_guidance_keeps_unsupported_behaviour_out_of_active() {
let shaping = skill("provenance-shaping");
let prose = normalized(&shaping);
for state in [
"`draft`",
"`review`",
"`proposed` proposal",
"open Question",
] {
assert!(
shaping.contains(state),
"shaping guidance does not name {state}: {shaping}"
);
}
assert!(
prose.contains("Do not make it `active` to clear a report."),
"{shaping}"
);
}
#[test]
fn guidance_calls_the_source_fields_citations_and_not_planned_code_homes() {
for name in ["provenance-shaping", "provenance-grounded-writing"] {
let text = skill(name);
assert!(
text.contains("are not a planned home for the code")
|| text.contains("They name no home for the code"),
"{name} does not deny the planned-home reading: {text}"
);
}
let writing = skill("provenance-grounded-writing");
assert!(
!writing.contains("--source-document ApprovalService.php"),
"the worked example still cites a code file as source material: {writing}"
);
assert!(
writing.contains("--source-document \"Finance Policy v3 (2026 revision)\""),
"{writing}"
);
}
#[test]
fn shaping_guidance_tells_an_agent_to_check_the_installed_cli() {
let shaping = skill("provenance-shaping");
assert!(shaping.contains("## Check your CLI"), "{shaping}");
assert!(shaping.contains("provenance --version"), "{shaping}");
assert!(
shaping.contains("cargo install provenance-cli --force"),
"{shaping}"
);
assert!(
shaping.contains("A Resolution producer is not required"),
"{shaping}"
);
}