use crate::pipeline::{certificate_track_for_op, CertificateTrack};
use crate::spec::law::LawViolation;
use crate::spec::types::{OpSpec, ParityFailure, Strictness};
use serde::Serialize;
#[cfg(test)]
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
use super::engine::run_engine_harnesses;
use super::hash::compute_registry_hash;
use super::ops::certify_op;
use super::track::{build_track, coverage_for, optional_track, unsupported_ops};
pub(crate) const MAX_RECORDED_PARITY_FAILURES: usize = 16;
static CERTIFICATE_SEQUENCE: AtomicU64 = AtomicU64::new(0);
#[cfg(test)]
thread_local! {
static TEST_MUTATION_CATALOG: RefCell<Option<Vec<crate::adversarial::mutations::catalog::Mutation>>> =
const { RefCell::new(None) };
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Violation {
pub(crate) op_id: String,
pub(crate) law: String,
pub(crate) backend: String,
pub(crate) reference_output: Vec<u8>,
pub(crate) backend_output: Vec<u8>,
pub(crate) message: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
pub enum CertificateStrength {
FastCheck,
#[default]
Standard,
Legendary,
}
impl CertificateStrength {
#[must_use]
pub const fn witness_count(self) -> u64 {
match self {
Self::FastCheck => 10_000,
Self::Standard => 1_000_000,
Self::Legendary => 100_000_000,
}
}
#[must_use]
pub const fn can_claim_conformance(self) -> bool {
!matches!(self, Self::FastCheck)
}
}
#[derive(Debug, Clone, Serialize)]
pub struct Certificate {
pub(crate) backend_name: String,
pub(crate) backend_version: String,
pub(crate) spec_version: u32,
pub(crate) level: CertificateLevels,
pub(crate) timestamp: String,
pub(crate) monotonic_sequence: u64,
pub(crate) certificate_hash: [u8; 32],
pub(crate) strength: CertificateStrength,
pub(crate) witness_count: u64,
pub(crate) witness_count_by_op: BTreeMap<String, u64>,
pub(crate) proof_status: String,
pub(crate) integer_track: TrackReport,
pub(crate) float_track: Option<TrackReport>,
pub(crate) approximate_track: Option<TrackReport>,
pub(crate) ops: Vec<OpResult>,
pub(crate) unsupported_ops: Vec<String>,
pub(crate) engines: Vec<EngineResult>,
pub(crate) registry_hash: [u8; 32],
pub(crate) coverage: CoverageMetrics,
}
#[derive(Debug, Clone, Serialize)]
pub struct TrackReport {
pub(crate) level: Option<ConformanceLevel>,
pub(crate) ops: Vec<OpResult>,
pub(crate) unsupported_ops: Vec<String>,
pub(crate) coverage: CoverageMetrics,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum OpOutcome {
Passed,
Failed,
Pending,
Unsupported,
}
#[derive(Debug, Clone, Serialize)]
pub struct OpResult {
pub(crate) id: String,
pub(crate) archetype: String,
pub(crate) outcome: OpOutcome,
pub(crate) parity_passed: bool,
pub(crate) laws_verified: Vec<String>,
pub(crate) laws_failed: Vec<LawViolation>,
pub(crate) parity_failures: Vec<ParityFailure>,
pub(crate) cases_tested: u64,
pub(crate) witness_count: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct EngineResult {
pub(crate) id: String,
pub(crate) status: EngineStatus,
pub(crate) invariants_verified: Vec<String>,
pub(crate) invariants_failed: Vec<String>,
pub(crate) cases_tested: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum EngineStatus {
Pass,
Fail,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct CoverageMetrics {
pub ops_total: u64,
pub ops_parity_passed: u64,
pub ops_unsupported: u64,
pub ops_laws_passed: u64,
pub laws_total: u64,
pub laws_passed: u64,
pub equivalence_classes_total: u64,
pub boundary_values_total: u64,
pub cases_tested: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum ConformanceLevel {
L1,
L2,
L1f,
L2f,
L1a,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub struct CertificateLevels {
pub integer: Option<ConformanceLevel>,
pub float: Option<ConformanceLevel>,
pub approximate: Option<ConformanceLevel>,
}
pub(crate) struct ParitySummary {
pub(super) cases_tested: u64,
pub(super) failures: Vec<ParityFailure>,
pub(super) unsupported: bool,
}
#[inline]
pub fn certify(
backend: &dyn vyre::VyreBackend,
specs: &[OpSpec],
strength: CertificateStrength,
) -> Result<Certificate, String> {
if specs.is_empty() {
return Err("Fix: certify requires at least one OpSpec, got empty list.".to_string());
}
run_layer4_mutation_gate()?;
reject_duplicate_or_mixed_specs(specs)?;
let mut routed_ops = Vec::with_capacity(specs.len());
for spec in specs {
routed_ops.push((
certificate_track_for_op(spec),
spec,
certify_op(backend, spec, strength),
));
}
let mut integer_track = build_track(
&routed_ops,
CertificateTrack::Integer,
ConformanceLevel::L1,
ConformanceLevel::L2,
);
let mut float_track = optional_track(
&routed_ops,
CertificateTrack::Float,
ConformanceLevel::L1f,
ConformanceLevel::L2f,
);
let mut approximate_track = optional_track(
&routed_ops,
CertificateTrack::Approximate,
ConformanceLevel::L1a,
ConformanceLevel::L1a,
);
if !strength.can_claim_conformance() {
integer_track.level = None;
if let Some(track) = &mut float_track {
track.level = None;
}
if let Some(track) = &mut approximate_track {
track.level = None;
}
}
let ops: Vec<_> = routed_ops
.iter()
.map(|(_, _, op_result)| op_result.clone())
.collect();
let unsupported_ops = unsupported_ops(&ops);
let coverage = coverage_for(specs, &ops);
let engines = run_engine_harnesses(backend, specs);
let all_engines_passed = engines
.iter()
.all(|engine| engine.status == EngineStatus::Pass);
let escaped_defendant_ids: Vec<String> = if matches!(
strength,
CertificateStrength::Standard | CertificateStrength::Legendary
) {
let report = crate::adversarial::run_gauntlet(&crate::adversarial::full_catalog(), specs);
report
.escaped()
.into_iter()
.map(|finding| finding.defendant_id.clone())
.collect()
} else {
Vec::new()
};
if !escaped_defendant_ids.is_empty() {
return Err(format!(
"Cat-C: layer5_adversarial gate failed; escaped defendant(s): {}",
escaped_defendant_ids.join(", ")
));
}
let level = if strength.can_claim_conformance() && all_engines_passed {
CertificateLevels {
integer: integer_track.level,
float: float_track.as_ref().and_then(|track| track.level),
approximate: approximate_track.as_ref().and_then(|track| track.level),
}
} else {
CertificateLevels {
integer: None,
float: None,
approximate: None,
}
};
let registry_hash = compute_registry_hash(specs);
let timestamp = certificate_timestamp()?;
let monotonic_sequence = next_certificate_sequence();
let witness_count = strength.witness_count();
let witness_count_by_op = ops
.iter()
.map(|op| (op.id.clone(), op.witness_count))
.collect();
let proof_status = proof_status(strength).to_string();
Ok(Certificate::new(
backend.id().to_string(),
"unspecified".to_string(),
specs
.iter()
.map(|spec| spec.version)
.max()
.unwrap_or_default(),
level,
timestamp,
monotonic_sequence,
strength,
witness_count,
witness_count_by_op,
proof_status,
integer_track,
float_track,
approximate_track,
ops,
unsupported_ops,
engines,
registry_hash,
coverage,
))
}
fn certificate_timestamp() -> Result<String, String> {
let elapsed = SystemTime::now().duration_since(UNIX_EPOCH).map_err(|err| {
format!(
"Fix: system clock is before the Unix epoch, cannot issue a conformance certificate: {err}"
)
})?;
Ok(format!("unix:{}", elapsed.as_secs()))
}
fn next_certificate_sequence() -> u64 {
CERTIFICATE_SEQUENCE.fetch_add(1, Ordering::SeqCst)
}
fn run_layer4_mutation_gate() -> Result<(), String> {
let catalog = mutation_catalog_for_certify();
crate::enforce::enforcers::layer4_mutation_gate::validate_catalog(&catalog).map_err(
|messages| {
format!(
"Cat-C: layer4_mutation_gate failed and certificate emission is blocked.\n{}",
messages
.into_iter()
.map(|message| format!("Fix: {message}"))
.collect::<Vec<_>>()
.join("\n")
)
},
)
}
fn mutation_catalog_for_certify() -> Vec<crate::adversarial::mutations::catalog::Mutation> {
#[cfg(test)]
{
if let Some(catalog) = TEST_MUTATION_CATALOG.with(|catalog| catalog.borrow().clone()) {
return catalog;
}
}
crate::adversarial::mutations::catalog::MUTATION_CATALOG.to_vec()
}
#[cfg(test)]
pub(crate) fn with_test_mutation_catalog<T>(
catalog: Vec<crate::adversarial::mutations::catalog::Mutation>,
f: impl FnOnce() -> T,
) -> T {
TEST_MUTATION_CATALOG.with(|slot| *slot.borrow_mut() = Some(catalog));
let output = f();
TEST_MUTATION_CATALOG.with(|slot| *slot.borrow_mut() = None);
output
}
fn reject_duplicate_or_mixed_specs(specs: &[OpSpec]) -> Result<(), String> {
let mut seen = BTreeMap::new();
for spec in specs {
let is_approximate = matches!(spec.strictness, Strictness::Approximate { .. });
if let Some(previous_is_approximate) = seen.insert(spec.id, is_approximate) {
if previous_is_approximate != is_approximate {
return Err(format!(
"Fix: op {} declared Strict AND Approximate. Split into two spec entries with different ids.",
spec.id
));
}
return Err(format!(
"Fix: duplicate op id {} in certificate input. Register every operation exactly once.",
spec.id
));
}
}
Ok(())
}
fn proof_status(strength: CertificateStrength) -> &'static str {
match strength {
CertificateStrength::FastCheck => "EXPLORATORY -- NOT A PROOF",
CertificateStrength::Standard | CertificateStrength::Legendary => "CONFORMANCE PROOF",
}
}