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(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
18#[serde(rename_all = "kebab-case")]
19pub enum Status {
20 Verified,
22 Tested,
24 Neural,
26 Stale,
29 Orphan,
32 Forged,
35 Unknown,
38 PendingDeepen,
41 Counterexample,
48 Inconclusive,
57}
58
59#[aristo::intent(
60 "The terminal-clean states are exactly Verified, Tested, and Neural — \
61 an intent whose current code IS confirmed to hold under some \
62 verification method. Stale, Counterexample, Inconclusive, Unknown, \
63 and the B5b error states (Orphan / Forged / PendingDeepen) are NOT \
64 clean: each means the property is unproven, refuted, or untrusted for \
65 the current code. This is the single definition every surface — \
66 status counts, the badge rate, and the nudge engine's unverified \
67 backlog — shares, so they can never disagree on what 'verified' means.",
68 verify = "test",
69 id = "status_terminal_clean_is_verified_tested_neural"
70)]
71impl Status {
72 pub fn is_terminal_clean(self) -> bool {
74 matches!(self, Status::Verified | Status::Tested | Status::Neural)
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
84#[serde(untagged)]
85pub enum VerifyLevel {
86 Bool(bool),
87 Method(VerifyMethod),
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
92#[serde(rename_all = "lowercase")]
93pub enum VerifyMethod {
94 Neural,
95 Test,
96 Full,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
103#[serde(rename_all = "snake_case")]
104pub enum CoveredRegion {
105 Function,
107 Statement,
109 ImplMethods,
111 ModuleInlineBody,
113 Type,
115 Field,
117 Crate,
119 Trait,
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn annotation_kind_round_trips_lowercase() {
129 let v = serde_json::to_value(AnnotationKind::Intent).unwrap();
130 assert_eq!(v, serde_json::json!("intent"));
131 let back: AnnotationKind = serde_json::from_value(v).unwrap();
132 assert_eq!(back, AnnotationKind::Intent);
133 }
134
135 #[test]
136 fn status_pending_deepen_is_kebab_case() {
137 let v = serde_json::to_value(Status::PendingDeepen).unwrap();
138 assert_eq!(v, serde_json::json!("pending-deepen"));
139 let back: Status = serde_json::from_value(serde_json::json!("pending-deepen")).unwrap();
140 assert_eq!(back, Status::PendingDeepen);
141 }
142
143 #[test]
144 fn verify_level_accepts_bool_form() {
145 let level: VerifyLevel = serde_json::from_value(serde_json::json!(false)).unwrap();
146 assert_eq!(level, VerifyLevel::Bool(false));
147 let level: VerifyLevel = serde_json::from_value(serde_json::json!(true)).unwrap();
148 assert_eq!(level, VerifyLevel::Bool(true));
149 }
150
151 #[test]
152 fn verify_level_accepts_named_method_form() {
153 let level: VerifyLevel = serde_json::from_value(serde_json::json!("full")).unwrap();
154 assert_eq!(level, VerifyLevel::Method(VerifyMethod::Full));
155 }
156
157 #[test]
158 fn verify_level_rejects_unknown_string() {
159 let result: Result<VerifyLevel, _> = serde_json::from_value(serde_json::json!("partial"));
160 assert!(result.is_err());
161 }
162
163 #[test]
164 fn covered_region_uses_snake_case() {
165 let v = serde_json::to_value(CoveredRegion::ImplMethods).unwrap();
166 assert_eq!(v, serde_json::json!("impl_methods"));
167 let v = serde_json::to_value(CoveredRegion::ModuleInlineBody).unwrap();
168 assert_eq!(v, serde_json::json!("module_inline_body"));
169 }
170
171 #[test]
172 fn unknown_status_value_is_rejected() {
173 let result: Result<Status, _> = serde_json::from_value(serde_json::json!("partial"));
174 assert!(result.is_err());
175 }
176
177 #[test]
178 fn terminal_clean_is_exactly_verified_tested_neural() {
179 for s in [Status::Verified, Status::Tested, Status::Neural] {
180 assert!(s.is_terminal_clean(), "{s:?} should be terminal-clean");
181 }
182 for s in [
183 Status::Stale,
184 Status::Orphan,
185 Status::Forged,
186 Status::Unknown,
187 Status::PendingDeepen,
188 Status::Counterexample,
189 Status::Inconclusive,
190 ] {
191 assert!(!s.is_terminal_clean(), "{s:?} must NOT be terminal-clean");
192 }
193 }
194}