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 {
123 key: "durability.mode",
124 tier: Tier::Critical,
125 default: || text("sync"),
126 },
127 ConfigDefault {
129 key: "runtime.result_cache.backend",
130 tier: Tier::Critical,
131 default: || text("legacy"),
132 },
133 ConfigDefault {
137 key: "runtime.result_cache.enabled",
138 tier: Tier::Critical,
139 default: || JsonValue::Bool(true),
140 },
141 ConfigDefault {
144 key: "runtime.result_cache.ttl_seconds",
145 tier: Tier::Optional,
146 default: || num(30.0),
147 },
148 ConfigDefault {
151 key: "runtime.result_cache.capacity_entries",
152 tier: Tier::Optional,
153 default: || num(1000.0),
154 },
155 ConfigDefault {
157 key: "concurrency.locking.enabled",
158 tier: Tier::Critical,
159 default: || JsonValue::Bool(true),
160 },
161 ConfigDefault {
162 key: "concurrency.locking.deadlock_timeout_ms",
163 tier: Tier::Optional,
164 default: || num(5000.0),
165 },
166 ConfigDefault {
168 key: "storage.wal.max_interval_ms",
169 tier: Tier::Critical,
170 default: || num(10.0),
171 },
172 ConfigDefault {
173 key: "storage.wal.min_batch_size",
174 tier: Tier::Optional,
175 default: || num(4.0),
176 },
177 ConfigDefault {
179 key: "storage.deploy.profile",
180 tier: Tier::Critical,
181 default: || text("embedded"),
182 },
183 ConfigDefault {
184 key: "storage.deploy.packaging",
185 tier: Tier::Critical,
186 default: || text("single-file"),
187 },
188 ConfigDefault {
189 key: "storage.deploy.preset",
190 tier: Tier::Critical,
191 default: || text("embedded"),
192 },
193 ConfigDefault {
194 key: "storage.deploy.replica_count",
195 tier: Tier::Critical,
196 default: || num(0.0),
197 },
198 ConfigDefault {
199 key: "storage.deploy.managed_backup",
200 tier: Tier::Critical,
201 default: || JsonValue::Bool(false),
202 },
203 ConfigDefault {
204 key: "storage.deploy.wal_retention",
205 tier: Tier::Critical,
206 default: || JsonValue::Bool(false),
207 },
208 ConfigDefault {
210 key: "storage.bgwriter.delay_ms",
211 tier: Tier::Critical,
212 default: || num(200.0),
213 },
214 ConfigDefault {
215 key: "storage.bgwriter.max_pages_per_round",
216 tier: Tier::Optional,
217 default: || num(100.0),
218 },
219 ConfigDefault {
220 key: "storage.bgwriter.lru_multiplier",
221 tier: Tier::Optional,
222 default: || num(2.0),
223 },
224 ConfigDefault {
226 key: "storage.bulk_insert.max_buffered_rows",
227 tier: Tier::Optional,
228 default: || num(1000.0),
229 },
230 ConfigDefault {
231 key: "storage.bulk_insert.max_buffered_bytes",
232 tier: Tier::Optional,
233 default: || num(65536.0),
234 },
235 ConfigDefault {
237 key: "storage.hot_update.max_chain_hops",
238 tier: Tier::Optional,
239 default: || num(32.0),
240 },
241 ConfigDefault {
243 key: "storage.btree.lehman_yao",
244 tier: Tier::Critical,
245 default: || JsonValue::Bool(true),
246 },
247 ConfigDefault {
251 key: "ai.ner.backend",
252 tier: Tier::Optional,
253 default: || text("heuristic"),
254 },
255 ConfigDefault {
256 key: "ai.ner.endpoint",
257 tier: Tier::Optional,
258 default: || text(""),
259 },
260 ConfigDefault {
261 key: "ai.ner.model",
262 tier: Tier::Optional,
263 default: || text(""),
264 },
265 ConfigDefault {
266 key: "ai.ner.timeout_ms",
267 tier: Tier::Optional,
268 default: || num(5000.0),
269 },
270 ConfigDefault {
271 key: "ai.ner.fallback",
272 tier: Tier::Optional,
273 default: || text("use_heuristic"),
274 },
275 ConfigDefault {
279 key: "runtime.ai.transport_pool_size",
280 tier: Tier::Optional,
281 default: || num(16.0),
282 },
283 ConfigDefault {
284 key: "runtime.ai.transport_timeout_ms",
285 tier: Tier::Optional,
286 default: || num(30000.0),
287 },
288 ConfigDefault {
289 key: "runtime.ai.transport_retry_max_attempts",
290 tier: Tier::Optional,
291 default: || num(3.0),
292 },
293 ConfigDefault {
294 key: "runtime.ai.transport_retry_base_ms",
295 tier: Tier::Optional,
296 default: || num(500.0),
297 },
298 ConfigDefault {
300 key: "cache.blob.policy.extended",
301 tier: Tier::Optional,
302 default: || text("off"),
303 },
304 ConfigDefault {
309 key: "cache.blob.async_promotion",
310 tier: Tier::Optional,
311 default: || text("off"),
312 },
313];
314
315pub fn default_for(key: &str) -> Option<JsonValue> {
319 MATRIX
320 .iter()
321 .find(|entry| entry.key == key)
322 .map(|entry| (entry.default)())
323}
324
325pub fn tier_for(key: &str) -> Option<Tier> {
328 MATRIX
329 .iter()
330 .find(|entry| entry.key == key)
331 .map(|entry| entry.tier)
332}
333
334pub fn heal_critical_keys(store: &UnifiedStore) {
341 for entry in MATRIX {
344 if entry.tier != Tier::Critical {
345 continue;
346 }
347 if is_key_present(store, entry.key) {
348 continue;
349 }
350 store.set_config_tree(entry.key, &(entry.default)());
351 }
352}
353
354fn is_key_present(store: &UnifiedStore, key: &str) -> bool {
357 let Some(manager) = store.get_collection("red_config") else {
358 return false;
359 };
360 let mut found = false;
361 manager.for_each_entity(|entity| {
362 if let Some(row) = entity.data.as_row() {
363 let entry_key = row.get_field("key").and_then(|v| match v {
364 crate::storage::schema::Value::Text(s) => Some(s.as_ref()),
365 _ => None,
366 });
367 if entry_key == Some(key) {
368 found = true;
369 return false; }
371 }
372 true
373 });
374 found
375}
376
377#[cfg(test)]
378mod tests {
379 use super::*;
380
381 #[test]
382 fn every_matrix_entry_has_a_default_that_resolves() {
383 for entry in MATRIX {
384 let value = (entry.default)();
385 assert!(
386 !matches!(value, JsonValue::Null),
387 "matrix key {} has a null default, defeats self-heal",
388 entry.key
389 );
390 }
391 }
392
393 #[test]
394 fn critical_keys_cover_the_core_guarantees() {
395 let required_critical = [
398 "cache.blob.l1_bytes_max",
399 "cache.blob.l2_bytes_max",
400 "cache.blob.max_namespaces",
401 "durability.mode",
402 "runtime.result_cache.backend",
403 "concurrency.locking.enabled",
404 "storage.wal.max_interval_ms",
405 "storage.deploy.profile",
406 "storage.deploy.packaging",
407 "storage.deploy.preset",
408 "storage.deploy.replica_count",
409 "storage.deploy.managed_backup",
410 "storage.deploy.wal_retention",
411 "storage.bgwriter.delay_ms",
412 "storage.btree.lehman_yao",
413 ];
414 for key in required_critical {
415 assert_eq!(
416 tier_for(key),
417 Some(Tier::Critical),
418 "{key} must be a Tier A (Critical) key",
419 );
420 }
421 }
422
423 #[test]
424 fn optional_keys_are_not_self_healed() {
425 let must_be_optional = [
426 "concurrency.locking.deadlock_timeout_ms",
427 "storage.wal.min_batch_size",
428 "storage.bgwriter.max_pages_per_round",
429 "storage.bgwriter.lru_multiplier",
430 "storage.bulk_insert.max_buffered_rows",
431 "storage.bulk_insert.max_buffered_bytes",
432 "storage.hot_update.max_chain_hops",
433 ];
434 for key in must_be_optional {
435 assert_eq!(tier_for(key), Some(Tier::Optional), "{key} tier mismatch");
436 }
437 }
438
439 #[test]
440 fn unknown_key_returns_none() {
441 assert!(default_for("nonexistent.key").is_none());
442 assert!(tier_for("nonexistent.key").is_none());
443 }
444}