Skip to main content

bucketwarden_server/
metadata_architecture_support.rs

1use super::*;
2
3pub const METADATA_ARCHITECTURE_CENTRALIZED: &str = "centralized";
4pub const METADATA_ARCHITECTURE_EMBEDDED: &str = "embedded";
5pub const METADATA_ARCHITECTURE_DISTRIBUTED: &str = "distributed";
6pub const METADATA_ARCHITECTURE_SHARDED_NAMESPACE: &str = "sharded-namespace";
7pub const METADATA_ARCHITECTURE_QUORUM: &str = "metadata-quorum";
8
9const METADATA_ARCHITECTURE_CAPABILITIES: &[&str] = &[
10    "centralized-metadata",
11    "distributed-metadata",
12    "sharded-namespace",
13    "embedded-metadata",
14    "metadata-quorum",
15    "native-support-state",
16    "semantic-parity",
17    "configuration-admin-surface",
18    "security-governance-impact",
19    "observability-evidence",
20    "failure-mode-behavior",
21    "validation-test-coverage",
22    "product-specific-caveats",
23];
24
25const METADATA_ARCHITECTURE_CAVEATS: &[&str] = &[
26    "BucketWarden supports centralized in-process metadata authority backed by embedded runtime state.",
27    "Snapshots and filesystem manifests persist bucket, object, version, lock, encryption, and audit metadata.",
28    "Distributed metadata, sharded namespace, and metadata quorum modes are tracked but fail closed outside the current runtime boundary.",
29    "Metadata architecture proof is local runtime behavior and does not claim distributed consensus, external metadata services, or namespace resharding.",
30];
31
32const METADATA_ARCHITECTURE_FAILURE_MODES: &[&str] = &[
33    "unsupported-metadata-architecture-rejected",
34    "distributed-metadata-policy-rejected",
35    "sharded-namespace-policy-rejected",
36    "metadata-quorum-policy-rejected",
37    "external-metadata-service-rejected",
38];
39
40#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
41pub struct MetadataArchitectureSupportEntry {
42    pub architecture: &'static str,
43    pub native_support: bool,
44    pub semantic_parity: &'static str,
45    pub namespace_model: &'static str,
46    pub persistence_model: &'static str,
47    pub failure_mode: &'static str,
48    pub caveat: &'static str,
49}
50
51#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
52pub struct MetadataArchitectureSupportReport {
53    pub active_architecture: &'static str,
54    pub supported_architectures: Vec<&'static str>,
55    pub unsupported_architectures: Vec<&'static str>,
56    pub namespace_model: &'static str,
57    pub persistence_model: &'static str,
58    pub capabilities: Vec<&'static str>,
59    pub failure_modes: Vec<&'static str>,
60    pub caveats: Vec<&'static str>,
61    pub entries: Vec<MetadataArchitectureSupportEntry>,
62}
63
64#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
65pub struct MetadataArchitecturePolicy {
66    pub architecture: String,
67    pub namespace_shards: Option<u16>,
68    pub quorum_writes: bool,
69    pub external_metadata_service: bool,
70}
71
72impl BucketWarden {
73    pub fn metadata_architecture_support_report(&self) -> MetadataArchitectureSupportReport {
74        MetadataArchitectureSupportReport {
75            active_architecture: METADATA_ARCHITECTURE_EMBEDDED,
76            supported_architectures: vec![
77                METADATA_ARCHITECTURE_CENTRALIZED,
78                METADATA_ARCHITECTURE_EMBEDDED,
79            ],
80            unsupported_architectures: vec![
81                METADATA_ARCHITECTURE_DISTRIBUTED,
82                METADATA_ARCHITECTURE_SHARDED_NAMESPACE,
83                METADATA_ARCHITECTURE_QUORUM,
84            ],
85            namespace_model: "single-authority-btree-namespace",
86            persistence_model: "runtime-snapshot-and-filesystem-manifest",
87            capabilities: METADATA_ARCHITECTURE_CAPABILITIES.to_vec(),
88            failure_modes: METADATA_ARCHITECTURE_FAILURE_MODES.to_vec(),
89            caveats: METADATA_ARCHITECTURE_CAVEATS.to_vec(),
90            entries: vec![
91                MetadataArchitectureSupportEntry {
92                    architecture: METADATA_ARCHITECTURE_CENTRALIZED,
93                    native_support: true,
94                    semantic_parity: "Bucket, object, version, multipart, policy, and audit metadata are resolved through one runtime authority.",
95                    namespace_model: "single authoritative namespace map.",
96                    persistence_model: "snapshot and filesystem manifest round-trip the authoritative metadata graph.",
97                    failure_mode: "External metadata service selection is rejected.",
98                    caveat: "Centralized metadata is scoped to one BucketWarden runtime process.",
99                },
100                MetadataArchitectureSupportEntry {
101                    architecture: METADATA_ARCHITECTURE_EMBEDDED,
102                    native_support: true,
103                    semantic_parity: "Embedded metadata travels with the local runtime snapshot and filesystem store manifest.",
104                    namespace_model: "bucket-local object namespace persisted in runtime state.",
105                    persistence_model: "metadata is serialized with object versions and restored before reads are accepted.",
106                    failure_mode: "Invalid shard or quorum policy is rejected.",
107                    caveat: "Embedded metadata does not claim an external DB, Raft log, or multi-node metadata service.",
108                },
109                MetadataArchitectureSupportEntry {
110                    architecture: METADATA_ARCHITECTURE_DISTRIBUTED,
111                    native_support: false,
112                    semantic_parity: "No distributed metadata ownership, lease, or consensus semantics are claimed.",
113                    namespace_model: "distributed namespace is out of the current runtime boundary.",
114                    persistence_model: "no external distributed metadata journal is written.",
115                    failure_mode: "Distributed metadata architecture selection is rejected.",
116                    caveat: "Distributed metadata requires explicit node membership and consensus contracts.",
117                },
118                MetadataArchitectureSupportEntry {
119                    architecture: METADATA_ARCHITECTURE_SHARDED_NAMESPACE,
120                    native_support: false,
121                    semantic_parity: "No namespace shard ownership, split, merge, or resharding semantics are claimed.",
122                    namespace_model: "sharded namespace is out of the current runtime boundary.",
123                    persistence_model: "no shard map or shard placement manifest is written.",
124                    failure_mode: "Sharded namespace architecture selection is rejected.",
125                    caveat: "Sharded namespace support needs shard maps, routing, and migration proof.",
126                },
127                MetadataArchitectureSupportEntry {
128                    architecture: METADATA_ARCHITECTURE_QUORUM,
129                    native_support: false,
130                    semantic_parity: "No metadata quorum read/write, leader election, or quorum repair semantics are claimed.",
131                    namespace_model: "quorum metadata is out of the current runtime boundary.",
132                    persistence_model: "no quorum journal or replicated metadata log is written.",
133                    failure_mode: "Metadata quorum architecture selection is rejected.",
134                    caveat: "Metadata quorum support needs replica membership and read/write quorum contracts.",
135                },
136            ],
137        }
138    }
139
140    pub fn ensure_metadata_architecture_supported(
141        &self,
142        architecture: &str,
143    ) -> Result<(), RuntimeError> {
144        let report = self.metadata_architecture_support_report();
145        if report.supported_architectures.contains(&architecture) {
146            Ok(())
147        } else {
148            Err(RuntimeError::UnsupportedMetadataArchitecture(
149                architecture.to_string(),
150            ))
151        }
152    }
153
154    pub fn validate_metadata_architecture_policy(
155        &self,
156        policy: &MetadataArchitecturePolicy,
157    ) -> Result<(), RuntimeError> {
158        self.ensure_metadata_architecture_supported(&policy.architecture)?;
159        if policy.external_metadata_service {
160            return Err(RuntimeError::InvalidMetadataArchitecturePolicy(
161                "external metadata service is outside the current metadata boundary".to_string(),
162            ));
163        }
164        if policy.namespace_shards.is_some_and(|shards| shards > 1) {
165            return Err(RuntimeError::InvalidMetadataArchitecturePolicy(
166                "namespace sharding is unsupported by the embedded metadata architecture"
167                    .to_string(),
168            ));
169        }
170        if policy.quorum_writes {
171            return Err(RuntimeError::InvalidMetadataArchitecturePolicy(
172                "metadata quorum writes are unsupported by the embedded metadata architecture"
173                    .to_string(),
174            ));
175        }
176        Ok(())
177    }
178}