Implement chrs-slurp: Context Intelligence layer with DR curation and Dolt integration
This commit is contained in:
17
chrs-slurp/Cargo.toml
Normal file
17
chrs-slurp/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "chrs-slurp"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
chrs-graph = { path = "../chrs-graph" }
|
||||
ucxl = { path = "../UCXL" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
thiserror = "1.0"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
uuid = { version = "1.0", features = ["v4", "serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
85
chrs-slurp/src/lib.rs
Normal file
85
chrs-slurp/src/lib.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use chrs_graph::{DoltGraph, GraphError};
|
||||
use ucxl::UCXLAddress;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct DecisionRecord {
|
||||
pub id: Uuid,
|
||||
pub author: String,
|
||||
pub reasoning: String,
|
||||
pub citations: Vec<String>, // Serialized UCXL addresses
|
||||
pub timestamp: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SlurpError {
|
||||
#[error("Graph error: {0}")]
|
||||
Graph(#[from] GraphError),
|
||||
#[error("Serialization error: {0}")]
|
||||
Serde(#[from] serde_json::Error),
|
||||
#[error("Validation error: {0}")]
|
||||
ValidationError(String),
|
||||
}
|
||||
|
||||
pub struct CurationEngine {
|
||||
graph: DoltGraph,
|
||||
}
|
||||
|
||||
impl CurationEngine {
|
||||
pub fn new(graph: DoltGraph) -> Self {
|
||||
Self { graph }
|
||||
}
|
||||
|
||||
pub fn curate_decision(&self, dr: DecisionRecord) -> Result<(), SlurpError> {
|
||||
// 1. Validate Citations
|
||||
for citation in &dr.citations {
|
||||
use std::str::FromStr;
|
||||
UCXLAddress::from_str(citation)
|
||||
.map_err(|e| SlurpError::ValidationError(format!("Invalid citation {}: {}", citation, e)))?;
|
||||
}
|
||||
|
||||
// 2. Log DR into Graph (create table if needed handled by insert_node in future,
|
||||
// but for now let's ensure it's there).
|
||||
// If it fails because it exists, that's fine.
|
||||
let _ = self.graph.create_table("curated_decisions", "id VARCHAR(255) PRIMARY KEY, author TEXT, reasoning TEXT, citations TEXT, curated_at TEXT");
|
||||
|
||||
let data = serde_json::json!({
|
||||
"id": dr.id.to_string(),
|
||||
"author": dr.author,
|
||||
"reasoning": dr.reasoning,
|
||||
"citations": serde_json::to_string(&dr.citations)?,
|
||||
"curated_at": dr.timestamp.to_rfc3339()
|
||||
});
|
||||
|
||||
self.graph.insert_node("curated_decisions", data)?;
|
||||
self.graph.commit(&format!("Curation complete for DR: {}", dr.id))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::TempDir;
|
||||
|
||||
#[test]
|
||||
fn test_curation_flow() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let graph = DoltGraph::init(dir.path()).expect("graph init failed");
|
||||
let engine = CurationEngine::new(graph);
|
||||
|
||||
let dr = DecisionRecord {
|
||||
id: Uuid::new_v4(),
|
||||
author: "agent-001".into(),
|
||||
reasoning: "Tested the implementation of SLURP.".into(),
|
||||
citations: vec!["ucxl://system:watcher@local:filesystem/#/UCXL/src/lib.rs".into()],
|
||||
timestamp: Utc::now(),
|
||||
};
|
||||
|
||||
engine.curate_decision(dr).expect("curation failed");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user