//! CHRONIC #2 enforcement seal (ultra-fuzz run-6 --deep). //! //! The tombstone filter (`deleted_at IS NULL`) was opt-in per query and drifted //! across runs: a new read of the raw `samples` table that forgot the filter //! leaked deleted samples into tag/collection/mirror views. The `live_samples` //! view centralizes the filter, but a view alone does not *prevent* a new raw //! `FROM samples` listing from drifting back in. //! //! This test makes that drift a build failure: every production read of the raw //! `samples` table must either go through `live_samples` (auto-filtered) or carry //! an explicit `tombstone-ok: ` justification within 3 lines. A new //! unfiltered `FROM samples` listing read fails here until the author routes it //! through the view or marks it, a visible, reviewed decision, not a silent //! regression. //! //! Exemptions, by construction: //! - `DELETE FROM samples` (a write, not a read). //! - The `CREATE VIEW live_samples` definition itself. //! - `#[cfg(test)]` modules (they legitimately assert raw table state). This //! assumes the repo convention of test modules at file end. use std::fs; use std::path::{Path, PathBuf}; /// True if `line` reads from the raw `samples` table (word-bounded), i.e. not /// `live_samples` and not `samples_*` (e.g. `samples_fts`, `sample_features`). fn reads_raw_samples(line: &str) -> bool { const NEEDLE: &str = "FROM samples"; let mut idx = 0; while let Some(pos) = line[idx..].find(NEEDLE) { let after = idx + pos + NEEDLE.len(); let boundary = line.as_bytes().get(after); let is_word = boundary.is_some_and(|&c| c.is_ascii_alphanumeric() || c == b'_'); if !is_word { return true; // exact table `samples`, not `samples_...` } idx = after; } false } #[test] fn tombstone_filter_seal() { let src = Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); let mut stack = vec![src]; let mut violations: Vec = Vec::new(); while let Some(dir) = stack.pop() { for entry in fs::read_dir(&dir).unwrap() { let path: PathBuf = entry.unwrap().path(); if path.is_dir() { stack.push(path); continue; } if path.extension().and_then(|e| e.to_str()) != Some("rs") { continue; } let text = fs::read_to_string(&path).unwrap(); let lines: Vec<&str> = text.lines().collect(); // Test modules (conventionally at file end) legitimately read raw rows. let end = lines .iter() .position(|l| l.contains("#[cfg(test)]")) .unwrap_or(lines.len()); for (i, line) in lines[..end].iter().enumerate() { if !reads_raw_samples(line) || line.contains("DELETE FROM samples") { continue; } let lo = i.saturating_sub(3); let window = lines[lo..=i].join("\n"); if window.contains("tombstone-ok") || window.contains("CREATE VIEW") { continue; } let rel = path .strip_prefix(env!("CARGO_MANIFEST_DIR")) .unwrap_or(&path); violations.push(format!("{}:{} {}", rel.display(), i + 1, line.trim())); } } } assert!( violations.is_empty(), "CHRONIC #2 seal: raw `FROM samples` read(s) without `live_samples` or a \ `tombstone-ok` justification:\n {}\n\nRoute visible-sample reads through \ `FROM live_samples`, or add a `tombstone-ok: ` comment within 3 \ lines if the raw access is intentional (point-lookup, tombstone sweep).", violations.join("\n ") ); }