Skip to main content

profile_runtime/
constitution.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use stack_ids::{
4    ApplicabilityContextId, CompiledObligationSetId, CompositionConflictSetId,
5    CompositionReceiptId, CompositionRuleSetId, ContentDigest, EffectiveConstitutionId,
6    PolicyImpactDiffId, ProfileExceptionBundleId, ProfileSetId,
7};
8
9use crate::rules::{CompiledObligationKindV1, FoldClassV1};
10
11pub const COMPOSITION_RECEIPT_V1_SCHEMA: &str = "composition_receipt_v1";
12pub const EFFECTIVE_CONSTITUTION_V1_SCHEMA: &str = "effective_constitution_v1";
13pub const COMPILED_OBLIGATION_SET_V1_SCHEMA: &str = "compiled_obligation_set_v1";
14pub const COMPOSITION_CONFLICT_SET_V1_SCHEMA: &str = "composition_conflict_set_v1";
15pub const POLICY_IMPACT_DIFF_V1_SCHEMA: &str = "policy_impact_diff_v1";
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
18pub struct CompositionReceiptV1 {
19    pub schema_version: String,
20    pub composition_receipt_id: CompositionReceiptId,
21    pub applicability_context_ref: ApplicabilityContextId,
22    pub profile_set_ref: ProfileSetId,
23    pub composition_rule_set_ref: CompositionRuleSetId,
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub effective_constitution_ref: Option<EffectiveConstitutionId>,
26    #[serde(default, skip_serializing_if = "Option::is_none")]
27    pub compiled_obligation_set_ref: Option<CompiledObligationSetId>,
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub composition_conflict_set_ref: Option<CompositionConflictSetId>,
30    #[serde(default, skip_serializing_if = "Vec::is_empty")]
31    pub degradation_markers: Vec<String>,
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub execution_context_ref: Option<String>,
34    pub replay_handle: String,
35    pub normalized_input_digest: ContentDigest,
36    pub generated_at: String,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
40#[serde(rename_all = "snake_case")]
41pub enum ConstitutionModeV1 {
42    Normal,
43    Incident,
44    AdvisoryOnly,
45    Blocked,
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
49pub struct EffectiveConstitutionV1 {
50    pub schema_version: String,
51    pub effective_constitution_id: EffectiveConstitutionId,
52    pub applicability_context_ref: ApplicabilityContextId,
53    pub profile_set_ref: ProfileSetId,
54    pub composition_rule_set_ref: CompositionRuleSetId,
55    #[serde(default, skip_serializing_if = "Vec::is_empty")]
56    pub base_law_refs: Vec<String>,
57    #[serde(default, skip_serializing_if = "Vec::is_empty")]
58    pub doctrine_refs: Vec<String>,
59    #[serde(default, skip_serializing_if = "Vec::is_empty")]
60    pub admitted_profile_refs: Vec<String>,
61    #[serde(default, skip_serializing_if = "Vec::is_empty")]
62    pub admitted_exception_refs: Vec<ProfileExceptionBundleId>,
63    pub current_mode_classification: ConstitutionModeV1,
64    #[serde(default, skip_serializing_if = "Vec::is_empty")]
65    pub hard_block_summary: Vec<String>,
66    #[serde(default, skip_serializing_if = "Vec::is_empty")]
67    pub active_warning_summary: Vec<String>,
68    #[serde(default, skip_serializing_if = "Vec::is_empty")]
69    pub approval_requirements: Vec<String>,
70    #[serde(default, skip_serializing_if = "Vec::is_empty")]
71    pub disclosure_obligations: Vec<String>,
72    #[serde(default, skip_serializing_if = "Vec::is_empty")]
73    pub residency_obligations: Vec<String>,
74    #[serde(default, skip_serializing_if = "Vec::is_empty")]
75    pub tenancy_obligations: Vec<String>,
76    #[serde(default, skip_serializing_if = "Vec::is_empty")]
77    pub assurance_obligations: Vec<String>,
78    #[serde(default, skip_serializing_if = "Vec::is_empty")]
79    pub monitoring_obligations: Vec<String>,
80    #[serde(default, skip_serializing_if = "Vec::is_empty")]
81    pub continuity_obligations: Vec<String>,
82    #[serde(default, skip_serializing_if = "Vec::is_empty")]
83    pub effect_obligations: Vec<String>,
84    #[serde(default, skip_serializing_if = "Vec::is_empty")]
85    pub delegation_obligations: Vec<String>,
86    #[serde(default, skip_serializing_if = "Vec::is_empty")]
87    pub replay_obligations: Vec<String>,
88    pub valid_as_of: String,
89    pub recorded_as_of: String,
90    pub explanation_summary: String,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
94pub struct CompiledObligationEntryV1 {
95    pub obligation_entry_id: String,
96    pub obligation_family: String,
97    pub obligation_key: String,
98    pub output_kind: CompiledObligationKindV1,
99    pub fold_class: FoldClassV1,
100    #[serde(default, skip_serializing_if = "Vec::is_empty")]
101    pub string_values: Vec<String>,
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub numeric_value: Option<i64>,
104    #[serde(default, skip_serializing_if = "Option::is_none")]
105    pub expiry_at: Option<String>,
106    pub blocking: bool,
107    #[serde(default, skip_serializing_if = "Vec::is_empty")]
108    pub source_profile_refs: Vec<String>,
109    #[serde(default, skip_serializing_if = "Vec::is_empty")]
110    pub source_exception_refs: Vec<ProfileExceptionBundleId>,
111    pub explanation: String,
112}
113
114#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
115pub struct BlockEntryV1 {
116    pub block_key: String,
117    pub reason: String,
118    #[serde(default, skip_serializing_if = "Vec::is_empty")]
119    pub source_profile_refs: Vec<String>,
120    #[serde(default, skip_serializing_if = "Vec::is_empty")]
121    pub admissible_exception_classes: Vec<String>,
122}
123
124#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
125pub struct CompiledObligationSetV1 {
126    pub schema_version: String,
127    pub compiled_obligation_set_id: CompiledObligationSetId,
128    pub effective_constitution_ref: EffectiveConstitutionId,
129    #[serde(default, skip_serializing_if = "Vec::is_empty")]
130    pub obligation_entries: Vec<CompiledObligationEntryV1>,
131    #[serde(default, skip_serializing_if = "Vec::is_empty")]
132    pub block_entries: Vec<BlockEntryV1>,
133    #[serde(default, skip_serializing_if = "Vec::is_empty")]
134    pub required_approvals: Vec<String>,
135    #[serde(default, skip_serializing_if = "Vec::is_empty")]
136    pub required_checks: Vec<String>,
137    #[serde(default, skip_serializing_if = "Vec::is_empty")]
138    pub required_monitors: Vec<String>,
139    #[serde(default, skip_serializing_if = "Vec::is_empty")]
140    pub required_evidence_obligations: Vec<String>,
141    #[serde(default, skip_serializing_if = "Vec::is_empty")]
142    pub required_disclosure_obligations: Vec<String>,
143    #[serde(default, skip_serializing_if = "Vec::is_empty")]
144    pub required_rollback_obligations: Vec<String>,
145    #[serde(default, skip_serializing_if = "Vec::is_empty")]
146    pub required_compensation_obligations: Vec<String>,
147    #[serde(default, skip_serializing_if = "Vec::is_empty")]
148    pub required_post_hoc_review_obligations: Vec<String>,
149    pub promotion_eligibility_summary: String,
150    pub release_eligibility_summary: String,
151    pub effect_eligibility_summary: String,
152    #[serde(default, skip_serializing_if = "Vec::is_empty")]
153    pub unresolved_dependency_refs: Vec<String>,
154}
155
156#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
157pub struct CompositionConflictV1 {
158    pub obligation_family: String,
159    pub obligation_key: String,
160    pub conflict_class: String,
161    pub blocking: bool,
162    #[serde(default, skip_serializing_if = "Vec::is_empty")]
163    pub source_profile_refs: Vec<String>,
164    #[serde(default, skip_serializing_if = "Vec::is_empty")]
165    pub implicated_values: Vec<String>,
166    #[serde(default, skip_serializing_if = "Vec::is_empty")]
167    pub admissible_exception_classes: Vec<String>,
168    pub review_path: String,
169    pub explanation: String,
170}
171
172#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
173pub struct CompositionConflictSetV1 {
174    pub schema_version: String,
175    pub composition_conflict_set_id: CompositionConflictSetId,
176    #[serde(default, skip_serializing_if = "Option::is_none")]
177    pub effective_constitution_ref: Option<EffectiveConstitutionId>,
178    #[serde(default, skip_serializing_if = "Option::is_none")]
179    pub composition_receipt_ref: Option<CompositionReceiptId>,
180    #[serde(default, skip_serializing_if = "Vec::is_empty")]
181    pub conflicts: Vec<CompositionConflictV1>,
182    pub blocking: bool,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
186pub struct PolicyImpactDiffV1 {
187    pub schema_version: String,
188    pub policy_impact_diff_id: PolicyImpactDiffId,
189    pub from_effective_constitution_ref: EffectiveConstitutionId,
190    pub to_effective_constitution_ref: EffectiveConstitutionId,
191    #[serde(default, skip_serializing_if = "Vec::is_empty")]
192    pub changed_obligation_families: Vec<String>,
193    #[serde(default, skip_serializing_if = "Vec::is_empty")]
194    pub unchanged_obligation_families: Vec<String>,
195    #[serde(default, skip_serializing_if = "Vec::is_empty")]
196    pub newly_blocked_paths: Vec<String>,
197    #[serde(default, skip_serializing_if = "Vec::is_empty")]
198    pub newly_admitted_paths: Vec<String>,
199    #[serde(default, skip_serializing_if = "Vec::is_empty")]
200    pub changed_approval_behavior: Vec<String>,
201    #[serde(default, skip_serializing_if = "Vec::is_empty")]
202    pub changed_monitoring_behavior: Vec<String>,
203    #[serde(default, skip_serializing_if = "Vec::is_empty")]
204    pub changed_disclosure_behavior: Vec<String>,
205    #[serde(default, skip_serializing_if = "Vec::is_empty")]
206    pub changed_residency_behavior: Vec<String>,
207    #[serde(default, skip_serializing_if = "Vec::is_empty")]
208    pub changed_incident_behavior: Vec<String>,
209    #[serde(default, skip_serializing_if = "Vec::is_empty")]
210    pub migration_consequences: Vec<String>,
211    pub simulation_only: bool,
212    pub explanation_summary: String,
213}