Skip to main content

ldp_protocol/types/
verification.rs

1//! LDP verification and lineage types.
2
3use serde::{Deserialize, Serialize};
4
5/// How a result was verified.
6#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum VerificationStatus {
9    #[default]
10    Unverified,
11    SelfVerified,
12    PeerVerified,
13    ToolVerified,
14    HumanVerified,
15}
16
17/// Reference to supporting evidence.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct EvidenceRef {
20    pub source: String,
21    pub kind: String,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub uri: Option<String>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub summary: Option<String>,
26}
27
28/// One hop in a delegation lineage chain.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ProvenanceEntry {
31    pub delegate_id: String,
32    pub model_version: String,
33    pub step: String,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub timestamp: Option<String>,
36    #[serde(default)]
37    pub verification_status: VerificationStatus,
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn default_verification_is_unverified() {
46        assert_eq!(
47            VerificationStatus::default(),
48            VerificationStatus::Unverified
49        );
50    }
51
52    #[test]
53    fn verification_status_serialization() {
54        let status = VerificationStatus::SelfVerified;
55        let json = serde_json::to_value(&status).unwrap();
56        assert_eq!(json, "self_verified");
57        let restored: VerificationStatus = serde_json::from_value(json).unwrap();
58        assert_eq!(restored, VerificationStatus::SelfVerified);
59    }
60
61    #[test]
62    fn all_verification_variants_serialize() {
63        for (variant, expected) in [
64            (VerificationStatus::Unverified, "unverified"),
65            (VerificationStatus::SelfVerified, "self_verified"),
66            (VerificationStatus::PeerVerified, "peer_verified"),
67            (VerificationStatus::ToolVerified, "tool_verified"),
68            (VerificationStatus::HumanVerified, "human_verified"),
69        ] {
70            let json = serde_json::to_value(&variant).unwrap();
71            assert_eq!(json, expected);
72        }
73    }
74
75    #[test]
76    fn evidence_ref_creation() {
77        let evidence = EvidenceRef {
78            source: "pytest".into(),
79            kind: "test_results".into(),
80            uri: Some("https://ci.example.com/run/123".into()),
81            summary: Some("All 50 tests passed".into()),
82        };
83        let json = serde_json::to_value(&evidence).unwrap();
84        let restored: EvidenceRef = serde_json::from_value(json).unwrap();
85        assert_eq!(restored.source, "pytest");
86        assert_eq!(restored.kind, "test_results");
87    }
88
89    #[test]
90    fn provenance_entry_creation() {
91        let entry = ProvenanceEntry {
92            delegate_id: "ldp:delegate:alpha".into(),
93            model_version: "v1.0".into(),
94            step: "reasoning".into(),
95            timestamp: Some("2026-03-15T12:00:00Z".into()),
96            verification_status: VerificationStatus::SelfVerified,
97        };
98        let json = serde_json::to_value(&entry).unwrap();
99        let restored: ProvenanceEntry = serde_json::from_value(json).unwrap();
100        assert_eq!(restored.delegate_id, "ldp:delegate:alpha");
101        assert_eq!(
102            restored.verification_status,
103            VerificationStatus::SelfVerified
104        );
105    }
106}