use crate::integrations::WpmVerdict;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum OracleVerdict {
Admit = 0,
Suggest = 1,
Warn = 2,
Fail = 3,
}
#[derive(Debug, Clone)]
pub struct OracleGateVerdict {
pub verdict: OracleVerdict,
pub reason: String,
pub evidence_refs: Vec<String>,
pub source: String,
}
#[derive(Debug, Clone, Default)]
pub struct VerdictSummary {
pub total: usize,
pub admits: usize,
pub suggests: usize,
pub warns: usize,
pub fails: usize,
}
#[derive(Debug, Clone, Default)]
pub struct EvidenceGate {
verdicts: Vec<OracleGateVerdict>,
}
#[derive(Debug, Clone)]
pub struct GateReport {
pub highest_verdict: Option<OracleVerdict>,
pub oracle_verdict: Option<WpmVerdict>,
pub is_blocked: bool,
pub summary: VerdictSummary,
}
impl EvidenceGate {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, verdict: OracleGateVerdict) {
self.verdicts.push(verdict);
}
pub fn verdicts(&self) -> &[OracleGateVerdict] {
&self.verdicts
}
pub fn highest_verdict(&self) -> Option<OracleVerdict> {
self.verdicts.iter().map(|v| v.verdict).max()
}
pub fn to_report(&self, oracle_verdict: Option<WpmVerdict>) -> GateReport {
let mut summary = VerdictSummary { total: self.verdicts.len(), ..Default::default() };
for v in &self.verdicts {
match v.verdict {
OracleVerdict::Admit => summary.admits += 1,
OracleVerdict::Suggest => summary.suggests += 1,
OracleVerdict::Warn => summary.warns += 1,
OracleVerdict::Fail => summary.fails += 1,
}
}
let mut highest = self.highest_verdict();
if let Some(wpm) = oracle_verdict {
let escalated = match wpm {
WpmVerdict::Fail => Some(OracleVerdict::Fail),
WpmVerdict::Warn => Some(OracleVerdict::Warn),
WpmVerdict::Pass => None,
WpmVerdict::Partial | WpmVerdict::NotAvailable => None,
};
if let Some(esc) = escalated {
highest = Some(match highest {
None => esc,
Some(h) => h.max(esc),
});
}
}
let is_blocked = highest == Some(OracleVerdict::Fail);
GateReport { highest_verdict: highest, oracle_verdict, is_blocked, summary }
}
}