Skip to main content

wickra_verify_core/
verdict.rs

1//! [`Verdict`] — the reproducible answer: does the claimed report hold up?
2
3use serde::{Deserialize, Serialize};
4
5/// A single field where the claimed report disagrees with the recomputed one,
6/// beyond tolerance. `field` is a dotted/indexed path (`metrics.sharpe`,
7/// `trades[3].pnl`, `trades[len]`). `delta` is `actual - claimed`, rounded to the
8/// 1e-8 display grid — human-facing only, never part of a hash.
9#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
10pub struct Mismatch {
11    /// Dotted/indexed path to the disagreeing field.
12    pub field: String,
13    /// The value the claim asserted.
14    pub claimed: f64,
15    /// The value recomputation produced.
16    pub actual: f64,
17    /// `actual - claimed`, rounded for display.
18    pub delta: f64,
19}
20
21/// The result of verifying a claim. Deterministic and self-contained: the same
22/// `(claim, data)` yields a byte-identical verdict in every language, and the
23/// three hashes let a verdict be cross-checked against a `wickra-proof` proof of
24/// the same inputs.
25#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
26pub struct Verdict {
27    /// `true` iff every numeric field of the claimed report agrees with the
28    /// recomputed one within tolerance (`mismatches` is empty).
29    pub matches: bool,
30    /// Every field that disagreed, stably sorted by `field`.
31    pub mismatches: Vec<Mismatch>,
32    /// The exact backtest engine version that recomputed the report.
33    pub engine_version: String,
34    /// blake3 hex of the canonicalized claimed report.
35    pub claimed_report_hash: String,
36    /// blake3 hex of the canonicalized recomputed report.
37    pub actual_report_hash: String,
38    /// blake3 hex of `canonicalize({strategy, dataset_ref, candles,
39    /// engine_version})` — the same inputs hash `wickra-proof` produces.
40    pub inputs_hash: String,
41}