mempill_types/disposition.rs
1//! Disposition: the 12-state outcome model returned on every write.
2
3/// The 12-state disposition model.
4///
5/// Returned synchronously on every write. For heavy-path (belief-overturning) operations,
6/// the engine returns `QueuedForAdjudication` immediately; the final state arrives
7/// asynchronously via the oracle callback.
8#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
9#[non_exhaustive]
10pub enum Disposition {
11 /// New non-conflicting first-hand external fact; committed Active at low currency.
12 CommittedCheap,
13 /// ModelDerived; committed down-weighted, ineligible to overturn until anchored.
14 CommittedInferred,
15 /// Belief-overturning op accepted into async adjudication (non-blocking return).
16 QueuedForAdjudication,
17 /// External contradiction; oracle absent; incumbent downgraded; no resolution yet.
18 Contested,
19 /// Not enough to overturn; both claims surfaced; awaiting evidence/oracle.
20 PendingConflict,
21 /// A depended-on parent was superseded; dependent flagged for review (not auto-invalidated).
22 PendingReview,
23 /// Ambiguous/weak source; held pending corroboration/oracle confirmation.
24 PendingLowConfidence,
25 /// Burst/loop signature or incoherent tx/valid; parked, auditable, not destroyed.
26 Quarantined,
27 /// Belief-overturning accepted; prior claim bounded and retained in history.
28 Superseded,
29 /// Validity assertion marks claim as no-longer-true; retained in history.
30 Invalidated,
31 /// Valid-time reopened by external/first-hand assertion (non-terminal).
32 Reinstated,
33 /// Structural failure: missing/invalid provenance, malformed fact, write-authority violation.
34 Rejected,
35}
36
37/// The synchronous write outcome returned from the engine.
38///
39/// For heavy-path (belief-overturning) operations, `disposition = QueuedForAdjudication`;
40/// the final state arrives asynchronously via the oracle callback.
41#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
42pub struct WriteOutcome {
43 /// Stable reference to the committed (or rejected) claim.
44 pub claim_ref: crate::identity::ClaimRef,
45 /// The synchronous disposition assigned by the engine on this write.
46 pub disposition: Disposition,
47 /// Populated when disposition is Contested or PendingConflict.
48 pub contested_with: Vec<crate::identity::ClaimRef>,
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn disposition_has_exactly_12_variants() {
57 // Enumerate all 12 variants — this test fails to compile if any are missing or renamed.
58 let variants = [
59 Disposition::CommittedCheap,
60 Disposition::CommittedInferred,
61 Disposition::QueuedForAdjudication,
62 Disposition::Contested,
63 Disposition::PendingConflict,
64 Disposition::PendingReview,
65 Disposition::PendingLowConfidence,
66 Disposition::Quarantined,
67 Disposition::Superseded,
68 Disposition::Invalidated,
69 Disposition::Reinstated,
70 Disposition::Rejected,
71 ];
72 assert_eq!(variants.len(), 12);
73 }
74
75 #[test]
76 fn disposition_equality() {
77 assert_eq!(Disposition::CommittedCheap, Disposition::CommittedCheap);
78 assert_ne!(Disposition::CommittedCheap, Disposition::Rejected);
79 }
80
81 #[test]
82 fn disposition_round_trip_serde() {
83 let d = Disposition::PendingReview;
84 let json = serde_json::to_string(&d).unwrap();
85 let back: Disposition = serde_json::from_str(&json).unwrap();
86 assert_eq!(d, back);
87 }
88
89 #[test]
90 fn all_dispositions_round_trip_serde() {
91 let variants = [
92 Disposition::CommittedCheap,
93 Disposition::CommittedInferred,
94 Disposition::QueuedForAdjudication,
95 Disposition::Contested,
96 Disposition::PendingConflict,
97 Disposition::PendingReview,
98 Disposition::PendingLowConfidence,
99 Disposition::Quarantined,
100 Disposition::Superseded,
101 Disposition::Invalidated,
102 Disposition::Reinstated,
103 Disposition::Rejected,
104 ];
105 for d in &variants {
106 let json = serde_json::to_string(d).unwrap();
107 let back: Disposition = serde_json::from_str(&json).unwrap();
108 assert_eq!(d, &back);
109 }
110 }
111}