pub mod lsif_import;
pub mod snapshot;
pub mod store;
pub use lsif_import::LsifImportStats;
pub use snapshot::{GraphDigest, LawGraphSnapshot};
pub trait SemanticLawGraph: Send + Sync {
fn load_snapshot(&self, snapshot: LawGraphSnapshot) -> Result<GraphDigest, String>;
fn query_invariants(&self, scope: &str) -> Result<Vec<String>, String>;
fn query_witnesses(&self, claim_id: &str) -> Result<Vec<String>, String>;
fn query_repairs(&self, diagnostic_code: &str) -> Result<Vec<String>, String>;
fn import_lsif_snapshot(
&self,
lsif_path: &std::path::Path,
graph_name: &str,
) -> anyhow::Result<LsifImportStats>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn oxigraph_boundary_held() {
fn _assert_impl<T: SemanticLawGraph>() {}
_assert_impl::<crate::runtime::control_plane::semantic_graph::store::OxigraphStore>();
}
#[test]
fn snapshot_load_returns_digest() {
let store = store::OxigraphStore::default();
let nquads = "<urn:a> <urn:b> \"c\" .\n";
let snapshot = LawGraphSnapshot::new(nquads, "test");
let expected_digest = snapshot.digest();
let actual_digest = store.load_snapshot(snapshot).unwrap();
assert_eq!(
expected_digest, actual_digest,
"digest must match snapshot content"
);
}
#[test]
fn empty_store_returns_empty_query_results() {
let store = store::OxigraphStore::default();
let result = store.query_invariants("nonexistent-scope").unwrap();
assert!(result.is_empty(), "empty store must return no invariants");
let repairs = store.query_repairs("LSPMAX-ANDON-001").unwrap();
assert!(repairs.is_empty(), "empty store must return no repairs");
}
#[test]
fn oxigraph_not_on_hot_path() {
let sync_rs_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src")
.join("language_server")
.join("impls")
.join("sync.rs");
let sync_rs = std::fs::read_to_string(&sync_rs_path).expect("Could not read sync.rs");
for (i, line) in sync_rs.lines().enumerate() {
let line = line.trim();
if line.starts_with("//") || line.is_empty() {
continue;
}
if line.contains("SemanticLawGraph")
|| line.contains("import_lsif_snapshot")
|| line.contains("oxigraph")
{
panic!(
"OXIGRAPH_NOT_ON_HOT_PATH violated in sync.rs at line {}: {}",
i + 1,
line
);
}
}
}
}