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}