use agi4_core::conjunct::ConjunctStatus;
use agi4_core::consistency::consistency_check;
use agi4_core::evaluators::{
evaluate_autonomous_agency, evaluate_economic_substitutability,
evaluate_environmental_transfer, evaluate_generality,
};
use agi4_core::evidence::Evidence;
use agi4_schema::{
ConjunctReport, ConjunctsOutput, ConsistencyCheckOutput, EvidenceReport, ModelMetadata,
VerdictOutput,
};
use chrono::Utc;
fn status_to_string(status: ConjunctStatus) -> String {
format!("{:?}", status).to_lowercase()
}
pub fn attest_live(model_id: &str) -> Result<VerdictOutput, Box<dyn std::error::Error>> {
eprintln!("Starting live attestation for model: {}", model_id);
eprintln!("HTTP fetcher: timeout=30s, retries=3");
eprintln!("Filesystem cache: ~/.cache/agi4/, 24-hour TTL");
let now = Utc::now();
let run_timestamp = now.to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
let all_evidence: Vec<Evidence> = Vec::new();
let evidence_reports: Vec<EvidenceReport> = Vec::new();
let generality_status = evaluate_generality(&all_evidence);
let econ_status = evaluate_economic_substitutability(&all_evidence);
let env_status = evaluate_environmental_transfer(&all_evidence);
let agency_status = evaluate_autonomous_agency(&all_evidence);
let conjunct_statuses = [generality_status, econ_status, env_status, agency_status];
let consistency_result = consistency_check(&all_evidence, &conjunct_statuses);
let overall_verdict = if conjunct_statuses.iter().all(|s| *s == ConjunctStatus::Pass)
&& consistency_result.passed
{
"attested"
} else {
"not_attested"
};
let mut generality_evidence = Vec::new();
let mut econ_evidence = Vec::new();
let mut env_evidence = Vec::new();
let mut agency_evidence = Vec::new();
for report in evidence_reports {
match report.source.as_str() {
"arc-agi-2" | "hle" | "gpqa-diamond" => generality_evidence.push(report),
"gdpval" | "gdpval-aa" | "rli" | "apex-agents" => econ_evidence.push(report),
"arc-agi-3" => {
generality_evidence.push(report.clone());
env_evidence.push(report);
}
"osworld" | "nes" => env_evidence.push(report),
"metr-80pct-time-horizon" | "re-bench" | "swe-bench-verified" => {
agency_evidence.push(report)
}
_ => {} }
}
let verdict_reasons = vec![
format!("Generality: {}", status_to_string(generality_status)),
format!(
"Economic Substitutability: {}",
status_to_string(econ_status)
),
format!("Environmental Transfer: {}", status_to_string(env_status)),
format!("Autonomous Agency: {}", status_to_string(agency_status)),
format!(
"Consistency Check: {}",
if consistency_result.passed {
"pass"
} else {
"fail"
}
),
];
let verdict_output = VerdictOutput {
spec_version: crate::SPEC_VERSION.to_string(),
runner_version: crate::VERSION.to_string(),
run_timestamp,
model: ModelMetadata {
id: model_id.to_string(),
provider: None,
version_or_date: None,
},
conjuncts: ConjunctsOutput {
generality: ConjunctReport {
status: status_to_string(generality_status),
evidence: generality_evidence,
margins: None,
},
economic_substitutability: ConjunctReport {
status: status_to_string(econ_status),
evidence: econ_evidence,
margins: None,
},
environmental_transfer: ConjunctReport {
status: status_to_string(env_status),
evidence: env_evidence,
margins: None,
},
autonomous_agency: ConjunctReport {
status: status_to_string(agency_status),
evidence: agency_evidence,
margins: None,
},
},
consistency_check: ConsistencyCheckOutput {
status: if consistency_result.passed {
"pass"
} else {
"fail"
}
.to_string(),
failed_rules: consistency_result.failed_rules,
detail: consistency_result.detail,
},
verdict: overall_verdict.to_string(),
verdict_reasons,
known_gaps_acknowledged: vec![
"NES (Novel-Environment Subset) underspecified; accepting evidence but not evaluating"
.to_string(),
],
};
eprintln!("Verdict: {} ({})", verdict_output.verdict, model_id);
Ok(verdict_output)
}