Skip to main content

bucketwarden_server/
consistency_model_support.rs

1use super::*;
2
3pub const CONSISTENCY_MODEL_STRONG_LOCAL: &str = "strong-local";
4pub const CONSISTENCY_MODEL_EVENTUAL: &str = "eventual";
5pub const CONSISTENCY_MODEL_SESSION: &str = "session";
6pub const CONSISTENCY_MODEL_BOUNDED_STALENESS: &str = "bounded-staleness";
7
8const CONSISTENCY_MODEL_CAPABILITIES: &[&str] = &[
9    "read-after-write-consistency",
10    "list-consistency",
11    "overwrite-consistency",
12    "delete-consistency",
13    "metadata-consistency",
14    "native-support-state",
15    "semantic-parity",
16    "configuration-admin-surface",
17    "security-governance-impact",
18    "observability-evidence",
19    "failure-mode-behavior",
20    "validation-test-coverage",
21    "product-specific-caveats",
22];
23
24const CONSISTENCY_MODEL_CAVEATS: &[&str] = &[
25    "BucketWarden supports strong local consistency inside a single runtime state authority.",
26    "Reads, heads, lists, overwrites, deletes, and metadata reads observe committed local object state immediately.",
27    "Eventual, session, and bounded-staleness consistency modes are tracked but fail closed outside the current runtime boundary.",
28    "Strong local consistency does not claim distributed consensus, cross-region ordering, or multi-writer conflict semantics.",
29];
30
31const CONSISTENCY_MODEL_FAILURE_MODES: &[&str] = &[
32    "unsupported-consistency-model-rejected",
33    "invalid-consistency-policy-rejected",
34    "stale-read-mode-rejected",
35    "cross-region-consistency-out-of-bounds",
36];
37
38#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
39pub struct ConsistencyModelSupportEntry {
40    pub model: &'static str,
41    pub native_support: bool,
42    pub semantic_parity: &'static str,
43    pub read_after_write: bool,
44    pub list_consistency: bool,
45    pub overwrite_consistency: bool,
46    pub delete_consistency: bool,
47    pub metadata_consistency: bool,
48    pub failure_mode: &'static str,
49    pub caveat: &'static str,
50}
51
52#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
53pub struct ConsistencyModelSupportReport {
54    pub active_model: &'static str,
55    pub supported_models: Vec<&'static str>,
56    pub unsupported_models: Vec<&'static str>,
57    pub capabilities: Vec<&'static str>,
58    pub failure_modes: Vec<&'static str>,
59    pub caveats: Vec<&'static str>,
60    pub entries: Vec<ConsistencyModelSupportEntry>,
61}
62
63#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
64pub struct ConsistencyPolicy {
65    pub model: String,
66    pub stale_reads_allowed: bool,
67    pub cross_region_ordering: bool,
68}
69
70impl BucketWarden {
71    pub fn consistency_model_support_report(&self) -> ConsistencyModelSupportReport {
72        ConsistencyModelSupportReport {
73            active_model: CONSISTENCY_MODEL_STRONG_LOCAL,
74            supported_models: vec![CONSISTENCY_MODEL_STRONG_LOCAL],
75            unsupported_models: vec![
76                CONSISTENCY_MODEL_EVENTUAL,
77                CONSISTENCY_MODEL_SESSION,
78                CONSISTENCY_MODEL_BOUNDED_STALENESS,
79            ],
80            capabilities: CONSISTENCY_MODEL_CAPABILITIES.to_vec(),
81            failure_modes: CONSISTENCY_MODEL_FAILURE_MODES.to_vec(),
82            caveats: CONSISTENCY_MODEL_CAVEATS.to_vec(),
83            entries: vec![
84                ConsistencyModelSupportEntry {
85                    model: CONSISTENCY_MODEL_STRONG_LOCAL,
86                    native_support: true,
87                    semantic_parity: "Single runtime state authority provides immediate visibility for committed object mutations.",
88                    read_after_write: true,
89                    list_consistency: true,
90                    overwrite_consistency: true,
91                    delete_consistency: true,
92                    metadata_consistency: true,
93                    failure_mode: "Invalid stale-read or cross-region policy is rejected.",
94                    caveat: "Strong local consistency is scoped to the local runtime and persisted snapshot/store boundary.",
95                },
96                ConsistencyModelSupportEntry {
97                    model: CONSISTENCY_MODEL_EVENTUAL,
98                    native_support: false,
99                    semantic_parity: "No delayed visibility or convergence-window semantics are claimed.",
100                    read_after_write: false,
101                    list_consistency: false,
102                    overwrite_consistency: false,
103                    delete_consistency: false,
104                    metadata_consistency: false,
105                    failure_mode: "Eventual consistency model selection is rejected as unsupported.",
106                    caveat: "Eventual consistency requires explicit replication lag and convergence semantics.",
107                },
108                ConsistencyModelSupportEntry {
109                    model: CONSISTENCY_MODEL_SESSION,
110                    native_support: false,
111                    semantic_parity: "No per-session read-your-writes token or causal session semantics are claimed.",
112                    read_after_write: false,
113                    list_consistency: false,
114                    overwrite_consistency: false,
115                    delete_consistency: false,
116                    metadata_consistency: false,
117                    failure_mode: "Session consistency model selection is rejected as unsupported.",
118                    caveat: "Session consistency needs session-bound causal metadata before support.",
119                },
120                ConsistencyModelSupportEntry {
121                    model: CONSISTENCY_MODEL_BOUNDED_STALENESS,
122                    native_support: false,
123                    semantic_parity: "No bounded stale read window, version lag, or timestamp lag semantics are claimed.",
124                    read_after_write: false,
125                    list_consistency: false,
126                    overwrite_consistency: false,
127                    delete_consistency: false,
128                    metadata_consistency: false,
129                    failure_mode: "Bounded-staleness consistency model selection is rejected as unsupported.",
130                    caveat: "Bounded staleness needs explicit clock and replica lag contracts before support.",
131                },
132            ],
133        }
134    }
135
136    pub fn ensure_consistency_model_supported(&self, model: &str) -> Result<(), RuntimeError> {
137        let report = self.consistency_model_support_report();
138        if report.supported_models.contains(&model) {
139            Ok(())
140        } else {
141            Err(RuntimeError::UnsupportedConsistencyModel(model.to_string()))
142        }
143    }
144
145    pub fn validate_consistency_policy(
146        &self,
147        policy: &ConsistencyPolicy,
148    ) -> Result<(), RuntimeError> {
149        self.ensure_consistency_model_supported(&policy.model)?;
150        if policy.stale_reads_allowed {
151            return Err(RuntimeError::InvalidConsistencyPolicy(
152                "strong local consistency rejects stale-read mode".to_string(),
153            ));
154        }
155        if policy.cross_region_ordering {
156            return Err(RuntimeError::InvalidConsistencyPolicy(
157                "cross-region ordering is outside the current consistency boundary".to_string(),
158            ));
159        }
160        Ok(())
161    }
162}