1use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
9#[serde(rename_all = "lowercase")]
10pub enum AnnotationKind {
11 Intent,
12 Assume,
13}
14
15#[derive(
21 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
22)]
23#[serde(rename_all = "kebab-case")]
24pub enum Status {
25 Verified,
27 Tested,
29 Neural,
31 Stale,
34 Orphan,
37 Forged,
40 Unknown,
43 PendingDeepen,
46 Counterexample,
53 Inconclusive,
62}
63
64#[aristo::intent(
65 "The terminal-clean states are exactly Verified, Tested, and Neural — \
66 an intent whose current code IS confirmed to hold under some \
67 verification method. Stale, Counterexample, Inconclusive, Unknown, \
68 and the B5b error states (Orphan / Forged / PendingDeepen) are NOT \
69 clean: each means the property is unproven, refuted, or untrusted for \
70 the current code. This is the single definition every surface — \
71 status counts, the badge rate, and the nudge engine's unverified \
72 backlog — shares, so they can never disagree on what 'verified' means.",
73 verify = "test",
74 id = "status_terminal_clean_is_verified_tested_neural"
75)]
76impl Status {
77 pub fn is_terminal_clean(self) -> bool {
79 matches!(self, Status::Verified | Status::Tested | Status::Neural)
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
89#[serde(untagged)]
90pub enum VerifyLevel {
91 Bool(bool),
92 Method(VerifyMethod),
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
97#[serde(rename_all = "lowercase")]
98pub enum VerifyMethod {
99 Neural,
100 Test,
101 Full,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
108#[serde(rename_all = "snake_case")]
109pub enum CoveredRegion {
110 Function,
112 Statement,
114 ImplMethods,
116 ModuleInlineBody,
118 Type,
120 Field,
122 Crate,
124 Trait,
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn annotation_kind_round_trips_lowercase() {
134 let v = serde_json::to_value(AnnotationKind::Intent).unwrap();
135 assert_eq!(v, serde_json::json!("intent"));
136 let back: AnnotationKind = serde_json::from_value(v).unwrap();
137 assert_eq!(back, AnnotationKind::Intent);
138 }
139
140 #[test]
141 fn status_pending_deepen_is_kebab_case() {
142 let v = serde_json::to_value(Status::PendingDeepen).unwrap();
143 assert_eq!(v, serde_json::json!("pending-deepen"));
144 let back: Status = serde_json::from_value(serde_json::json!("pending-deepen")).unwrap();
145 assert_eq!(back, Status::PendingDeepen);
146 }
147
148 #[test]
149 fn verify_level_accepts_bool_form() {
150 let level: VerifyLevel = serde_json::from_value(serde_json::json!(false)).unwrap();
151 assert_eq!(level, VerifyLevel::Bool(false));
152 let level: VerifyLevel = serde_json::from_value(serde_json::json!(true)).unwrap();
153 assert_eq!(level, VerifyLevel::Bool(true));
154 }
155
156 #[test]
157 fn verify_level_accepts_named_method_form() {
158 let level: VerifyLevel = serde_json::from_value(serde_json::json!("full")).unwrap();
159 assert_eq!(level, VerifyLevel::Method(VerifyMethod::Full));
160 }
161
162 #[test]
163 fn verify_level_rejects_unknown_string() {
164 let result: Result<VerifyLevel, _> = serde_json::from_value(serde_json::json!("partial"));
165 assert!(result.is_err());
166 }
167
168 #[test]
169 fn covered_region_uses_snake_case() {
170 let v = serde_json::to_value(CoveredRegion::ImplMethods).unwrap();
171 assert_eq!(v, serde_json::json!("impl_methods"));
172 let v = serde_json::to_value(CoveredRegion::ModuleInlineBody).unwrap();
173 assert_eq!(v, serde_json::json!("module_inline_body"));
174 }
175
176 #[test]
177 fn unknown_status_value_is_rejected() {
178 let result: Result<Status, _> = serde_json::from_value(serde_json::json!("partial"));
179 assert!(result.is_err());
180 }
181
182 #[test]
183 fn terminal_clean_is_exactly_verified_tested_neural() {
184 for s in [Status::Verified, Status::Tested, Status::Neural] {
185 assert!(s.is_terminal_clean(), "{s:?} should be terminal-clean");
186 }
187 for s in [
188 Status::Stale,
189 Status::Orphan,
190 Status::Forged,
191 Status::Unknown,
192 Status::PendingDeepen,
193 Status::Counterexample,
194 Status::Inconclusive,
195 ] {
196 assert!(!s.is_terminal_clean(), "{s:?} must NOT be terminal-clean");
197 }
198 }
199}