canic_host/deployment_truth/model/safety/
mod.rs1use super::inventory::DeploymentInventoryV1;
2use super::plan::{DeploymentIdentityV1, DeploymentPlanV1};
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
9pub struct DeploymentDiffV1 {
10 pub schema_version: u32,
11 pub plan_identity: DeploymentIdentityV1,
12 pub observed_identity: Option<DeploymentIdentityV1>,
13 pub artifact_diff: Vec<DiffItemV1>,
14 pub controller_diff: Vec<DiffItemV1>,
15 pub pool_diff: Vec<DiffItemV1>,
16 pub embedded_config_diff: Vec<DiffItemV1>,
17 pub module_hash_diff: Vec<DiffItemV1>,
18 pub verifier_readiness_diff: Vec<DiffItemV1>,
19 pub resume_safety: ResumeSafetyV1,
20 pub hard_failures: Vec<SafetyFindingV1>,
21 pub warnings: Vec<SafetyFindingV1>,
22 pub resumable_phases: Vec<String>,
23}
24
25#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
29pub struct SafetyReportV1 {
30 pub schema_version: u32,
31 pub report_id: String,
32 pub diff_id: Option<String>,
33 pub status: SafetyStatusV1,
34 pub summary: String,
35 pub hard_failures: Vec<SafetyFindingV1>,
36 pub warnings: Vec<SafetyFindingV1>,
37 pub next_actions: Vec<String>,
38}
39
40#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
44pub struct DeploymentCheckV1 {
45 pub schema_version: u32,
46 pub check_id: String,
47 pub plan: DeploymentPlanV1,
48 pub inventory: DeploymentInventoryV1,
49 pub diff: DeploymentDiffV1,
50 pub report: SafetyReportV1,
51}
52
53#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
57pub struct DiffItemV1 {
58 pub category: String,
59 pub subject: String,
60 pub expected: Option<String>,
61 pub observed: Option<String>,
62 pub severity: SafetySeverityV1,
63}
64
65#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
69pub struct ResumeSafetyV1 {
70 pub status: SafetyStatusV1,
71 pub reasons: Vec<String>,
72}
73
74#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
78pub struct SafetyFindingV1 {
79 pub code: String,
80 pub message: String,
81 pub severity: SafetySeverityV1,
82 pub subject: Option<String>,
83}
84
85#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
89pub enum SafetyStatusV1 {
90 NotEvaluated,
91 Safe,
92 Warning,
93 Blocked,
94}
95
96impl SafetyStatusV1 {
97 #[must_use]
98 pub const fn label(self) -> &'static str {
99 match self {
100 Self::NotEvaluated => "not_evaluated",
101 Self::Safe => "safe",
102 Self::Warning => "warning",
103 Self::Blocked => "blocked",
104 }
105 }
106}
107
108#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
112pub enum SafetySeverityV1 {
113 Info,
114 Warning,
115 HardFailure,
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn safety_status_owns_text_labels() {
124 assert_eq!(SafetyStatusV1::NotEvaluated.label(), "not_evaluated");
125 assert_eq!(SafetyStatusV1::Safe.label(), "safe");
126 assert_eq!(SafetyStatusV1::Warning.label(), "warning");
127 assert_eq!(SafetyStatusV1::Blocked.label(), "blocked");
128 }
129}