use crate::brain::agent::service::phantom::{
asserted_history_denials, asserted_produced_identifiers, denials_contradicted,
ledger_tool_inputs, mixed_iteration_facts, mixed_iteration_facts_with_history,
};
const DENIAL_TEXT: &str = "No `sleep` command was ever in my tool calls.";
fn bash_input(command: &str) -> String {
format!(r#"{{"command":"{command}"}}"#)
}
#[test]
fn a_denied_command_is_extracted() {
let denials = asserted_history_denials(DENIAL_TEXT);
assert_eq!(denials, vec!["sleep".to_string()], "{denials:?}");
}
#[test]
fn the_never_ran_form_is_extracted() {
for text in [
"I never ran `cargo clippy`.",
"I didn't run cargo clippy.",
"I did not call `cargo clippy`.",
"I never invoked `cargo clippy`.",
] {
let denials = asserted_history_denials(text);
assert!(
denials.iter().any(|d| d == "cargo"),
"{text} produced {denials:?}"
);
}
}
#[test]
fn a_pronoun_names_nothing_checkable() {
for text in [
"I never ran it.",
"I didn't call that.",
"I never executed anything.",
] {
let denials = asserted_history_denials(text);
assert!(denials.is_empty(), "{text} produced {denials:?}");
}
}
#[test]
fn ordinary_prose_yields_no_denial() {
for text in [
"No issues found in the gate.",
"There were no test failures.",
"The clippy run was clean.",
] {
let denials = asserted_history_denials(text);
assert!(denials.is_empty(), "{text} produced {denials:?}");
}
}
#[test]
fn a_denial_the_calls_contradict_is_flagged() {
let denials = asserted_history_denials(DENIAL_TEXT);
let executed = vec![bash_input("sleep 30")];
assert_eq!(
denials_contradicted(&denials, &executed),
vec!["sleep".to_string()]
);
}
#[test]
fn a_wrapped_denial_still_counts() {
let denials = asserted_history_denials(DENIAL_TEXT);
for command in ["timeout 30 sleep 5", "sudo sleep 5", "cd /tmp && sleep 5"] {
let executed = vec![bash_input(command)];
assert_eq!(
denials_contradicted(&denials, &executed),
vec!["sleep".to_string()],
"{command} was not read as a sleep"
);
}
}
#[test]
fn a_mere_mention_does_not_contradict() {
let denials = asserted_history_denials(DENIAL_TEXT);
for command in [
"grep -rn \"sleep\" src/",
"rg 'sleep' ~/.opencrabs/logs",
"echo sleep",
] {
let executed = vec![bash_input(command)];
assert!(
denials_contradicted(&denials, &executed).is_empty(),
"{command} was miscounted as a sleep"
);
}
}
#[test]
fn a_true_denial_is_not_flagged() {
let denials = asserted_history_denials(DENIAL_TEXT);
let executed = vec![bash_input("cargo clippy --all-features")];
assert!(denials_contradicted(&denials, &executed).is_empty());
}
#[test]
fn a_referenced_number_is_not_a_claim() {
for text in [
"Check #2098 for the details.",
"That is #2122.",
"See #1693.",
] {
let ids = asserted_produced_identifiers(text);
assert!(ids.is_empty(), "{text} produced {ids:?}");
}
}
#[test]
fn a_reported_filing_is_a_claim() {
let ids = asserted_produced_identifiers("Filed #2122 and closed #2123.");
assert_eq!(ids, vec!["#2122".to_string(), "#2123".to_string()]);
}
#[test]
fn a_filing_backed_by_a_url_is_not_flagged() {
let text = "Filed #2122 with the measurement.";
let evidence = "https://github.com/opencrabs/opencrabs/issues/2122";
let verdict = mixed_iteration_facts(text, &[], &[], evidence);
assert!(
verdict.is_none(),
"a backed filing was flagged: {verdict:?}"
);
}
#[test]
fn a_filing_with_nothing_behind_it_is_flagged() {
let text = "Filed #9999 for that.";
let verdict = mixed_iteration_facts(text, &[], &[], "no tool output at all")
.expect("an unbacked filing was not flagged");
assert!(
verdict.branches.contains(&"mixed_unbacked_actions"),
"wrong branch: {:?}",
verdict.branches
);
assert!(
verdict.unbacked_actions.iter().any(|a| a.contains("#9999")),
"the identifier was not named: {:?}",
verdict.unbacked_actions
);
}
#[test]
fn a_non_ascii_tail_does_not_panic_the_verb_window() {
let text = format!("Filed #2122 {}", "é".repeat(40));
let ids = asserted_produced_identifiers(&text);
assert_eq!(ids, vec!["#2122".to_string()]);
}
#[test]
fn a_recorded_call_is_recovered_from_the_ledger() {
let row = "Done.\n<!-- tools-v2: [{\"d\":\"bash: sleep 30\",\"s\":true,\"i\":{\"command\":\"sleep 30\"}}] -->\n";
let inputs = ledger_tool_inputs(&[row.to_string()]);
assert_eq!(inputs.len(), 1, "{inputs:?}");
assert!(inputs[0].contains("sleep 30"), "{inputs:?}");
}
#[test]
fn an_older_row_without_the_input_field_still_yields_the_command() {
let row = "\n<!-- tools-v2: [{\"d\":\"bash: sleep 30\",\"s\":true}] -->\n";
let inputs = ledger_tool_inputs(&[row.to_string()]);
assert_eq!(inputs, vec!["sleep 30".to_string()]);
}
#[test]
fn a_ledger_quoted_in_prose_is_not_history() {
let row =
"The row read: <!-- tools-v2: [{\"i\":{\"command\":\"sleep 30\"}}] --> and that is all.";
let inputs = ledger_tool_inputs(&[row.to_string()]);
assert!(inputs.is_empty(), "{inputs:?}");
}
#[test]
fn an_earlier_turn_contradicts_the_denial() {
let history = vec![bash_input("sleep 30")];
let verdict = mixed_iteration_facts_with_history(DENIAL_TEXT, &[], &[], "", &history)
.expect("a denial contradicted by earlier turns was not flagged");
assert!(
verdict.unbacked_actions.iter().any(|a| a == "sleep"),
"{:?}",
verdict.unbacked_actions
);
}
#[test]
fn earlier_history_never_clears_a_this_turn_claim() {
let text = "Ran `gh pr view 2098` and it was already merged.";
let history = vec![bash_input("gh pr view 2098")];
let verdict = mixed_iteration_facts_with_history(text, &[], &[], "", &history)
.expect("the this-turn claim was cleared by old history");
assert!(
verdict.branches.contains(&"mixed_uncalled_commands"),
"{:?}",
verdict.branches
);
}
#[test]
fn the_denial_reaches_the_violation() {
let executed = vec![bash_input("sleep 3111")];
let verdict = mixed_iteration_facts(DENIAL_TEXT, &executed, &[], "")
.expect("the contradicted denial was not flagged");
assert!(
verdict.branches.contains(&"mixed_unbacked_actions"),
"wrong branch: {:?}",
verdict.branches
);
assert!(
verdict.unbacked_actions.iter().any(|a| a == "sleep"),
"the denied command was not named: {:?}",
verdict.unbacked_actions
);
}
#[test]
fn an_honest_turn_stays_clean() {
let text = "Clippy came back clean. No `sleep` command was in that run.";
let executed = vec![bash_input("cargo clippy --all-features")];
let outputs = vec!["Finished `dev` profile".to_string()];
assert!(
mixed_iteration_facts(text, &executed, &outputs, "Finished `dev` profile").is_none(),
"an honest answer was flagged"
);
}
#[test]
fn a_kill_claim_without_a_named_command_is_not_flagged() {
let text = "I killed the gate.";
let executed = vec![bash_input("grep -n foo src/bar.rs")];
let outputs = vec!["foo:12".to_string()];
assert!(
mixed_iteration_facts(text, &executed, &outputs, "foo:12").is_none(),
"a claim with nothing checkable in it was flagged"
);
}
#[test]
fn the_nudge_picker_never_falls_through_to_no_tool_calls() {
let src = include_str!("../brain/agent/service/tool_loop.rs");
let (_, block) = src
.split_once("if let Some(violation) = mixed_fact_verdict")
.expect("the mixed-iteration correction is gone");
let (block, _) = block
.split_once("context.add_message(Message::user(nudge));")
.expect("the correction block never injects its nudge");
let actions = block
.find("unbacked_actions_nudge(")
.expect("the actions nudge is never selected in the mixed correction");
let fallthrough = block
.find("super::nudge::no_tool_calls_nudge(is_local_provider)")
.expect("the no-tool-calls fallthrough is gone from the mixed correction");
assert!(
actions < fallthrough,
"the actions nudge sits after the no-tool-calls fallthrough"
);
}