pub const AC_CONV_002_TYPE_D_FLOOR: f32 = 0.30;
pub const AC_CONV_004_MAX_VARIANT_SHARE: f32 = 0.20;
pub const AC_CONV_005_HONESTY_PHRASE_1: &str = "not a replacement";
pub const AC_CONV_005_HONESTY_PHRASE_2: &str = "pattern matching";
pub const AC_CONV_001_ROLE_SYSTEM: &str = "system";
pub const AC_CONV_001_ROLE_USER: &str = "user";
pub const AC_CONV_001_ROLE_ASSISTANT: &str = "assistant";
pub const AC_CONV_001_TURN_COUNT: usize = 3;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConvVerdict {
Pass,
Fail,
}
#[derive(Debug, Clone)]
pub struct Turn {
pub role: String,
pub content: String,
}
#[derive(Debug, Clone)]
pub struct Conversation {
pub turns: Vec<Turn>,
}
#[must_use]
pub fn verdict_from_chatml_structure(conversations: &[Conversation]) -> ConvVerdict {
if conversations.is_empty() {
return ConvVerdict::Fail;
}
for c in conversations {
if c.turns.len() != AC_CONV_001_TURN_COUNT {
return ConvVerdict::Fail;
}
if c.turns[0].role != AC_CONV_001_ROLE_SYSTEM {
return ConvVerdict::Fail;
}
if c.turns[1].role != AC_CONV_001_ROLE_USER {
return ConvVerdict::Fail;
}
if c.turns[2].role != AC_CONV_001_ROLE_ASSISTANT {
return ConvVerdict::Fail;
}
}
ConvVerdict::Pass
}
#[must_use]
pub fn verdict_from_type_d_threshold(type_labels: &[&str]) -> ConvVerdict {
if type_labels.is_empty() {
return ConvVerdict::Fail;
}
let total = type_labels.len() as f32;
let count_d = type_labels.iter().filter(|&&t| t == "D").count() as f32;
let frac = count_d / total;
if frac >= AC_CONV_002_TYPE_D_FLOOR {
ConvVerdict::Pass
} else {
ConvVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_no_empty_responses(conversations: &[Conversation]) -> ConvVerdict {
if conversations.is_empty() {
return ConvVerdict::Fail;
}
for c in conversations {
for t in &c.turns {
if t.content.trim().is_empty() {
return ConvVerdict::Fail;
}
}
}
ConvVerdict::Pass
}
#[must_use]
pub fn verdict_from_variant_diversity(variant_ids: &[u32]) -> ConvVerdict {
if variant_ids.is_empty() {
return ConvVerdict::Fail;
}
let total = variant_ids.len() as f32;
let mut counts = std::collections::HashMap::<u32, usize>::new();
for &id in variant_ids {
*counts.entry(id).or_insert(0) += 1;
}
for &c in counts.values() {
let share = c as f32 / total;
if share > AC_CONV_004_MAX_VARIANT_SHARE {
return ConvVerdict::Fail;
}
}
ConvVerdict::Pass
}
#[must_use]
pub fn verdict_from_system_prompt_honesty(system_prompt: &str) -> ConvVerdict {
if !system_prompt.contains(AC_CONV_005_HONESTY_PHRASE_1) {
return ConvVerdict::Fail;
}
if !system_prompt.contains(AC_CONV_005_HONESTY_PHRASE_2) {
return ConvVerdict::Fail;
}
ConvVerdict::Pass
}
#[cfg(test)]
mod tests {
use super::*;
fn make_conv(roles: &[&str], contents: &[&str]) -> Conversation {
Conversation {
turns: roles
.iter()
.zip(contents.iter())
.map(|(r, c)| Turn {
role: r.to_string(),
content: c.to_string(),
})
.collect(),
}
}
fn canonical_conv() -> Conversation {
make_conv(
&["system", "user", "assistant"],
&[
"You are a code analyst — not a replacement, just pattern matching.",
"Is `rm -rf /` safe?",
"No, that command is unsafe.",
],
)
}
#[test]
fn provenance_type_d_floor_30() {
assert_eq!(AC_CONV_002_TYPE_D_FLOOR, 0.30);
}
#[test]
fn provenance_max_variant_share_20() {
assert_eq!(AC_CONV_004_MAX_VARIANT_SHARE, 0.20);
}
#[test]
fn provenance_turn_count_3() {
assert_eq!(AC_CONV_001_TURN_COUNT, 3);
}
#[test]
fn provenance_role_strings() {
assert_eq!(AC_CONV_001_ROLE_SYSTEM, "system");
assert_eq!(AC_CONV_001_ROLE_USER, "user");
assert_eq!(AC_CONV_001_ROLE_ASSISTANT, "assistant");
}
#[test]
fn provenance_honesty_phrases() {
assert_eq!(AC_CONV_005_HONESTY_PHRASE_1, "not a replacement");
assert_eq!(AC_CONV_005_HONESTY_PHRASE_2, "pattern matching");
}
#[test]
fn conv001_pass_canonical_conversation() {
let convs = vec![canonical_conv()];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Pass);
}
#[test]
fn conv001_pass_multiple_canonical() {
let convs = vec![canonical_conv(), canonical_conv(), canonical_conv()];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Pass);
}
#[test]
fn conv001_fail_two_turns_only() {
let convs = vec![make_conv(&["system", "user"], &["sys", "ask"])];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv001_fail_four_turns() {
let convs = vec![make_conv(
&["system", "user", "assistant", "user"],
&["sys", "ask", "ans", "follow"],
)];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv001_fail_wrong_first_role() {
let convs = vec![make_conv(
&["user", "system", "assistant"],
&["a", "b", "c"],
)];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv001_fail_swapped_user_assistant() {
let convs = vec![make_conv(
&["system", "assistant", "user"],
&["a", "b", "c"],
)];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv001_fail_empty_batch() {
let convs: Vec<Conversation> = vec![];
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv001_fail_one_corrupt_in_batch() {
let mut convs = vec![canonical_conv(), canonical_conv()];
convs[1].turns.pop(); assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Fail);
}
#[test]
fn conv002_pass_at_threshold() {
let labels = vec!["A", "B", "C", "D", "D", "D", "A", "B", "C", "A"];
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Pass);
}
#[test]
fn conv002_pass_well_above() {
let labels = vec!["D", "D", "D", "D", "A", "B"];
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Pass);
}
#[test]
fn conv002_fail_below_threshold() {
let labels = vec!["A", "B", "C", "D", "D", "A", "B", "C", "A", "B"];
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Fail);
}
#[test]
fn conv002_fail_zero_d() {
let labels = vec!["A", "B", "C", "A"];
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Fail);
}
#[test]
fn conv002_fail_empty() {
let labels: Vec<&str> = vec![];
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Fail);
}
#[test]
fn conv003_pass_full_responses() {
let convs = vec![canonical_conv()];
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Pass);
}
#[test]
fn conv003_fail_empty_assistant_response() {
let convs = vec![make_conv(
&["system", "user", "assistant"],
&["sys", "ask", ""],
)];
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Fail);
}
#[test]
fn conv003_fail_whitespace_only_response() {
let convs = vec![make_conv(
&["system", "user", "assistant"],
&["sys", "ask", " \n\t "],
)];
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Fail);
}
#[test]
fn conv003_fail_empty_in_one_of_many() {
let mut convs = vec![canonical_conv(), canonical_conv()];
convs[1].turns[2].content = String::new();
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Fail);
}
#[test]
fn conv003_fail_empty_batch() {
let convs: Vec<Conversation> = vec![];
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Fail);
}
#[test]
fn conv004_pass_uniform_distribution() {
let mut variants = Vec::new();
for v in 0..12_u32 {
for _ in 0..5 {
variants.push(v); }
}
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Pass);
}
#[test]
fn conv004_pass_mild_skew() {
let variants = vec![0_u32, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6];
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Pass);
}
#[test]
fn conv004_fail_one_variant_dominant() {
let mut variants = vec![0_u32; 6];
variants.extend(vec![1_u32, 2, 3, 4]);
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Fail);
}
#[test]
fn conv004_fail_just_above_20() {
let variants = vec![0_u32, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Fail);
}
#[test]
fn conv004_fail_empty() {
let variants: Vec<u32> = vec![];
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Fail);
}
#[test]
fn conv005_pass_contains_both_phrases() {
let prompt = "I am a code analyst — not a replacement for human review, \
and I work via pattern matching against known unsafe constructs.";
assert_eq!(
verdict_from_system_prompt_honesty(prompt),
ConvVerdict::Pass
);
}
#[test]
fn conv005_fail_missing_phrase_1() {
let prompt = "I work via pattern matching only.";
assert_eq!(
verdict_from_system_prompt_honesty(prompt),
ConvVerdict::Fail
);
}
#[test]
fn conv005_fail_missing_phrase_2() {
let prompt = "I am not a replacement for code review.";
assert_eq!(
verdict_from_system_prompt_honesty(prompt),
ConvVerdict::Fail
);
}
#[test]
fn conv005_fail_neither_phrase() {
let prompt = "Hello, I'm a coding assistant.";
assert_eq!(
verdict_from_system_prompt_honesty(prompt),
ConvVerdict::Fail
);
}
#[test]
fn conv005_fail_empty_prompt() {
assert_eq!(
verdict_from_system_prompt_honesty(""),
ConvVerdict::Fail
);
}
#[test]
fn sweep_type_d_pct_around_threshold() {
for d_count in [29_usize, 30, 31, 50, 99] {
let mut labels = vec!["D"; d_count];
for _ in 0..(100 - d_count) {
labels.push("A");
}
let v = verdict_from_type_d_threshold(&labels);
let expected = if d_count >= 30 {
ConvVerdict::Pass
} else {
ConvVerdict::Fail
};
assert_eq!(v, expected, "d_count={d_count}");
}
}
#[test]
fn realistic_full_ssc_batch_passes_all_gates() {
let prompt = "Code analyst — not a replacement for review; uses pattern matching.";
let convs: Vec<Conversation> = (0..10)
.map(|i| {
make_conv(
&["system", "user", "assistant"],
&[
prompt,
&format!("Is `rm -rf /tmp/{}` safe?", i),
if i < 4 {
"Type D — confirmed safe."
} else {
"Type A — security concern."
},
],
)
})
.collect();
let labels: Vec<&str> = (0..10)
.map(|i| if i < 4 { "D" } else { "A" })
.collect();
let variants: Vec<u32> = (0..10).map(|i| (i as u32) % 12).collect();
assert_eq!(verdict_from_chatml_structure(&convs), ConvVerdict::Pass);
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Pass);
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Pass);
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Pass);
assert_eq!(
verdict_from_system_prompt_honesty(prompt),
ConvVerdict::Pass
);
}
#[test]
fn realistic_classification_bug_caught() {
let labels = vec!["A"; 9].into_iter().chain(vec!["D"; 1]).collect::<Vec<_>>();
assert_eq!(verdict_from_type_d_threshold(&labels), ConvVerdict::Fail);
}
#[test]
fn realistic_template_render_empty_caught() {
let convs = vec![make_conv(
&["system", "user", "assistant"],
&["sys", "ask", ""], )];
assert_eq!(verdict_from_no_empty_responses(&convs), ConvVerdict::Fail);
}
#[test]
fn realistic_seed_modular_clustering_caught() {
let mut variants = Vec::new();
for _ in 0..30 {
variants.push(0_u32);
}
for _ in 0..30 {
variants.push(1);
}
for _ in 0..40 {
variants.push(2);
}
assert_eq!(verdict_from_variant_diversity(&variants), ConvVerdict::Fail);
}
}