1use crate::serde_json::Value as JsonValue;
20use crate::storage::UnifiedStore;
21
22#[inline]
23fn num(v: f64) -> JsonValue {
24 JsonValue::Number(v)
25}
26
27#[inline]
28fn text(s: &str) -> JsonValue {
29 JsonValue::String(s.to_string())
30}
31
32#[derive(Debug, Clone)]
35pub struct ConfigDefault {
36 pub key: &'static str,
37 pub tier: Tier,
38 pub default: fn() -> JsonValue,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum Tier {
46 Critical,
48 Optional,
50}
51
52pub const MATRIX: &[ConfigDefault] = &[
54 ConfigDefault {
56 key: "ask.max_prompt_tokens",
57 tier: Tier::Optional,
58 default: || num(8192.0),
59 },
60 ConfigDefault {
61 key: "ask.max_completion_tokens",
62 tier: Tier::Optional,
63 default: || num(1024.0),
64 },
65 ConfigDefault {
66 key: "ask.max_sources_bytes",
67 tier: Tier::Optional,
68 default: || num(262_144.0),
69 },
70 ConfigDefault {
71 key: "ask.timeout_ms",
72 tier: Tier::Optional,
73 default: || num(30_000.0),
74 },
75 ConfigDefault {
76 key: "ask.daily_cost_cap_usd",
77 tier: Tier::Optional,
78 default: || text(""),
79 },
80 ConfigDefault {
81 key: "ask.audit.include_answer",
82 tier: Tier::Optional,
83 default: || JsonValue::Bool(false),
84 },
85 ConfigDefault {
86 key: "ask.audit.retention_days",
87 tier: Tier::Optional,
88 default: || num(90.0),
89 },
90 ConfigDefault {
91 key: "ask.cache.enabled",
92 tier: Tier::Optional,
93 default: || JsonValue::Bool(false),
94 },
95 ConfigDefault {
96 key: "ask.cache.default_ttl",
97 tier: Tier::Optional,
98 default: || text(""),
99 },
100 ConfigDefault {
101 key: "ask.cache.max_entries",
102 tier: Tier::Optional,
103 default: || num(1024.0),
104 },
105 ConfigDefault {
107 key: "cache.blob.l1_bytes_max",
108 tier: Tier::Critical,
109 default: || num(crate::storage::cache::DEFAULT_BLOB_L1_BYTES_MAX as f64),
110 },
111 ConfigDefault {
112 key: "cache.blob.l2_bytes_max",
113 tier: Tier::Critical,
114 default: || num(crate::storage::cache::DEFAULT_BLOB_L2_BYTES_MAX as f64),
115 },
116 ConfigDefault {
117 key: "cache.blob.max_namespaces",
118 tier: Tier::Critical,
119 default: || num(crate::storage::cache::DEFAULT_BLOB_MAX_NAMESPACES as f64),
120 },
121 ConfigDefault {
127 key: "storage.binary_document_body",
128 tier: Tier::Optional,
129 default: || JsonValue::Bool(true),
130 },
131 ConfigDefault {
133 key: "durability.mode",
134 tier: Tier::Critical,
135 default: || text("sync"),
136 },
137 ConfigDefault {
139 key: "runtime.result_cache.backend",
140 tier: Tier::Critical,
141 default: || text("legacy"),
142 },
143 ConfigDefault {
147 key: "runtime.result_cache.enabled",
148 tier: Tier::Critical,
149 default: || JsonValue::Bool(true),
150 },
151 ConfigDefault {
154 key: "runtime.result_cache.ttl_seconds",
155 tier: Tier::Optional,
156 default: || num(30.0),
157 },
158 ConfigDefault {
161 key: "runtime.result_cache.capacity_entries",
162 tier: Tier::Optional,
163 default: || num(1000.0),
164 },
165 ConfigDefault {
167 key: "concurrency.locking.enabled",
168 tier: Tier::Critical,
169 default: || JsonValue::Bool(true),
170 },
171 ConfigDefault {
172 key: "concurrency.locking.deadlock_timeout_ms",
173 tier: Tier::Optional,
174 default: || num(5000.0),
175 },
176 ConfigDefault {
178 key: "storage.wal.max_interval_ms",
179 tier: Tier::Critical,
180 default: || num(10.0),
181 },
182 ConfigDefault {
183 key: "storage.wal.min_batch_size",
184 tier: Tier::Optional,
185 default: || num(4.0),
186 },
187 ConfigDefault {
189 key: "storage.deploy.profile",
190 tier: Tier::Critical,
191 default: || text("embedded"),
192 },
193 ConfigDefault {
194 key: "storage.deploy.packaging",
195 tier: Tier::Critical,
196 default: || text("single-file"),
197 },
198 ConfigDefault {
199 key: "storage.deploy.preset",
200 tier: Tier::Critical,
201 default: || text("embedded"),
202 },
203 ConfigDefault {
204 key: "storage.deploy.replica_count",
205 tier: Tier::Critical,
206 default: || num(0.0),
207 },
208 ConfigDefault {
209 key: "storage.deploy.managed_backup",
210 tier: Tier::Critical,
211 default: || JsonValue::Bool(false),
212 },
213 ConfigDefault {
214 key: "storage.deploy.wal_retention",
215 tier: Tier::Critical,
216 default: || JsonValue::Bool(false),
217 },
218 ConfigDefault {
220 key: "storage.bgwriter.delay_ms",
221 tier: Tier::Critical,
222 default: || num(200.0),
223 },
224 ConfigDefault {
225 key: "storage.bgwriter.max_pages_per_round",
226 tier: Tier::Optional,
227 default: || num(100.0),
228 },
229 ConfigDefault {
230 key: "storage.bgwriter.lru_multiplier",
231 tier: Tier::Optional,
232 default: || num(2.0),
233 },
234 ConfigDefault {
236 key: "storage.bulk_insert.max_buffered_rows",
237 tier: Tier::Optional,
238 default: || num(1000.0),
239 },
240 ConfigDefault {
241 key: "storage.bulk_insert.max_buffered_bytes",
242 tier: Tier::Optional,
243 default: || num(65536.0),
244 },
245 ConfigDefault {
247 key: "storage.hot_update.max_chain_hops",
248 tier: Tier::Optional,
249 default: || num(32.0),
250 },
251 ConfigDefault {
253 key: "storage.btree.lehman_yao",
254 tier: Tier::Critical,
255 default: || JsonValue::Bool(true),
256 },
257 ConfigDefault {
261 key: "ai.ner.backend",
262 tier: Tier::Optional,
263 default: || text("heuristic"),
264 },
265 ConfigDefault {
266 key: "ai.ner.endpoint",
267 tier: Tier::Optional,
268 default: || text(""),
269 },
270 ConfigDefault {
271 key: "ai.ner.model",
272 tier: Tier::Optional,
273 default: || text(""),
274 },
275 ConfigDefault {
276 key: "ai.ner.timeout_ms",
277 tier: Tier::Optional,
278 default: || num(5000.0),
279 },
280 ConfigDefault {
281 key: "ai.ner.fallback",
282 tier: Tier::Optional,
283 default: || text("use_heuristic"),
284 },
285 ConfigDefault {
289 key: "runtime.ai.transport_pool_size",
290 tier: Tier::Optional,
291 default: || num(16.0),
292 },
293 ConfigDefault {
294 key: "runtime.ai.transport_timeout_ms",
295 tier: Tier::Optional,
296 default: || num(30000.0),
297 },
298 ConfigDefault {
299 key: "runtime.ai.transport_retry_max_attempts",
300 tier: Tier::Optional,
301 default: || num(3.0),
302 },
303 ConfigDefault {
304 key: "runtime.ai.transport_retry_base_ms",
305 tier: Tier::Optional,
306 default: || num(500.0),
307 },
308 ConfigDefault {
310 key: "cache.blob.policy.extended",
311 tier: Tier::Optional,
312 default: || text("off"),
313 },
314 ConfigDefault {
319 key: "cache.blob.async_promotion",
320 tier: Tier::Optional,
321 default: || text("off"),
322 },
323];
324
325pub fn default_for(key: &str) -> Option<JsonValue> {
329 MATRIX
330 .iter()
331 .find(|entry| entry.key == key)
332 .map(|entry| (entry.default)())
333}
334
335pub fn tier_for(key: &str) -> Option<Tier> {
338 MATRIX
339 .iter()
340 .find(|entry| entry.key == key)
341 .map(|entry| entry.tier)
342}
343
344pub fn heal_critical_keys(store: &UnifiedStore) {
351 for entry in MATRIX {
354 if entry.tier != Tier::Critical {
355 continue;
356 }
357 if is_key_present(store, entry.key) {
358 continue;
359 }
360 store.set_config_tree(entry.key, &(entry.default)());
361 }
362}
363
364fn is_key_present(store: &UnifiedStore, key: &str) -> bool {
367 let Some(manager) = store.get_collection("red_config") else {
368 return false;
369 };
370 let mut found = false;
371 manager.for_each_entity(|entity| {
372 if let Some(row) = entity.data.as_row() {
373 let entry_key = row.get_field("key").and_then(|v| match v {
374 crate::storage::schema::Value::Text(s) => Some(s.as_ref()),
375 _ => None,
376 });
377 if entry_key == Some(key) {
378 found = true;
379 return false; }
381 }
382 true
383 });
384 found
385}
386
387#[cfg(test)]
388mod tests {
389 use super::*;
390
391 #[test]
392 fn every_matrix_entry_has_a_default_that_resolves() {
393 for entry in MATRIX {
394 let value = (entry.default)();
395 assert!(
396 !matches!(value, JsonValue::Null),
397 "matrix key {} has a null default, defeats self-heal",
398 entry.key
399 );
400 }
401 }
402
403 #[test]
404 fn critical_keys_cover_the_core_guarantees() {
405 let required_critical = [
408 "cache.blob.l1_bytes_max",
409 "cache.blob.l2_bytes_max",
410 "cache.blob.max_namespaces",
411 "durability.mode",
412 "runtime.result_cache.backend",
413 "concurrency.locking.enabled",
414 "storage.wal.max_interval_ms",
415 "storage.deploy.profile",
416 "storage.deploy.packaging",
417 "storage.deploy.preset",
418 "storage.deploy.replica_count",
419 "storage.deploy.managed_backup",
420 "storage.deploy.wal_retention",
421 "storage.bgwriter.delay_ms",
422 "storage.btree.lehman_yao",
423 ];
424 for key in required_critical {
425 assert_eq!(
426 tier_for(key),
427 Some(Tier::Critical),
428 "{key} must be a Tier A (Critical) key",
429 );
430 }
431 }
432
433 #[test]
434 fn optional_keys_are_not_self_healed() {
435 let must_be_optional = [
436 "concurrency.locking.deadlock_timeout_ms",
437 "storage.wal.min_batch_size",
438 "storage.bgwriter.max_pages_per_round",
439 "storage.bgwriter.lru_multiplier",
440 "storage.bulk_insert.max_buffered_rows",
441 "storage.bulk_insert.max_buffered_bytes",
442 "storage.hot_update.max_chain_hops",
443 ];
444 for key in must_be_optional {
445 assert_eq!(tier_for(key), Some(Tier::Optional), "{key} tier mismatch");
446 }
447 }
448
449 #[test]
450 fn unknown_key_returns_none() {
451 assert!(default_for("nonexistent.key").is_none());
452 assert!(tier_for("nonexistent.key").is_none());
453 }
454}