use std::sync::OnceLock;
use clap::CommandFactory;
use serde_json::Value;
use crate::Cli;
pub const EXPECTED_ACCEPTED: &str = "accepted";
pub const EXPECTED_ACCEPTED_ALIAS: &str = "ok";
pub const EXPECTED_REJECTED: &str = "rejected";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum QuantizeArgvVerdict {
Accepted,
Rejected { reason: String },
}
impl QuantizeArgvVerdict {
#[must_use]
pub fn label(&self) -> &'static str {
match self {
Self::Accepted => EXPECTED_ACCEPTED,
Self::Rejected { .. } => EXPECTED_REJECTED,
}
}
#[must_use]
pub fn is_accepted(&self) -> bool {
matches!(self, Self::Accepted)
}
}
fn on_big_stack<T: Send + 'static>(f: impl FnOnce() -> T + Send + 'static) -> T {
std::thread::Builder::new()
.stack_size(16 * 1024 * 1024)
.spawn(f)
.expect("spawn shipped-CLI parser thread")
.join()
.expect("shipped-CLI parser thread must not panic")
}
fn normalized_argv(argv: &[&str]) -> Vec<String> {
let mut full = Vec::with_capacity(argv.len() + 2);
full.push("apr".to_string());
if argv.first().copied() != Some("quantize") {
full.push("quantize".to_string());
}
full.extend(argv.iter().map(|s| (*s).to_string()));
full
}
fn clap_reason(e: &clap::Error) -> String {
use clap::error::ErrorKind;
match e.kind() {
ErrorKind::DisplayHelp | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => {
"argv is a help request, not an `apr quantize` invocation".to_string()
}
ErrorKind::DisplayVersion => {
"argv is a version request, not an `apr quantize` invocation".to_string()
}
_ => first_diagnostic_line(&e.to_string()),
}
}
fn first_diagnostic_line(rendered: &str) -> String {
rendered
.lines()
.map(str::trim)
.find(|l| !l.is_empty())
.map(|l| l.trim_start_matches("error:").trim().to_string())
.filter(|l| !l.is_empty())
.unwrap_or_else(|| "refused by the shipped parser".to_string())
}
#[must_use]
pub fn shipped_quantize_verdict(argv: &[&str]) -> QuantizeArgvVerdict {
let owned = normalized_argv(argv);
on_big_stack(move || match Cli::command().try_get_matches_from(&owned) {
Ok(_) => QuantizeArgvVerdict::Accepted,
Err(e) => QuantizeArgvVerdict::Rejected {
reason: clap_reason(&e),
},
})
}
fn arg_value_name(a: &clap::Arg) -> String {
a.get_value_names()
.and_then(<[clap::builder::Str]>::first)
.map_or_else(|| a.get_id().as_str().to_uppercase(), ToString::to_string)
}
fn arg_takes_value(a: &clap::Arg) -> bool {
use clap::ArgAction;
!matches!(
a.get_action(),
ArgAction::SetTrue | ArgAction::SetFalse | ArgAction::Count | ArgAction::Help
)
}
fn render_arg(a: &clap::Arg) -> String {
if a.is_positional() {
return format!("<{}>", arg_value_name(a));
}
let mut s = String::new();
if let Some(l) = a.get_long() {
s.push_str("--");
s.push_str(l);
}
if let Some(c) = a.get_short() {
s.push('/');
s.push('-');
s.push(c);
}
if arg_takes_value(a) {
s.push_str(&format!(" <{}>", arg_value_name(a)));
}
s
}
fn build_quantize_summary() -> String {
let root = Cli::command();
let Some(q) = root.find_subcommand("quantize") else {
return "(the shipped CLI has no `quantize` subcommand)".to_string();
};
let parts: Vec<String> = q
.get_arguments()
.filter(|a| !matches!(a.get_id().as_str(), "help" | "version"))
.map(render_arg)
.collect();
if parts.is_empty() {
return "(no arguments)".to_string();
}
parts.join(" ")
}
#[must_use]
pub fn shipped_quantize_accepts_summary() -> &'static str {
static SUMMARY: OnceLock<String> = OnceLock::new();
SUMMARY.get_or_init(|| on_big_stack(build_quantize_summary))
}
#[derive(Debug, Clone)]
pub struct FlagParityGate {
pub passed: bool,
pub outcome: String,
pub failure: Option<String>,
}
fn read_argv(v: &Value, falsify_id: &str) -> Result<Vec<String>, String> {
let Some(items) = v.get("argv").and_then(Value::as_array) else {
return Err(format!(
"{falsify_id}: flags.argv is missing or is not an array — the gate has no argv to hand the shipped `apr quantize` parser"
));
};
items
.iter()
.map(|s| {
s.as_str().map(ToString::to_string).ok_or_else(|| {
format!("{falsify_id}: flags.argv contains a non-string element ({s})")
})
})
.collect()
}
fn read_expectation(v: &Value, falsify_id: &str) -> Result<bool, String> {
let Some(raw) = v.get("expected_outcome").and_then(Value::as_str) else {
return Err(format!(
"{falsify_id}: flags.expected_outcome is missing — state `{EXPECTED_ACCEPTED}` or `{EXPECTED_REJECTED}`; a gate with an implied expectation asserts nothing"
));
};
match raw {
EXPECTED_ACCEPTED | EXPECTED_ACCEPTED_ALIAS => Ok(true),
EXPECTED_REJECTED => Ok(false),
other => Err(format!(
"{falsify_id}: flags.expected_outcome `{other}` is not a verdict of the shipped `apr quantize` parser. This gate now runs the real clap parser, whose only outcomes are `{EXPECTED_ACCEPTED}` (alias `{EXPECTED_ACCEPTED_ALIAS}`) and `{EXPECTED_REJECTED}`; the per-flag labels this observation was captured with described a parser that never shipped. Re-capture it."
)),
}
}
fn describe_argv(argv: &[String]) -> String {
if argv.is_empty() {
"(empty)".to_string()
} else {
argv.join(" ")
}
}
fn failure_text(expected_accepted: bool, argv: &[String], verdict: &QuantizeArgvVerdict) -> String {
let shown = describe_argv(argv);
let accepts = shipped_quantize_accepts_summary();
match verdict {
QuantizeArgvVerdict::Rejected { reason } => format!(
"the shipped `apr quantize` REJECTED this argv, but the observation expected it to be accepted.\n \
argv: {shown}\n \
shipped parser said: {reason}\n \
`apr quantize` accepts: {accepts}"
),
QuantizeArgvVerdict::Accepted => {
debug_assert!(!expected_accepted, "accepted+expected-accepted is a pass");
format!(
"the shipped `apr quantize` ACCEPTED this argv, but the observation expected it to be rejected.\n \
argv: {shown}\n \
`apr quantize` accepts: {accepts}"
)
}
}
}
pub fn evaluate_flags_observation(v: &Value, falsify_id: &str) -> Result<FlagParityGate, String> {
let argv = read_argv(v, falsify_id)?;
let expected_accepted = read_expectation(v, falsify_id)?;
let borrowed: Vec<&str> = argv.iter().map(String::as_str).collect();
let verdict = shipped_quantize_verdict(&borrowed);
let passed = verdict.is_accepted() == expected_accepted;
let expected_label = if expected_accepted {
EXPECTED_ACCEPTED
} else {
EXPECTED_REJECTED
};
let got = verdict.label();
let outcome = match &verdict {
QuantizeArgvVerdict::Accepted => {
format!("expected={expected_label} got={got} (shipped `apr quantize` parser)")
}
QuantizeArgvVerdict::Rejected { reason } => {
format!("expected={expected_label} got={got} (shipped `apr quantize` parser: {reason})")
}
};
let failure = if passed {
None
} else {
Some(failure_text(expected_accepted, &argv, &verdict))
};
Ok(FlagParityGate {
passed,
outcome,
failure,
})
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn shipped_parser_rejects_the_flags_the_hand_rolled_parser_accepted() {
let v =
shipped_quantize_verdict(&["--method", "gptq", "--bits", "4", "--group-size", "128"]);
let QuantizeArgvVerdict::Rejected { reason } = v else {
panic!("shipped `apr quantize` must REFUSE --method/--bits/--group-size, got: {v:?}");
};
assert!(
reason.contains("--method"),
"the refusal must name the flag that does not exist; got: {reason}"
);
}
#[test]
fn shipped_parser_rejects_the_awq_argv_the_hand_rolled_parser_accepted() {
let v = shipped_quantize_verdict(&["--method=awq", "--bits=4"]);
assert!(
!v.is_accepted(),
"shipped `apr quantize` must REFUSE --method=awq --bits=4, got: {v:?}"
);
}
#[test]
fn shipped_parser_accepts_a_real_quantize_invocation() {
let v =
shipped_quantize_verdict(&["model.safetensors", "--scheme", "int4", "-o", "out.apr"]);
assert_eq!(
v,
QuantizeArgvVerdict::Accepted,
"a real `apr quantize <FILE> --scheme int4 -o out.apr` must be accepted"
);
}
#[test]
fn shipped_parser_accepts_the_long_form_and_the_plan_flag() {
assert_eq!(
shipped_quantize_verdict(&["m.apr", "--scheme", "q4k", "--plan"]),
QuantizeArgvVerdict::Accepted
);
assert_eq!(
shipped_quantize_verdict(&[
"m.apr", "--output", "o.apr", "--format", "gguf", "--force"
]),
QuantizeArgvVerdict::Accepted
);
}
#[test]
fn a_leading_literal_quantize_is_not_double_prefixed() {
assert_eq!(
shipped_quantize_verdict(&["quantize", "m.apr", "--scheme", "int8"]),
QuantizeArgvVerdict::Accepted
);
}
#[test]
fn shipped_parser_refuses_quantize_without_the_required_file() {
let v = shipped_quantize_verdict(&["--scheme", "int4"]);
assert!(
!v.is_accepted(),
"`apr quantize --scheme int4` omits the required <FILE>; got: {v:?}"
);
}
#[test]
fn shipped_parser_refuses_an_unknown_flag() {
let v = shipped_quantize_verdict(&["m.apr", "--totally-made-up"]);
assert!(!v.is_accepted(), "unknown flag must be refused; got: {v:?}");
}
#[test]
fn verdict_labels_are_the_observation_vocabulary() {
assert_eq!(QuantizeArgvVerdict::Accepted.label(), "accepted");
assert_eq!(
QuantizeArgvVerdict::Rejected { reason: "x".into() }.label(),
"rejected"
);
}
#[test]
fn accepts_summary_names_the_real_quantize_surface() {
let s = shipped_quantize_accepts_summary();
for expected in [
"<FILE>", "--scheme", "--output", "--format", "--batch", "--plan", "--force",
] {
assert!(
s.contains(expected),
"summary must name {expected}; got: {s}"
);
}
}
#[test]
fn accepts_summary_never_advertises_the_flags_that_do_not_exist() {
let s = shipped_quantize_accepts_summary();
for absent in ["--method", "--bits", "--group-size"] {
assert!(
!s.contains(absent),
"summary must not advertise {absent}, which `apr quantize` does not take; got: {s}"
);
}
}
#[test]
fn gate_fails_when_observation_expects_the_nonexistent_flags_to_be_accepted() {
let obs = json!({
"argv": ["--method", "gptq", "--bits", "4", "--group-size", "128"],
"expected_outcome": "ok"
});
let gate = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("observation is usable");
assert!(
!gate.passed,
"gate must fail: the shipped parser refuses this argv; outcome={}",
gate.outcome
);
let msg = gate.failure.expect("a failed gate must explain itself");
assert!(msg.contains("REJECTED"), "got: {msg}");
assert!(
msg.contains("--scheme"),
"the failure must name the flags `apr quantize` does accept; got: {msg}"
);
}
#[test]
fn gate_passes_when_observation_expects_a_real_invocation_to_be_accepted() {
let obs = json!({
"argv": ["model.safetensors", "--scheme", "int4", "-o", "out.apr"],
"expected_outcome": "accepted"
});
let gate = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("observation is usable");
assert!(gate.passed, "outcome={}", gate.outcome);
assert!(gate.failure.is_none());
}
#[test]
fn gate_passes_when_observation_expects_the_nonexistent_flags_to_be_rejected() {
let obs = json!({
"argv": ["--method", "awq", "--bits", "4"],
"expected_outcome": "rejected"
});
let gate = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("observation is usable");
assert!(gate.passed, "outcome={}", gate.outcome);
}
#[test]
fn gate_fails_when_observation_expects_a_real_invocation_to_be_rejected() {
let obs = json!({
"argv": ["m.apr", "--scheme", "int4", "-o", "o.apr"],
"expected_outcome": "rejected"
});
let gate = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("observation is usable");
assert!(!gate.passed, "outcome={}", gate.outcome);
let msg = gate.failure.expect("a failed gate must explain itself");
assert!(msg.contains("ACCEPTED"), "got: {msg}");
}
#[test]
fn a_stale_per_flag_label_is_refused_as_unusable_not_folded_into_rejected() {
let obs = json!({ "argv": ["--method", "gptq"], "expected_outcome": "missing_bits" });
let err = evaluate_flags_observation(&obs, "FALSIFY-TEST")
.expect_err("a label the real parser cannot produce must be refused");
assert!(err.contains("missing_bits"), "got: {err}");
assert!(err.contains("Re-capture it"), "got: {err}");
}
#[test]
fn a_missing_expectation_is_refused_rather_than_defaulted() {
let obs = json!({ "argv": ["m.apr", "--scheme", "int4", "-o", "o.apr"] });
let err = evaluate_flags_observation(&obs, "FALSIFY-TEST")
.expect_err("an implied expectation asserts nothing");
assert!(err.contains("expected_outcome is missing"), "got: {err}");
}
#[test]
fn a_missing_argv_is_refused_rather_than_treated_as_empty() {
let obs = json!({ "expected_outcome": "accepted" });
let err = evaluate_flags_observation(&obs, "FALSIFY-TEST")
.expect_err("no argv means nothing was captured");
assert!(err.contains("flags.argv is missing"), "got: {err}");
}
#[test]
fn a_non_string_argv_element_is_refused() {
let obs = json!({ "argv": ["m.apr", 4], "expected_outcome": "accepted" });
let err =
evaluate_flags_observation(&obs, "FALSIFY-TEST").expect_err("argv must be strings");
assert!(err.contains("non-string element"), "got: {err}");
}
#[test]
fn the_gate_is_deterministic() {
let obs = json!({
"argv": ["--method", "gptq", "--bits", "4"],
"expected_outcome": "ok"
});
let a = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("usable");
let b = evaluate_flags_observation(&obs, "FALSIFY-TEST").expect("usable");
assert_eq!(a.passed, b.passed);
assert_eq!(a.outcome, b.outcome);
}
}