truth-mirror 0.1.0

Truthfulness gate and adversarial reviewer harness for AI coding agents.
Documentation
use assert_cmd::Command;

fn help_text(args: &[&str]) -> String {
    let output = Command::cargo_bin("truth-mirror")
        .unwrap()
        .args(args)
        .assert()
        .success()
        .get_output()
        .stdout
        .clone();

    String::from_utf8(output).unwrap()
}

#[test]
fn root_help_exposes_brief_defined_surface() {
    let help = help_text(&["--help"]);

    for expected in [
        "install-hooks",
        "review",
        "gate",
        "reinject",
        "ledger",
        "watch",
    ] {
        assert!(
            help.contains(expected),
            "missing {expected} in help:\n{help}"
        );
    }
}

#[test]
fn install_hooks_help_exposes_agent_and_lifecycle_flags() {
    let help = help_text(&["install-hooks", "--help"]);

    for expected in ["--claude", "--codex", "--pi", "--uninstall", "--dry-run"] {
        assert!(
            help.contains(expected),
            "missing {expected} in help:\n{help}"
        );
    }
}

#[test]
fn review_help_exposes_model_opposition_and_strict_mode_flags() {
    let help = help_text(&["review", "--help"]);

    for expected in [
        "--staged",
        "--watched-agent",
        "--reviewer-harness",
        "--watched-model",
        "--reviewer-model",
        "--allow-same-model",
        "--strict-two-pass",
    ] {
        assert!(
            help.contains(expected),
            "missing {expected} in help:\n{help}"
        );
    }
}

#[test]
fn gate_help_exposes_pre_push_range() {
    let help = help_text(&["gate", "--help"]);

    assert!(
        help.contains("--pre-push"),
        "missing --pre-push in help:\n{help}"
    );
    assert!(
        help.contains("--commit-msg"),
        "missing --commit-msg in help:\n{help}"
    );
    assert!(
        help.contains("--claim-file"),
        "missing --claim-file in help:\n{help}"
    );
    assert!(
        help.contains("--diff-file"),
        "missing --diff-file in help:\n{help}"
    );
    assert!(
        help.contains("RANGE"),
        "missing RANGE value name in help:\n{help}"
    );
}

#[test]
fn reinject_help_requires_agent_selection() {
    let help = help_text(&["reinject", "--help"]);

    assert!(help.contains("--agent"), "missing --agent in help:\n{help}");
    for expected in ["claude", "codex", "pi"] {
        assert!(
            help.contains(expected),
            "missing {expected} in help:\n{help}"
        );
    }
}

#[test]
fn ledger_help_exposes_all_required_subcommands() {
    let help = help_text(&["ledger", "--help"]);

    for expected in ["list", "show", "resolve", "waive", "stats"] {
        assert!(
            help.contains(expected),
            "missing {expected} in help:\n{help}"
        );
    }
}