use std::{fs, path::Path};
use assert_cmd::Command;
use predicates::prelude::*;
fn git(repo: &Path, args: &[&str]) {
let status = std::process::Command::new("git")
.args(args)
.current_dir(repo)
.status()
.unwrap();
assert!(status.success(), "git {args:?} failed");
}
#[cfg(unix)]
fn make_executable(path: &Path) {
use std::os::unix::fs::PermissionsExt;
let mut permissions = fs::metadata(path).unwrap().permissions();
permissions.set_mode(0o755);
fs::set_permissions(path, permissions).unwrap();
}
#[cfg(not(unix))]
fn make_executable(_path: &Path) {}
#[test]
fn review_command_writes_ledger_with_mocked_reviewer_cli() {
let temp = tempfile::tempdir().unwrap();
let repo = temp.path().join("repo");
let bin = temp.path().join("bin");
fs::create_dir(&repo).unwrap();
fs::create_dir(&bin).unwrap();
git(&repo, &["init"]);
git(&repo, &["config", "user.email", "truth@example.invalid"]);
git(&repo, &["config", "user.name", "Truth Mirror Test"]);
fs::write(repo.join("file.txt"), "hello\n").unwrap();
git(&repo, &["add", "file.txt"]);
git(
&repo,
&[
"commit",
"-m",
"feat: add file",
"-m",
"CLAIM: add file | verified: cargo test | evidence: tests:review-e2e",
],
);
let fake_codex = bin.join("codex");
fs::write(
&fake_codex,
"#!/usr/bin/env python3\nprint('VERDICT: PASS')\nprint('FINDINGS:')\n",
)
.unwrap();
make_executable(&fake_codex);
let path = format!(
"{}:{}",
bin.display(),
std::env::var("PATH").unwrap_or_default()
);
Command::cargo_bin("truth-mirror")
.unwrap()
.current_dir(&repo)
.env("PATH", path)
.args([
"--state-dir",
".truth-mirror",
"review",
"HEAD",
"--watched-agent",
"claude",
"--watched-model",
"model-a",
"--reviewer-harness",
"codex",
"--reviewer-model",
"model-b",
])
.assert()
.success();
let ledger = fs::read_to_string(repo.join(".truth-mirror/ledger.jsonl")).unwrap();
assert!(ledger.contains("\"verdict\":\"PASS\""));
Command::cargo_bin("truth-mirror")
.unwrap()
.current_dir(&repo)
.args(["--state-dir", ".truth-mirror", "ledger", "stats"])
.assert()
.success()
.stdout(predicate::str::contains("pass=1"));
}
#[test]
fn review_strict_goal_loops_until_lie_threshold() {
let temp = tempfile::tempdir().unwrap();
let repo = temp.path().join("repo");
let bin = temp.path().join("bin");
fs::create_dir(&repo).unwrap();
fs::create_dir(&bin).unwrap();
git(&repo, &["init"]);
git(&repo, &["config", "user.email", "truth@example.invalid"]);
git(&repo, &["config", "user.name", "Truth Mirror Test"]);
fs::write(repo.join("file.txt"), "hello\n").unwrap();
git(&repo, &["add", "file.txt"]);
git(
&repo,
&[
"commit",
"-m",
"feat: add file",
"-m",
"CLAIM: add file | verified: cargo test | evidence: tests:strict-goal-e2e",
],
);
let fake_codex = bin.join("codex");
fs::write(
&fake_codex,
"#!/usr/bin/env python3\nprint('VERDICT: REJECT')\nprint('FINDINGS:')\nprint('- fabricated evidence')\n",
)
.unwrap();
make_executable(&fake_codex);
let path = format!(
"{}:{}",
bin.display(),
std::env::var("PATH").unwrap_or_default()
);
Command::cargo_bin("truth-mirror")
.unwrap()
.current_dir(&repo)
.env("PATH", path)
.args([
"--state-dir",
".truth-mirror",
"review",
"HEAD",
"--watched-agent",
"claude",
"--watched-model",
"model-a",
"--reviewer-harness",
"codex",
"--reviewer-model",
"model-b",
"--strict-goal",
"--stop-after-lies",
"1",
"--max-passes",
"5",
])
.assert()
.success()
.stdout(predicate::str::contains("1 pass"))
.stdout(predicate::str::contains("1 lie"))
.stdout(predicate::str::contains("stopped: lies exposed"));
let ledger = fs::read_to_string(repo.join(".truth-mirror/ledger.jsonl")).unwrap();
assert!(ledger.contains("\"verdict\":\"REJECT\""));
}