pub struct MemoryStore { /* private fields */ }Implementations§
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn calibration(&self, family: Option<&str>) -> CalibrationReport
pub fn calibration(&self, family: Option<&str>) -> CalibrationReport
Calibration of every family, or of one family.
Sourcepub fn calibration_report(&self, filter: FamilyFilter<'_>) -> CalibrationReport
pub fn calibration_report(&self, filter: FamilyFilter<'_>) -> CalibrationReport
Calibration of the families filter selects; a prefix filter adds pooled rows.
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn active_conflicts(&self) -> Vec<ActiveConflict>
pub fn active_conflicts(&self) -> Vec<ActiveConflict>
Every claim key whose active traces carry more than one normalized value. Conflicts are derived from current state on every call, so a supersession or purge resolves them without any extra event. Sensitive traces are left out unless the policy allows them.
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn consolidation_proposals(&self) -> Vec<ConsolidationProposal>
pub fn consolidation_proposals(&self) -> Vec<ConsolidationProposal>
Quiet Replay: generate evidence-preserving consolidation proposals. This never writes a new belief automatically.
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn focus(&self, query: &RecallQuery) -> FocusCapsule
pub fn focus(&self, query: &RecallQuery) -> FocusCapsule
Start a working set from one recall, bounded by the policy’s working_set_limit.
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn open(path: impl AsRef<Path>, policy: KernelPolicy) -> Result<Self>
pub fn open(path: impl AsRef<Path>, policy: KernelPolicy) -> Result<Self>
Open a store, creating the file (and parent directories) when it does not exist.
Use this for commands that write. Read-only commands should use Self::open_existing.
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}
239
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}
386
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn open_existing(
path: impl AsRef<Path>,
policy: KernelPolicy,
) -> Result<Self>
pub fn open_existing( path: impl AsRef<Path>, policy: KernelPolicy, ) -> Result<Self>
Open a store that must already exist. A mistyped path is an error, not an empty store.
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}
239
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}
386
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn remember(&mut self, trace: Trace) -> Result<(Trace, Vec<ClaimConflict>)>
pub fn remember(&mut self, trace: Trace) -> Result<(Trace, Vec<ClaimConflict>)>
Examples found in repository?
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}
386
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn remember_many(
&mut self,
traces: Vec<Trace>,
) -> Result<Vec<(Trace, Vec<ClaimConflict>)>>
pub fn remember_many( &mut self, traces: Vec<Trace>, ) -> Result<Vec<(Trace, Vec<ClaimConflict>)>>
Append several traces as one batch: one lock, one validation pass, one write, so either
every trace is stored or none is. Each trace gets the same checks as Self::remember
against the stored state; an outcome must resolve a prediction that is already stored.
Conflicts are reported against stored traces, not between traces of the same batch.
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}pub fn fulfill(&mut self, id: impl Into<String>) -> Result<()>
Sourcepub fn purge(
&mut self,
id: impl Into<String>,
reason: impl Into<String>,
) -> Result<()>
pub fn purge( &mut self, id: impl Into<String>, reason: impl Into<String>, ) -> Result<()>
Tombstone a trace: it leaves recall, consolidation, and commitments. The content stays in the append-only ledger; this is not erasure.
Sourcepub fn get(&self, id: &str) -> Option<&TraceEntry>
pub fn get(&self, id: &str) -> Option<&TraceEntry>
Examples found in repository?
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn all(&self) -> impl Iterator<Item = &TraceEntry>
pub fn all(&self) -> impl Iterator<Item = &TraceEntry>
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}
239
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}pub fn active_traces(&self) -> impl Iterator<Item = &Trace>
Sourcepub fn policy(&self) -> &KernelPolicy
pub fn policy(&self) -> &KernelPolicy
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}Sourcepub fn record_count(&self) -> usize
pub fn record_count(&self) -> usize
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}
386
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}pub fn records(&self) -> &[LedgerRecord]
Sourcepub fn head(&self) -> Option<LedgerHead>
pub fn head(&self) -> Option<LedgerHead>
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}Sourcepub fn head_path(&self) -> PathBuf
pub fn head_path(&self) -> PathBuf
Examples found in repository?
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn verify(&self) -> Result<()>
pub fn verify(&self) -> Result<()>
Integrity check. Errors on any chain break; returns Ok(()) only when the report is ok.
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}
239
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}
214
215// Specified, platform-independent SplitMix64; never a cryptographic RNG.
216struct Rng(u64);
217impl Rng {
218 fn next(&mut self) -> u64 {
219 self.0 = self.0.wrapping_add(0x9e3779b97f4a7c15);
220 let mut x = self.0;
221 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
222 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
223 x ^ (x >> 31)
224 }
225 fn unit(&mut self) -> f64 {
226 (self.next() % 10001) as f64 / 10000.0
227 }
228}
229
230fn option(name: &str, a: f64, b: f64) -> DecisionOption {
231 DecisionOption {
232 name: name.into(),
233 description: None,
234 scores: BTreeMap::from([("a".into(), a), ("b".into(), b)]),
235 model_scores: BTreeMap::new(),
236 evidence_confidence: 1.0,
237 hard_blocks: vec![],
238 reversible: false,
239 }
240}
241
242fn decisions(cases: usize, seed: u64) -> Result<Value> {
243 if cases < 6 {
244 return Err("at least 6 cases required to exercise every family".into());
245 }
246 let mut rng = Rng(seed);
247 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
248 let mut failures = Vec::new();
249 let mut violations = 0;
250 let start = Instant::now();
251 for i in 0..cases {
252 let mut a = option("a", rng.unit(), rng.unit());
253 let mut b = option("b", rng.unit(), rng.unit());
254 let family;
255 let mut expected: Option<Option<String>> = None;
256 match i % 6 {
257 0 => {
258 family = "high_score_hard_block";
259 a.scores.values_mut().for_each(|s| *s = 1.0);
260 a.hard_blocks.push("no authorization".into());
261 expected = Some(Some("b".into()));
262 }
263 1 => {
264 family = "all_blocked";
265 a.hard_blocks.push("privacy".into());
266 b.hard_blocks.push("consent".into());
267 expected = Some(None);
268 }
269 2 => {
270 family = "complete_score_oracle";
271 let sum_a: f64 = a.scores.values().sum();
272 let sum_b: f64 = b.scores.values().sum();
273 expected = Some(Some(if sum_a >= sum_b { "a" } else { "b" }.into()));
274 }
275 3 => {
276 family = "unknowns_and_model_estimates";
277 a.scores.clear();
278 a.model_scores.insert("a".into(), rng.unit());
279 }
280 4 => {
281 family = "reversibility_band";
282 let top = 0.5 + rng.unit() * 0.4;
283 let gap = if rng.next().is_multiple_of(2) {
284 0.01
285 } else {
286 0.03
287 };
288 a.scores.values_mut().for_each(|s| *s = top);
289 a.evidence_confidence = 0.1;
290 b.scores.values_mut().for_each(|s| *s = top - gap);
291 b.reversible = true;
292 expected = Some(Some(if gap < 0.02 { "b" } else { "a" }.into()));
293 }
294 _ => {
295 family = "invalid_numeric_input";
296 a.scores.insert("a".into(), 1.01 + rng.unit());
297 }
298 }
299 *counts.entry(family).or_default() += 1;
300 let frame = DecisionFrame {
301 question: "synthetic decision".into(),
302 criteria: ["a", "b"]
303 .into_iter()
304 .map(|id| Criterion {
305 id: id.into(),
306 weight: 1.0,
307 description: id.into(),
308 })
309 .collect(),
310 options: vec![a, b],
311 };
312 let actual = evaluate(&frame);
313 let mut reasons = Vec::new();
314 if family == "invalid_numeric_input" {
315 if actual.is_ok() {
316 reasons.push("invalid input admitted");
317 }
318 } else if let Ok(answer) = &actual {
319 if let Some(expected) = expected {
320 if answer.recommended != expected {
321 reasons.push("wrong recommendation");
322 }
323 }
324 if let Some(name) = &answer.recommended {
325 if frame
326 .options
327 .iter()
328 .any(|o| &o.name == name && !o.hard_blocks.is_empty())
329 {
330 reasons.push("hard-blocked option selected");
331 }
332 }
333 if family == "unknowns_and_model_estimates" {
334 let ranked = answer.ranking.iter().find(|o| o.name == "a").unwrap();
335 if ranked.coverage != 0.0
336 || ranked.evidence_interval != [0.0, 1.0]
337 || ranked.missing_criteria != ["b"]
338 || answer.decisive
339 {
340 reasons.push("unknown evidence hidden or model guess counted as evidence");
341 }
342 }
343 let mut permuted = frame.clone();
344 permuted.options.reverse();
345 permuted.question = "irrelevant wording changed".into();
346 let other = evaluate(&permuted)?;
347 if answer.recommended != other.recommended
348 || serde_json::to_value(&answer.ranking)? != serde_json::to_value(&other.ranking)?
349 {
350 reasons.push("order or irrelevant text changed result");
351 }
352 } else {
353 reasons.push("valid frame rejected");
354 }
355 if !reasons.is_empty() {
356 violations += 1;
357 if failures.len() < 20 {
358 failures.push(
359 json!({"case_index": i, "family": family, "reasons": reasons,
360 "frame": frame, "actual": actual.as_ref().ok()}),
361 );
362 }
363 }
364 }
365 Ok(
366 json!({"kind": "synthetic_decision_invariants", "seed": seed, "rng": "splitmix64",
367 "cases": cases, "families": counts, "violations": violations,
368 "violation_rate": violations as f64 / cases as f64, "ok": violations == 0,
369 "elapsed_ms": ms(start), "counterexamples": failures,
370 "limits": ["Generated families are not real decision-quality labels or a proof over all inputs.",
371 "Metamorphic checks keep criteria fixed; weight perturbations require separate expectations."]}),
372 )
373}
374
375fn committed_child(dir: &Path) -> Result<()> {
376 let path = fresh(dir)?;
377 let mut store = MemoryStore::open(path, KernelPolicy::default())?;
378 store.remember_many((0..50).map(trace).collect())?;
379 println!("committed:50");
380 io::stdout().flush()?;
381 // Parent kills us after the acknowledged commit; this is not an in-flight crash claim.
382 loop {
383 std::thread::park();
384 }
385}
386
387fn recovery(dir: &Path) -> Result<Value> {
388 fs::create_dir(dir)?;
389 let child_dir = dir.join("committed");
390 let mut child = Command::new(std::env::current_exe()?)
391 .args(["committed-child", "--dir"])
392 .arg(&child_dir)
393 .stdin(Stdio::null())
394 .stdout(Stdio::piped())
395 .spawn()?;
396 let mut ack = String::new();
397 let read_result = io::BufReader::new(child.stdout.take().unwrap()).read_line(&mut ack);
398 let kill_result = child.kill();
399 let wait_result = child.wait();
400 read_result?;
401 kill_result?;
402 wait_result?;
403 if ack.trim() != "committed:50" {
404 return Err("child did not acknowledge commit".into());
405 }
406 let path = child_dir.join("memory.jsonl");
407 let start = Instant::now();
408 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
409 store.verify()?;
410 let restart_ms = ms(start);
411 let acknowledged_survived =
412 store.record_count() == 50 && (0..50).all(|i| store.get(&format!("sample-{i}")).is_some());
413 let head_path = store.head_path();
414 drop(store);
415 let original = fs::read(&path)?;
416 let original_head = fs::read(head_path)?;
417 let copied_store = |name: &str, bytes: &[u8]| -> Result<PathBuf> {
418 let target = fresh(&dir.join(name))?;
419 let store = MemoryStore::open(&target, KernelPolicy::default())?;
420 let target_head = store.head_path();
421 drop(store);
422 fs::write(&target, bytes)?;
423 fs::write(target_head, &original_head)?;
424 Ok(target)
425 };
426 let torn = copied_store("torn", &original)?;
427 OpenOptions::new()
428 .append(true)
429 .open(&torn)?
430 .write_all(b"{\"seq\":")?;
431 let mut store = MemoryStore::open_existing(&torn, KernelPolicy::default())?;
432 store.remember(trace(50))?;
433 store.verify()?;
434 let torn_repaired = store.record_count() == 51;
435 let mut edited = String::from_utf8(original.clone())?;
436 edited = edited.replacen("deployment observation", "deployment fabrication", 1);
437 let tampered = copied_store("edited", edited.as_bytes())?;
438 let rejected = |path: &Path| match MemoryStore::open_existing(path, KernelPolicy::default()) {
439 Err(_) => true,
440 Ok(store) => store.verify().is_err(),
441 };
442 let edit_detected = rejected(&tampered);
443 let last = original[..original.len() - 1]
444 .iter()
445 .rposition(|b| *b == b'\n')
446 .unwrap()
447 + 1;
448 let truncated = copied_store("truncated", &original[..last])?;
449 let truncation_detected = rejected(&truncated);
450 Ok(
451 json!({"kind": "synthetic_recovery", "acknowledged_records": 50,
452 "acknowledged_survived": acknowledged_survived, "restart_ms": restart_ms,
453 "torn_tail_repaired": torn_repaired, "edit_detected": edit_detected,
454 "truncation_detected": truncation_detected,
455 "ok": acknowledged_survived && torn_repaired && edit_detected && truncation_detected,
456 "limits": ["Process killed after an acknowledged commit, not during fsync or head replacement.",
457 "Torn tail, edit and truncation are injected into separate copies.",
458 "This does not simulate power loss or an attacker rewriting both ledger and head."]}),
459 )
460}Sourcepub fn verify_report(&self, expected_head: Option<&str>) -> Result<VerifyReport>
pub fn verify_report(&self, expected_head: Option<&str>) -> Result<VerifyReport>
Full verification report. expected_head pins the latest hash (for example a value kept
in CI or in git) so a wholesale re-chain by someone with write access is detected. When the
loaded ledger holds records past its head snapshot, this waits for in-flight writes (a
shared lock on the <store>.lock sidecar) before reporting them as unacknowledged.
Sourcepub fn accept_tail(&mut self) -> Result<TailAcceptance>
pub fn accept_tail(&mut self) -> Result<TailAcceptance>
Acknowledge records appended after the head file (after inspecting them): the head moves
to the end of the ledger and writes are allowed again. Unlike Self::reset_head this
accepts only appended records. It refuses when records were removed or rewritten, when the
head file is unreadable, and when there is no head file to extend.
Sourcepub fn reset_head(&mut self) -> Result<Option<LedgerHead>>
pub fn reset_head(&mut self) -> Result<Option<LedgerHead>>
Explicitly accept the current ledger as the new head (after a deliberate repair).
Sourcepub fn set_nonblocking_writes(&mut self, nonblocking: bool)
pub fn set_nonblocking_writes(&mut self, nonblocking: bool)
Make writes fail immediately when another process holds the writer lock, instead of waiting. For callers such as the Stop hook that must never stall on a busy store.
pub fn lock_path(&self) -> PathBuf
Source§impl MemoryStore
impl MemoryStore
pub fn commitments_due(&self, now_ms: u64, within_ms: u64) -> Vec<CommitmentDue>
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn recall(&self, query: &RecallQuery) -> Vec<RecallResult>
pub fn recall(&self, query: &RecallQuery) -> Vec<RecallResult>
Examples found in repository?
144fn retrieve(corpus: &Path, queries: &Path, dir: &Path, dataset: &str, k: usize) -> Result<()> {
145 if !(1..=100).contains(&k) || dataset.trim().is_empty() {
146 return Err("k must be 1..100 and dataset must be nonempty".into());
147 }
148 let policy = KernelPolicy {
149 recall_limit: k,
150 ..KernelPolicy::default()
151 };
152 let path = fresh(dir)?;
153 let source = format!("beir:{dataset}");
154 let mut store = MemoryStore::open(&path, policy.clone())?;
155 let mut baseline = Bm25::default();
156 let mut ids = HashSet::new();
157 let mut rejected = Vec::new();
158 let mut batch = Vec::new();
159 let mut baseline_index_ms = 0.0;
160 let ingest = Instant::now();
161 for line in BufReader::new(File::open(corpus)?).lines() {
162 let doc: Document = serde_json::from_str(&line?)?;
163 if doc.id.trim().is_empty() || !ids.insert(doc.id.clone()) {
164 return Err("empty or duplicate document id".into());
165 }
166 let trace = make_trace(&doc.id, &doc.content, &source, TraceKind::Observation);
167 if let Err(reason) = trace.validate() {
168 rejected.push(json!({"id": doc.id, "reason": reason.to_string()}));
169 continue;
170 }
171 let timer = Instant::now();
172 baseline.add(&doc);
173 baseline_index_ms += ms(timer);
174 batch.push(trace);
175 if batch.len() == 1000 {
176 store.remember_many(std::mem::take(&mut batch))?;
177 }
178 }
179 if !batch.is_empty() {
180 store.remember_many(batch)?;
181 }
182 let ingest_ms = ms(ingest);
183 store.verify()?;
184 let head_before = serde_json::to_value(store.head())?;
185 drop(store);
186 let start = Instant::now();
187 let store = MemoryStore::open_existing(&path, policy)?;
188 let reopen_ms = ms(start);
189 store.verify()?;
190 let provenance_retained = store
191 .all()
192 .filter(|entry| {
193 let t = &entry.trace;
194 t.provenance.source == source
195 && !t.provenance.verified
196 && t.created_at_ms == CLOCK
197 && t.provenance.observed_at_ms == CLOCK
198 && t.provenance.locator.as_deref() == Some(format!("{source}:{}", t.id).as_str())
199 })
200 .count();
201 if store.record_count() != baseline.ids.len()
202 || provenance_retained != baseline.ids.len()
203 || serde_json::to_value(store.head())? != head_before
204 {
205 return Err("replay, head or provenance invariant failed".into());
206 }
207 emit(
208 json!({"kind": "loaded", "corpus_total": ids.len(), "admitted": baseline.ids.len(),
209 "rejected": rejected, "provenance_retained": provenance_retained,
210 "ingest_both_ms": ingest_ms, "bm25_index_ms": baseline_index_ms, "reopen_ms": reopen_ms,
211 "policy": store.policy(), "bm25": {"k1": 1.2, "b": 0.75}, "query_clock_ms": CLOCK}),
212 )?;
213 let mut query_ids = HashSet::new();
214 for line in BufReader::new(File::open(queries)?).lines() {
215 let q: Query = serde_json::from_str(&line?)?;
216 if q.id.trim().is_empty() || !query_ids.insert(q.id.clone()) {
217 return Err("invalid query id".into());
218 }
219 let mut query = RecallQuery::new(&q.text);
220 query.now_ms = CLOCK;
221 query.limit = k;
222 let start = Instant::now();
223 let recalled = store.recall(&query);
224 let hikmah_ms = ms(start);
225 let start = Instant::now();
226 let bm25 = baseline.search(&q.text, k);
227 let bm25_ms = ms(start);
228 let hikmah: Vec<_> = recalled.into_iter().map(|r| json!({
229 "id": r.trace.id, "score": r.score, "duplicates_folded": r.duplicates,
230 "provenance_source": r.trace.provenance.source, "verified": r.trace.provenance.verified,
231 })).collect();
232 emit(
233 json!({"kind": "query", "id": q.id, "hikmah": hikmah, "bm25": bm25,
234 "hikmah_ms": hikmah_ms, "bm25_ms": bm25_ms}),
235 )?;
236 }
237 emit(json!({"kind": "finished", "queries": query_ids.len()}))
238}
239
240fn corrections(dir: &Path, cases: usize) -> Result<()> {
241 if !(1..=10000).contains(&cases) {
242 return Err("cases must be 1..10000".into());
243 }
244 let path = fresh(dir)?;
245 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
246 let mut stale_hits = 0;
247 let mut latest_hits = 0;
248 let mut model_rejections = 0;
249 let mut link_hits = 0;
250 let mut expected = Vec::new();
251 for i in 0..cases {
252 let subject = format!("service{i}topic");
253 let key = format!("{subject}.region");
254 let mut predecessor = None;
255 for (version, value) in ["oldregion", "middlezone", "newlocation"]
256 .iter()
257 .enumerate()
258 {
259 let id = format!("{i}-v{version}");
260 let mut trace = make_trace(
261 &id,
262 &format!("{subject} {value}"),
263 "synthetic:correction",
264 if version == 0 {
265 TraceKind::Belief
266 } else {
267 TraceKind::Correction
268 },
269 );
270 trace.claim_key = Some(key.clone());
271 trace.claim_value = Some((*value).into());
272 trace.supersedes = predecessor;
273 store.remember(trace)?;
274 predecessor = Some(id);
275 }
276 let mut malicious = make_trace(
277 &format!("{i}-model"),
278 "invented overwrite",
279 "model:fixture",
280 TraceKind::Correction,
281 );
282 malicious.supersedes = predecessor;
283 model_rejections += usize::from(store.remember(malicious).is_err());
284 let results = store.recall(&RecallQuery::new(&subject));
285 stale_hits += results
286 .iter()
287 .filter(|r| r.trace.id == format!("{i}-v0") || r.trace.id == format!("{i}-v1"))
288 .count();
289 latest_hits += usize::from(results.iter().any(|r| r.trace.id == format!("{i}-v2")));
290 link_hits +=
291 usize::from(results.iter().any(|r| {
292 r.trace.id == format!("{i}-v2") && r.supersedes == Some(format!("{i}-v1"))
293 }));
294 expected.push((subject, format!("{i}-v2")));
295 }
296 let old_only_results = store
297 .recall(&RecallQuery::new("oldregion middlezone"))
298 .len();
299 drop(store);
300 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
301 store.verify()?;
302 let restart_hits = expected
303 .iter()
304 .filter(|(q, id)| {
305 store
306 .recall(&RecallQuery::new(q))
307 .iter()
308 .any(|r| &r.trace.id == id)
309 })
310 .count();
311 let provenance = store
312 .all()
313 .filter(|e| {
314 e.trace.provenance.source == "synthetic:correction" && !e.trace.provenance.verified
315 })
316 .count();
317 let ok = stale_hits == 0
318 && latest_hits == cases
319 && model_rejections == cases
320 && link_hits == cases
321 && old_only_results == 0
322 && restart_hits == cases
323 && provenance == 3 * cases;
324 emit(
325 json!({"kind": "synthetic_corrections", "cases": cases, "ok": ok,
326 "stale_hits": stale_hits, "latest_hits": latest_hits, "supersession_link_hits": link_hits,
327 "model_overwrite_rejections": model_rejections, "old_only_query_results": old_only_results,
328 "latest_hits_after_restart": restart_hits, "provenance_retained": provenance,
329 "limits": ["Generated structured histories; not extracted real incident corrections.",
330 "Subject variants of one generated template, not independent real incidents or a proof across all histories.",
331 "A query matching only retired terms abstains; no semantic alias expansion is implied."]}),
332 )?;
333 if !ok {
334 return Err("correction invariant failure".into());
335 }
336 Ok(())
337}More examples
114fn scale(dir: &Path, records: usize, queries: usize) -> Result<Value> {
115 if records == 0 || queries == 0 {
116 return Err("records and queries must be positive".into());
117 }
118 let path = fresh(dir)?;
119 let mut store = MemoryStore::open(&path, KernelPolicy::default())?;
120 let single_count = records.min(50);
121 let batched = records - single_count;
122 let mut batches = Vec::new();
123 let seed_started = Instant::now();
124 for begin in (0..batched).step_by(1000) {
125 let traces = (begin..(begin + 1000).min(batched)).map(trace).collect();
126 let start = Instant::now();
127 store.remember_many(traces)?;
128 batches.push(ms(start));
129 }
130 let mut appends = Vec::new();
131 for i in batched..records {
132 let t = trace(i);
133 let start = Instant::now();
134 store.remember(t)?;
135 appends.push(ms(start));
136 }
137 let seed_ms = ms(seed_started);
138 let memory_after_seed = rss();
139 let mut recall_ms = Vec::new();
140 let mut hits = 0;
141 let mut returned = 0;
142 let mut result_ids = Vec::new();
143 // Warm up with an exact cue; quality here is a synthetic exact-cue check, not field recall.
144 std::hint::black_box(store.recall(&RecallQuery::new(token(0))));
145 for i in 0..queries {
146 let selected = i * records / queries;
147 let mut query = RecallQuery::new(token(selected));
148 query.now_ms = CLOCK;
149 query.limit = 1;
150 let start = Instant::now();
151 let found = store.recall(&query);
152 recall_ms.push(ms(start));
153 returned += found.len();
154 hits += usize::from(
155 found
156 .first()
157 .is_some_and(|r| r.trace.id == format!("sample-{selected}")),
158 );
159 result_ids.push(found.iter().map(|r| r.trace.id.clone()).collect::<Vec<_>>());
160 }
161 let start = Instant::now();
162 store.verify()?;
163 let verify_ms = ms(start);
164 let before = store.head();
165 drop(store);
166 let start = Instant::now();
167 let store = MemoryStore::open_existing(&path, KernelPolicy::default())?;
168 let replay_ms = ms(start);
169 store.verify()?;
170 let retained = store
171 .all()
172 .filter(|e| {
173 e.trace.provenance.source == "synthetic-kernel-benchmark"
174 && e.trace.provenance.observed_at_ms == CLOCK
175 && !e.trace.provenance.verified
176 })
177 .count();
178 let mut replay_matches = 0;
179 for (i, expected) in result_ids.iter().enumerate() {
180 let mut query = RecallQuery::new(token(i * records / queries));
181 query.now_ms = CLOCK;
182 query.limit = 1;
183 let ids: Vec<_> = store
184 .recall(&query)
185 .into_iter()
186 .map(|r| r.trace.id)
187 .collect();
188 replay_matches += usize::from(ids == *expected);
189 }
190 let head_same = serde_json::to_value(before)? == serde_json::to_value(store.head())?;
191 let ok = store.record_count() == records
192 && retained == records
193 && hits == queries
194 && replay_matches == queries
195 && head_same;
196 Ok(json!({
197 "kind": "synthetic_scale", "ok": ok, "records": records, "queries": queries,
198 "workload": "unclaimed observation traces, unique exact lexical cues, fixed clock",
199 "seed_ms": seed_ms, "batch_size": 1000, "batched_records": batched,
200 "batch_append_ms": quantiles(batches), "single_append_ms": quantiles(appends),
201 "recall_ms": quantiles(recall_ms), "verify_ms": verify_ms, "replay_ms": replay_ms,
202 "exact_cue_hits": hits, "returned": returned, "recall_at_1": hits as f64 / queries as f64,
203 "provenance_retained": retained, "replayed_records": store.record_count(),
204 "recall_replay_matches": replay_matches, "head_unchanged": head_same,
205 "ledger_bytes": fs::metadata(path)?.len(), "memory_after_seed": memory_after_seed,
206 "memory_after_replay": rss(), "policy": store.policy(),
207 "limits": ["Batched seeding does not measure per-record durable append latency.",
208 "Warm filesystem cache; reopening in the same process is not a cold-start measurement.",
209 "No structured claims in this workload; conflict-heavy stores need a separate workload.",
210 "Synthetic exact-cue quality is not semantic or real-world retrieval accuracy.",
211 "RSS is process-wide Linux /proc data; unavailable platforms report null."]
212 }))
213}Source§impl MemoryStore
impl MemoryStore
Sourcepub fn gate_threshold(
&self,
max_false_block: f64,
) -> Result<GateThresholdReport>
pub fn gate_threshold( &self, max_false_block: f64, ) -> Result<GateThresholdReport>
Pair recorded Truth Gate engine predictions (model: sources only) with their outcomes and
choose the engine threshold. Refuses with fewer than MIN_OUTCOMES resolved
predictions, or without both classes.
Source§impl MemoryStore
impl MemoryStore
Sourcepub fn provenance_chain(&self, id: &str) -> Option<TraceLineage>
pub fn provenance_chain(&self, id: &str) -> Option<TraceLineage>
The full provenance chain of one trace: itself, its supersession lineage,
and its unresolved conflicts. None when no trace carries id.