pub const AC_CLI_VALIDATE_SCORE_THRESHOLD: u32 = 50;
pub const AC_CLI_VALIDATE_LOW_SCORE_EXIT: i32 = 5;
pub const AC_CLI_NETWORK_PREFIXES: &[&str] = &["hf://", "http://", "https://"];
pub const AC_CLI_ENCRYPTED_EXTENSIONS: &[&str] = &[".enc"];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CliSafetyVerdict {
Pass,
Fail,
}
#[must_use]
pub fn verdict_from_validate_exit(score: u32, exit_code: i32) -> CliSafetyVerdict {
if score < AC_CLI_VALIDATE_SCORE_THRESHOLD {
if exit_code == AC_CLI_VALIDATE_LOW_SCORE_EXIT {
CliSafetyVerdict::Pass
} else {
CliSafetyVerdict::Fail
}
} else if exit_code == 0 {
CliSafetyVerdict::Pass
} else {
CliSafetyVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_offline_blocks_network(
offline_flag: bool,
source: &str,
rejected_before_io: bool,
) -> CliSafetyVerdict {
if !offline_flag {
return CliSafetyVerdict::Pass;
}
if source.is_empty() {
return CliSafetyVerdict::Fail;
}
let is_network = AC_CLI_NETWORK_PREFIXES
.iter()
.any(|p| source.starts_with(p));
if is_network && !rejected_before_io {
return CliSafetyVerdict::Fail;
}
if !is_network {
return CliSafetyVerdict::Pass;
}
CliSafetyVerdict::Pass
}
#[must_use]
pub fn verdict_from_encrypt_rejects_enc(
input_path: &str,
encrypt_was_rejected: bool,
) -> CliSafetyVerdict {
if input_path.is_empty() {
return CliSafetyVerdict::Fail;
}
let already_encrypted = AC_CLI_ENCRYPTED_EXTENSIONS
.iter()
.any(|ext| input_path.ends_with(ext));
if already_encrypted && !encrypt_was_rejected {
return CliSafetyVerdict::Fail;
}
CliSafetyVerdict::Pass
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn provenance_constants() {
assert_eq!(AC_CLI_VALIDATE_SCORE_THRESHOLD, 50);
assert_eq!(AC_CLI_VALIDATE_LOW_SCORE_EXIT, 5);
assert_eq!(AC_CLI_NETWORK_PREFIXES, &["hf://", "http://", "https://"]);
assert_eq!(AC_CLI_ENCRYPTED_EXTENSIONS, &[".enc"]);
}
#[test]
fn fcli001_pass_low_score_exits_5() {
let v = verdict_from_validate_exit(3, 5);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli001_pass_high_score_exits_0() {
let v = verdict_from_validate_exit(95, 0);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli001_pass_at_threshold_exits_0() {
let v = verdict_from_validate_exit(50, 0);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli001_fail_low_score_exits_0() {
let v = verdict_from_validate_exit(3, 0);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli001_fail_low_score_exits_other() {
let v = verdict_from_validate_exit(3, 1);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli001_fail_high_score_exits_5() {
let v = verdict_from_validate_exit(95, 5);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli002_pass_offline_hf_rejected() {
let v = verdict_from_offline_blocks_network(true, "hf://test/x", true);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli002_pass_offline_https_rejected() {
let v = verdict_from_offline_blocks_network(true, "https://example.com/x", true);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli002_pass_offline_local_path() {
let v = verdict_from_offline_blocks_network(true, "/tmp/model.gguf", true);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli002_pass_online_no_constraint() {
let v = verdict_from_offline_blocks_network(false, "hf://test/x", false);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli002_fail_offline_hf_not_rejected() {
let v = verdict_from_offline_blocks_network(true, "hf://test/x", false);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli002_fail_empty_source() {
let v = verdict_from_offline_blocks_network(true, "", true);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli003_pass_enc_rejected() {
let v = verdict_from_encrypt_rejects_enc("model.enc", true);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli003_pass_plain_input_unchecked() {
let v = verdict_from_encrypt_rejects_enc("model.apr", false);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn fcli003_fail_enc_not_rejected() {
let v = verdict_from_encrypt_rejects_enc("model.enc", false);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli003_fail_empty_path() {
let v = verdict_from_encrypt_rejects_enc("", true);
assert_eq!(v, CliSafetyVerdict::Fail);
}
#[test]
fn fcli003_pass_path_with_dot_enc_in_dir() {
let v = verdict_from_encrypt_rejects_enc("/foo.enc/model.apr", false);
assert_eq!(v, CliSafetyVerdict::Pass);
}
#[test]
fn mutation_survey_001_score_band() {
for score in [0_u32, 49, 50, 51, 99, 100] {
for exit in [0_i32, 5, 1] {
let v = verdict_from_validate_exit(score, exit);
let expected = if score < 50 {
if exit == 5 {
CliSafetyVerdict::Pass
} else {
CliSafetyVerdict::Fail
}
} else if exit == 0 {
CliSafetyVerdict::Pass
} else {
CliSafetyVerdict::Fail
};
assert_eq!(v, expected, "score={score} exit={exit}");
}
}
}
#[test]
fn mutation_survey_002_network_prefix_band() {
for src in [
"hf://x",
"http://x",
"https://x",
"file:///tmp/x",
"/local/path",
"s3://bucket/x", ] {
let v = verdict_from_offline_blocks_network(true, src, true);
assert_eq!(v, CliSafetyVerdict::Pass, "src={src}");
}
}
#[test]
fn realistic_healthy_passes_all_3() {
let v1 = verdict_from_validate_exit(85, 0);
let v2 = verdict_from_offline_blocks_network(true, "hf://model/x", true);
let v3 = verdict_from_encrypt_rejects_enc("model.enc", true);
assert_eq!(v1, CliSafetyVerdict::Pass);
assert_eq!(v2, CliSafetyVerdict::Pass);
assert_eq!(v3, CliSafetyVerdict::Pass);
}
#[test]
fn realistic_pre_fix_all_3_failures() {
let v1 = verdict_from_validate_exit(3, 0);
let v2 = verdict_from_offline_blocks_network(true, "hf://x", false);
let v3 = verdict_from_encrypt_rejects_enc("model.enc", false);
assert_eq!(v1, CliSafetyVerdict::Fail);
assert_eq!(v2, CliSafetyVerdict::Fail);
assert_eq!(v3, CliSafetyVerdict::Fail);
}
}