mnemo_core/query/
write_provenance.rs1use uuid::Uuid;
12
13use crate::error::{Error, Result};
14use crate::hash::ChainVerificationResult;
15use crate::model::capability::Capability;
16use crate::model::write_provenance::{
17 WriteFlag, WriteOp, WriteProvenance, verify_provenance_chain,
18};
19use crate::query::MnemoEngine;
20use crate::query::forget::{self, ForgetRequest, ForgetResponse, ForgetStrategy};
21
22impl MnemoEngine {
23 pub(crate) async fn record_write_provenance(
27 &self,
28 memory_id: Uuid,
29 principal: String,
30 capability_id: Option<Uuid>,
31 session_id: Option<String>,
32 op: WriteOp,
33 flags: Vec<WriteFlag>,
34 ) -> Result<()> {
35 if !self.storage.records_write_provenance() {
36 return Ok(());
37 }
38 let prev_hash = self.storage.get_latest_provenance_hash().await?;
39 let prov = WriteProvenance::new(
40 memory_id,
41 principal,
42 capability_id,
43 session_id,
44 op,
45 flags,
46 prev_hash,
47 );
48 self.storage.insert_write_provenance(&prov).await
49 }
50
51 pub fn verify_capability(&self, cap: &Capability) -> Result<()> {
54 let issuer = self.capability_issuer.as_ref().ok_or_else(|| {
55 Error::PermissionDenied(
56 "a capability was presented but no CapabilityIssuer is configured".to_string(),
57 )
58 })?;
59 issuer
60 .verify(cap)
61 .map_err(|e| Error::PermissionDenied(format!("capability rejected: {e}")))
62 }
63
64 pub async fn write_provenance_for(&self, memory_id: Uuid) -> Result<Option<WriteProvenance>> {
66 self.storage.get_write_provenance(memory_id).await
67 }
68
69 pub async fn writes_by_principal(
71 &self,
72 principal: &str,
73 limit: usize,
74 ) -> Result<Vec<WriteProvenance>> {
75 self.storage
76 .list_provenance_by_principal(principal, limit)
77 .await
78 }
79
80 pub async fn writes_by_session(
82 &self,
83 session_id: &str,
84 limit: usize,
85 ) -> Result<Vec<WriteProvenance>> {
86 self.storage
87 .list_provenance_by_session(session_id, limit)
88 .await
89 }
90
91 pub async fn verify_provenance_chain(&self, limit: usize) -> Result<ChainVerificationResult> {
94 let recs = self.storage.list_all_provenance(limit).await?;
95 Ok(verify_provenance_chain(&recs))
96 }
97
98 pub async fn forget_by_principal(
102 &self,
103 principal: &str,
104 strategy: ForgetStrategy,
105 ) -> Result<ForgetResponse> {
106 let ids = self.storage.list_memory_ids_by_principal(principal).await?;
107 self.forget_ids(ids, strategy).await
108 }
109
110 pub async fn forget_by_session(
112 &self,
113 session_id: &str,
114 strategy: ForgetStrategy,
115 ) -> Result<ForgetResponse> {
116 let ids = self.storage.list_memory_ids_by_session(session_id).await?;
117 self.forget_ids(ids, strategy).await
118 }
119
120 async fn forget_ids(&self, ids: Vec<Uuid>, strategy: ForgetStrategy) -> Result<ForgetResponse> {
121 if ids.is_empty() {
122 return Ok(ForgetResponse {
123 forgotten: Vec::new(),
124 errors: Vec::new(),
125 });
126 }
127 let request = ForgetRequest {
128 memory_ids: ids,
129 agent_id: None,
130 strategy: Some(strategy),
131 criteria: None,
132 };
133 forget::execute(self, request).await
134 }
135}