Skip to main content

canic_host/deployment_truth/
model.rs

1use serde::{Deserialize, Serialize};
2
3///
4/// DeploymentPlanV1
5///
6#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
7pub struct DeploymentPlanV1 {
8    pub schema_version: u32,
9    pub plan_id: String,
10    pub deployment_identity: DeploymentIdentityV1,
11    pub trust_domain: TrustDomainV1,
12    pub fleet_template: String,
13    pub runtime_variant: String,
14    pub authority_profile: AuthorityProfileV1,
15    pub role_artifacts: Vec<RoleArtifactV1>,
16    pub expected_canisters: Vec<ExpectedCanisterV1>,
17    pub expected_pool: Vec<ExpectedPoolCanisterV1>,
18    pub expected_verifier_readiness: VerifierReadinessExpectationV1,
19    pub unresolved_assumptions: Vec<DeploymentAssumptionV1>,
20}
21
22///
23/// DeploymentInventoryV1
24///
25#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
26pub struct DeploymentInventoryV1 {
27    pub schema_version: u32,
28    pub inventory_id: String,
29    pub observed_at: String,
30    pub observed_identity: Option<DeploymentIdentityV1>,
31    pub local_config: LocalDeploymentConfigV1,
32    pub observed_canisters: Vec<ObservedCanisterV1>,
33    pub observed_pool: Vec<ObservedPoolCanisterV1>,
34    pub observed_artifacts: Vec<ObservedArtifactV1>,
35    pub observed_verifier_readiness: VerifierReadinessObservationV1,
36    pub unresolved_observations: Vec<DeploymentObservationGapV1>,
37}
38
39///
40/// DeploymentReceiptV1
41///
42#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
43pub struct DeploymentReceiptV1 {
44    pub schema_version: u32,
45    pub operation_id: String,
46    pub plan_id: String,
47    pub operation_status: DeploymentExecutionStatusV1,
48    pub started_at: String,
49    pub finished_at: Option<String>,
50    pub operator_principal: Option<String>,
51    pub root_principal: Option<String>,
52    pub previous_observed_deployment_epoch: Option<u64>,
53    pub phase_receipts: Vec<PhaseReceiptV1>,
54    pub role_phase_receipts: Vec<RolePhaseReceiptV1>,
55    pub final_inventory_id: Option<String>,
56    pub command_result: DeploymentCommandResultV1,
57}
58
59///
60/// AuthorityReceiptV1
61///
62#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
63pub struct AuthorityReceiptV1 {
64    pub schema_version: u32,
65    pub operation_id: String,
66    pub check_id: Option<String>,
67    pub reconciliation_plan_id: String,
68    pub authority_report_id: String,
69    pub inventory_id: String,
70    pub authority_profile_hash: Option<String>,
71    pub operation_status: DeploymentExecutionStatusV1,
72    pub started_at: String,
73    pub finished_at: Option<String>,
74    pub attempted_actions: Vec<AuthorityAttemptedActionV1>,
75    pub verified_controller_observations: Vec<AuthorityControllerObservationV1>,
76    pub hard_failures: Vec<SafetyFindingV1>,
77    pub unresolved_observation_gaps: Vec<DeploymentObservationGapV1>,
78    pub unresolved_external_actions: Vec<AuthorityExternalActionV1>,
79    pub command_result: DeploymentCommandResultV1,
80}
81
82///
83/// AuthorityDryRunEvidenceV1
84///
85#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
86pub struct AuthorityDryRunEvidenceV1 {
87    pub schema_version: u32,
88    pub evidence_id: String,
89    pub check_id: String,
90    pub generated_at: String,
91    pub reconciliation_plan: AuthorityReconciliationPlanV1,
92    pub authority_report: AuthorityReportV1,
93    pub authority_receipt: AuthorityReceiptV1,
94}
95
96///
97/// AuthorityAttemptedActionV1
98///
99#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
100pub struct AuthorityAttemptedActionV1 {
101    pub subject: String,
102    pub canister_id: Option<String>,
103    pub role: Option<String>,
104    pub action: AuthorityActionV1,
105    pub result: RolePhaseResultV1,
106    pub error: Option<String>,
107}
108
109///
110/// AuthorityControllerObservationV1
111///
112#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
113pub struct AuthorityControllerObservationV1 {
114    pub subject: String,
115    pub canister_id: Option<String>,
116    pub role: Option<String>,
117    pub state: AuthorityReconciliationStateV1,
118    pub action: AuthorityActionV1,
119    pub observed_controllers: Vec<String>,
120    pub desired_controllers: Vec<String>,
121    pub controller_delta: AuthorityControllerDeltaV1,
122}
123
124///
125/// RoleArtifactManifestV1
126///
127#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
128pub struct RoleArtifactManifestV1 {
129    pub schema_version: u32,
130    pub manifest_id: String,
131    pub network: String,
132    pub artifact_root: Option<String>,
133    pub role_artifacts: Vec<RoleArtifactV1>,
134    pub unresolved_artifacts: Vec<DeploymentObservationGapV1>,
135}
136
137///
138/// DeploymentDiffV1
139///
140#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
141pub struct DeploymentDiffV1 {
142    pub schema_version: u32,
143    pub plan_identity: DeploymentIdentityV1,
144    pub observed_identity: Option<DeploymentIdentityV1>,
145    pub artifact_diff: Vec<DiffItemV1>,
146    pub controller_diff: Vec<DiffItemV1>,
147    pub pool_diff: Vec<DiffItemV1>,
148    pub embedded_config_diff: Vec<DiffItemV1>,
149    pub module_hash_diff: Vec<DiffItemV1>,
150    pub verifier_readiness_diff: Vec<DiffItemV1>,
151    pub resume_safety: ResumeSafetyV1,
152    pub hard_failures: Vec<SafetyFindingV1>,
153    pub warnings: Vec<SafetyFindingV1>,
154    pub resumable_phases: Vec<String>,
155}
156
157///
158/// SafetyReportV1
159///
160#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
161pub struct SafetyReportV1 {
162    pub schema_version: u32,
163    pub report_id: String,
164    pub diff_id: Option<String>,
165    pub status: SafetyStatusV1,
166    pub summary: String,
167    pub hard_failures: Vec<SafetyFindingV1>,
168    pub warnings: Vec<SafetyFindingV1>,
169    pub next_actions: Vec<String>,
170}
171
172///
173/// DeploymentCheckV1
174///
175#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
176pub struct DeploymentCheckV1 {
177    pub schema_version: u32,
178    pub check_id: String,
179    pub plan: DeploymentPlanV1,
180    pub inventory: DeploymentInventoryV1,
181    pub diff: DeploymentDiffV1,
182    pub report: SafetyReportV1,
183}
184
185///
186/// AuthorityReconciliationPlanV1
187///
188#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
189pub struct AuthorityReconciliationPlanV1 {
190    pub schema_version: u32,
191    pub plan_id: String,
192    pub inventory_id: String,
193    pub authority_profile_hash: Option<String>,
194    pub canister_actions: Vec<CanisterAuthorityActionV1>,
195    pub automatic_actions: Vec<AuthorityAutomaticActionV1>,
196    pub hard_failures: Vec<SafetyFindingV1>,
197    pub external_actions_required: Vec<AuthorityExternalActionV1>,
198}
199
200///
201/// AuthorityAutomaticActionV1
202///
203#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
204pub struct AuthorityAutomaticActionV1 {
205    pub subject: String,
206    pub canister_id: String,
207    pub role: Option<String>,
208    pub action: AuthorityActionV1,
209    pub observed_controllers: Vec<String>,
210    pub desired_controllers: Vec<String>,
211    pub controller_delta: AuthorityControllerDeltaV1,
212    pub reason: String,
213}
214
215///
216/// AuthorityControllerDeltaV1
217///
218#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
219pub struct AuthorityControllerDeltaV1 {
220    pub add_controllers: Vec<String>,
221    pub remove_controllers: Vec<String>,
222}
223
224///
225/// AuthorityReportV1
226///
227#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
228pub struct AuthorityReportV1 {
229    pub schema_version: u32,
230    pub report_id: String,
231    pub check_id: Option<String>,
232    pub reconciliation_plan_id: String,
233    pub inventory_id: String,
234    pub authority_profile_hash: Option<String>,
235    pub status: SafetyStatusV1,
236    pub summary: String,
237    pub counts: AuthorityReportCountsV1,
238    pub apply_readiness: AuthorityApplyReadinessV1,
239    pub action_counts: Vec<AuthorityActionCountV1>,
240    pub control_class_counts: Vec<AuthorityControlClassCountV1>,
241    pub observation_gaps: Vec<DeploymentObservationGapV1>,
242    pub automatic_actions: Vec<AuthorityAutomaticActionV1>,
243    pub hard_failures: Vec<SafetyFindingV1>,
244    pub external_actions_required: Vec<AuthorityExternalActionV1>,
245    pub next_actions: Vec<String>,
246}
247
248///
249/// AuthorityApplyReadinessV1
250///
251#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
252pub struct AuthorityApplyReadinessV1 {
253    pub can_apply_automatically: bool,
254    pub automatic_action_count: usize,
255    pub blockers: Vec<AuthorityApplyBlockerV1>,
256}
257
258///
259/// AuthorityApplyBlockerV1
260///
261#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
262pub enum AuthorityApplyBlockerV1 {
263    UnsafeBlocked,
264    HardFailures,
265    ObservationGaps,
266    ExternalActions,
267}
268
269///
270/// AuthorityActionCountV1
271///
272#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
273pub struct AuthorityActionCountV1 {
274    pub action: AuthorityActionV1,
275    pub count: usize,
276}
277
278///
279/// AuthorityControlClassCountV1
280///
281#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
282pub struct AuthorityControlClassCountV1 {
283    pub control_class: CanisterControlClassV1,
284    pub count: usize,
285}
286
287///
288/// AuthorityReportCountsV1
289///
290#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
291pub struct AuthorityReportCountsV1 {
292    pub already_correct: usize,
293    pub can_apply_automatically: usize,
294    pub requires_external_action: usize,
295    pub unsafe_blocked: usize,
296    pub unknown: usize,
297    pub hard_failures: usize,
298}
299
300///
301/// CanisterAuthorityActionV1
302///
303#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
304pub struct CanisterAuthorityActionV1 {
305    pub canister_id: Option<String>,
306    pub role: Option<String>,
307    pub control_classification: CanisterControlClassV1,
308    pub observed_controllers: Vec<String>,
309    pub desired_controllers: Vec<String>,
310    pub controller_delta: AuthorityControllerDeltaV1,
311    pub action: AuthorityActionV1,
312    pub state: AuthorityReconciliationStateV1,
313    pub can_apply: bool,
314    pub reason: String,
315}
316
317///
318/// AuthorityExternalActionV1
319///
320#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
321pub struct AuthorityExternalActionV1 {
322    pub subject: String,
323    pub canister_id: Option<String>,
324    pub role: Option<String>,
325    pub control_classification: CanisterControlClassV1,
326    pub state: AuthorityReconciliationStateV1,
327    pub action: AuthorityActionV1,
328    pub observed_controllers: Vec<String>,
329    pub desired_controllers: Vec<String>,
330    pub controller_delta: AuthorityControllerDeltaV1,
331    pub reason: String,
332}
333
334///
335/// AuthorityActionV1
336///
337#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
338pub enum AuthorityActionV1 {
339    None,
340    AddControllers,
341    RemoveControllers,
342    ReplaceControllerSet,
343    RequiresExternalController,
344    RequiresDestructiveImportConfirmation,
345    ObserveOnly,
346    AdoptPlanAvailable,
347    BlockedByPolicy,
348    UnknownObservation,
349}
350
351///
352/// AuthorityReconciliationStateV1
353///
354#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
355pub enum AuthorityReconciliationStateV1 {
356    AlreadyCorrect,
357    CanApplyAutomatically,
358    RequiresExternalAction,
359    UnsafeBlocked,
360    Unknown,
361}
362
363///
364/// DeploymentIdentityV1
365///
366#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
367pub struct DeploymentIdentityV1 {
368    pub deployment_name: String,
369    pub network: String,
370    pub root_principal: Option<String>,
371    pub authority_profile_hash: Option<String>,
372    pub role_topology_hash: Option<String>,
373    pub deployment_manifest_digest: Option<String>,
374    pub canonical_runtime_config_digest: Option<String>,
375    pub role_embedded_config_set_digest: Option<String>,
376    pub artifact_set_digest: Option<String>,
377    pub pool_identity_set_digest: Option<String>,
378    pub canic_version: Option<String>,
379    pub ic_memory_version: Option<String>,
380}
381
382///
383/// TrustDomainV1
384///
385#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
386pub struct TrustDomainV1 {
387    pub root_trust_anchor: Option<String>,
388    pub migration_from: Option<String>,
389}
390
391///
392/// AuthorityProfileV1
393///
394#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
395pub struct AuthorityProfileV1 {
396    pub profile_id: String,
397    pub expected_controllers: Vec<String>,
398    pub staging_controllers: Vec<String>,
399    pub emergency_controllers: Vec<String>,
400}
401
402///
403/// RoleArtifactV1
404///
405#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
406pub struct RoleArtifactV1 {
407    pub role: String,
408    pub source: ArtifactSourceV1,
409    pub build_profile: String,
410    pub wasm_path: Option<String>,
411    pub wasm_gz_path: Option<String>,
412    pub wasm_gz_size_bytes: Option<u64>,
413    pub wasm_sha256: Option<String>,
414    pub wasm_gz_sha256: Option<String>,
415    pub wasm_gz_sha256_source: Option<ArtifactDigestSourceV1>,
416    pub observed_wasm_gz_file_sha256: Option<String>,
417    pub observed_wasm_gz_file_sha256_source: Option<ArtifactDigestSourceV1>,
418    pub installed_module_hash: Option<String>,
419    pub candid_path: Option<String>,
420    pub candid_sha256: Option<String>,
421    pub raw_config_sha256: Option<String>,
422    pub canonical_embedded_config_sha256: Option<String>,
423    pub embedded_topology_sha256: Option<String>,
424    pub builder_version: Option<String>,
425    pub rust_toolchain: Option<String>,
426    pub package_version: Option<String>,
427}
428
429///
430/// ArtifactDigestSourceV1
431///
432#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
433pub enum ArtifactDigestSourceV1 {
434    ReleaseSetManifest,
435    ObservedFileDigest,
436    InstalledModuleHash,
437}
438
439///
440/// ArtifactSourceV1
441///
442#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
443pub enum ArtifactSourceV1 {
444    LocalBuild,
445    ReleaseSet,
446    WasmStore,
447    External,
448    Unknown,
449}
450
451///
452/// ExpectedCanisterV1
453///
454#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
455pub struct ExpectedCanisterV1 {
456    pub role: String,
457    pub canister_id: Option<String>,
458    pub control_class: CanisterControlClassV1,
459}
460
461///
462/// ObservedCanisterV1
463///
464#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
465pub struct ObservedCanisterV1 {
466    pub canister_id: String,
467    pub role: Option<String>,
468    pub control_class: CanisterControlClassV1,
469    pub controllers: Vec<String>,
470    pub module_hash: Option<String>,
471    pub status: Option<String>,
472    pub root_trust_anchor: Option<String>,
473    pub canonical_embedded_config_digest: Option<String>,
474    pub role_assignment_source: Option<String>,
475}
476
477///
478/// CanisterControlClassV1
479///
480#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
481pub enum CanisterControlClassV1 {
482    DeploymentControlled,
483    CanicManagedPool,
484    ExternallyImported,
485    JointlyControlled,
486    UserControlled,
487    UnknownUnsafe,
488}
489
490///
491/// ExpectedPoolCanisterV1
492///
493#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
494pub struct ExpectedPoolCanisterV1 {
495    pub pool: String,
496    pub canister_id: Option<String>,
497    pub role: Option<String>,
498}
499
500///
501/// ObservedPoolCanisterV1
502///
503#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
504pub struct ObservedPoolCanisterV1 {
505    pub pool: String,
506    pub canister_id: String,
507    pub role: Option<String>,
508    pub control_class: CanisterControlClassV1,
509}
510
511///
512/// LocalDeploymentConfigV1
513///
514#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
515pub struct LocalDeploymentConfigV1 {
516    pub config_path: Option<String>,
517    pub raw_config_sha256: Option<String>,
518    pub canonical_embedded_config_sha256: Option<String>,
519}
520
521///
522/// ObservedArtifactV1
523///
524#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
525pub struct ObservedArtifactV1 {
526    pub role: String,
527    pub artifact_path: String,
528    pub file_sha256: Option<String>,
529    pub file_sha256_source: Option<ArtifactDigestSourceV1>,
530    pub payload_sha256: Option<String>,
531    pub payload_size_bytes: Option<u64>,
532    pub source: ArtifactSourceV1,
533}
534
535///
536/// VerifierReadinessExpectationV1
537///
538#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
539pub struct VerifierReadinessExpectationV1 {
540    pub required: bool,
541    pub expected_role_epochs: Vec<RoleEpochExpectationV1>,
542}
543
544///
545/// VerifierReadinessObservationV1
546///
547#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
548pub struct VerifierReadinessObservationV1 {
549    pub status: ObservationStatusV1,
550    pub role_epochs: Vec<RoleEpochObservationV1>,
551}
552
553///
554/// RoleEpochExpectationV1
555///
556#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
557pub struct RoleEpochExpectationV1 {
558    pub role: String,
559    pub minimum_epoch: u64,
560}
561
562///
563/// RoleEpochObservationV1
564///
565#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
566pub struct RoleEpochObservationV1 {
567    pub role: String,
568    pub observed_epoch: Option<u64>,
569    pub status: ObservationStatusV1,
570}
571
572///
573/// DeploymentAssumptionV1
574///
575#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
576pub struct DeploymentAssumptionV1 {
577    pub key: String,
578    pub description: String,
579}
580
581///
582/// DeploymentObservationGapV1
583///
584#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
585pub struct DeploymentObservationGapV1 {
586    pub key: String,
587    pub description: String,
588}
589
590///
591/// PhaseReceiptV1
592///
593#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
594pub struct PhaseReceiptV1 {
595    pub phase: String,
596    pub started_at: String,
597    pub finished_at: Option<String>,
598    pub attempted_action: String,
599    pub verified_postcondition: VerifiedPostconditionV1,
600}
601
602///
603/// VerifiedPostconditionV1
604///
605#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
606pub struct VerifiedPostconditionV1 {
607    pub status: ObservationStatusV1,
608    pub evidence: Vec<String>,
609}
610
611///
612/// DeploymentExecutionStatusV1
613///
614#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
615pub enum DeploymentExecutionStatusV1 {
616    NotStarted,
617    InProgress,
618    FailedBeforeMutation,
619    PartiallyApplied,
620    FailedAfterMutation,
621    Complete,
622}
623
624///
625/// DeploymentCommandResultV1
626///
627#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
628pub enum DeploymentCommandResultV1 {
629    NotFinished,
630    Succeeded,
631    Failed { code: String, message: String },
632}
633
634///
635/// RolePhaseReceiptV1
636///
637#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
638pub struct RolePhaseReceiptV1 {
639    pub role: String,
640    pub phase: String,
641    pub result: RolePhaseResultV1,
642    pub previous_module_hash: Option<String>,
643    pub target_module_hash: Option<String>,
644    pub observed_module_hash_after: Option<String>,
645    pub artifact_digest: Option<String>,
646    pub canonical_embedded_config_sha256: Option<String>,
647    pub error: Option<String>,
648}
649
650///
651/// RolePhaseResultV1
652///
653#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
654pub enum RolePhaseResultV1 {
655    Applied,
656    Failed,
657    Skipped,
658    NotAttempted,
659    VerifiedAlreadyApplied,
660}
661
662///
663/// DiffItemV1
664///
665#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
666pub struct DiffItemV1 {
667    pub category: String,
668    pub subject: String,
669    pub expected: Option<String>,
670    pub observed: Option<String>,
671    pub severity: SafetySeverityV1,
672}
673
674///
675/// ResumeSafetyV1
676///
677#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
678pub struct ResumeSafetyV1 {
679    pub status: SafetyStatusV1,
680    pub reasons: Vec<String>,
681}
682
683///
684/// SafetyFindingV1
685///
686#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
687pub struct SafetyFindingV1 {
688    pub code: String,
689    pub message: String,
690    pub severity: SafetySeverityV1,
691    pub subject: Option<String>,
692}
693
694///
695/// SafetyStatusV1
696///
697#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
698pub enum SafetyStatusV1 {
699    NotEvaluated,
700    Safe,
701    Warning,
702    Blocked,
703}
704
705///
706/// SafetySeverityV1
707///
708#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
709pub enum SafetySeverityV1 {
710    Info,
711    Warning,
712    HardFailure,
713}
714
715///
716/// ObservationStatusV1
717///
718#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
719pub enum ObservationStatusV1 {
720    NotObserved,
721    Observed,
722    Missing,
723    Inconclusive,
724}