3131
3232from engraphis .core import scoring
3333from engraphis .core .interfaces import MemoryRecord , MemoryType , Scope , SearchFilter
34+ from engraphis .core .poisoning import provenance_is_trusted
3435from engraphis .core .textutil import estimate_tokens , jaccard , tokenize
3536
3637logger = logging .getLogger (__name__ )
@@ -388,8 +389,7 @@ def _inherit_safety(engine, memory_id: str, sources: list[MemoryRecord]) -> tupl
388389 [record .sensitivity or "normal" ] + [(m .sensitivity or "normal" ) for m in sources ],
389390 key = lambda value : _SENSITIVITY_RANK .get (value , len (_SENSITIVITY_RANK )),
390391 )
391- trusted = (bool ((record .provenance or {}).get ("trusted" , True ))
392- and all (bool ((m .provenance or {}).get ("trusted" , True )) for m in sources ))
392+ trusted = provenance_is_trusted (record .provenance ) and _sources_are_trusted (sources )
393393 provenance = dict (record .provenance or {})
394394 provenance ["trusted" ] = trusted
395395 metadata = dict (record .metadata or {})
@@ -405,6 +405,11 @@ def _inherit_safety(engine, memory_id: str, sources: list[MemoryRecord]) -> tupl
405405 return sensitivity , trusted
406406
407407
408+ def _sources_are_trusted (sources : list [MemoryRecord ]) -> bool :
409+ """Require every consolidated source to carry an explicit trust approval."""
410+ return all (provenance_is_trusted (source .provenance ) for source in sources )
411+
412+
408413def _already_consolidated (store , memory_id : str ) -> bool :
409414 return any (link ["relation" ] == "consolidates" for link in store .get_links (memory_id ))
410415
@@ -647,13 +652,14 @@ def _write_digest(engine, cluster: list[MemoryRecord], *, content: str, subject:
647652 now : float ) -> str :
648653 first = cluster [0 ]
649654 importance = max ([m .importance or 0.0 for m in cluster ] + [0.5 ])
655+ trusted = _sources_are_trusted (cluster )
650656 digest_id = engine .remember (
651657 content ,
652658 workspace_id = first .workspace_id , repo_id = first .repo_id ,
653659 mtype = MemoryType .SEMANTIC , scope = Scope (first .scope ),
654660 title = f"Consolidated: { subject } " [:200 ], importance = importance ,
655661 keywords = _common_tokens (cluster , k = 8 ),
656- metadata = {"provenance" : {"source" : "consolidation" ,
662+ metadata = {"provenance" : {"source" : "consolidation" , "trusted" : trusted ,
657663 "consolidates" : [m .id for m in cluster ]}},
658664 resolve_conflicts = False , # the digest is new by construction
659665 )
@@ -682,12 +688,14 @@ def _write_structured_digests(engine, cluster: list[MemoryRecord], facts: list[d
682688 continue
683689 sources = [source_by_id [source_id ] for source_id in fact_source_ids ]
684690 first = sources [0 ]
691+ trusted = _sources_are_trusted (sources )
685692 cited_sources .update (fact_source_ids )
686693 base_importance = max ([memory .importance or 0.0 for memory in sources ] + [0.5 ])
687694 importance = max (base_importance , float (fact .get ("importance" ) or 0.0 ))
688695 metadata = {
689696 "provenance" : {
690697 "source" : "structured_consolidation" ,
698+ "trusted" : trusted ,
691699 "consolidates" : fact_source_ids ,
692700 "source_ids" : fact_source_ids ,
693701 "confidence" : fact .get ("confidence" , 0.0 ),
@@ -826,13 +834,15 @@ def _write_profile(engine, name: str, etype: str, sources: list[MemoryRecord],
826834 * , content : str , now : float ) -> str :
827835 first = sources [0 ]
828836 importance = max ([m .importance or 0.0 for m in sources ] + [0.6 ])
837+ trusted = _sources_are_trusted (sources )
829838 profile_id = engine .remember (
830839 content ,
831840 workspace_id = first .workspace_id , repo_id = first .repo_id ,
832841 mtype = MemoryType .SEMANTIC , scope = Scope (first .scope ),
833842 title = f"Profile: { name } " [:200 ], importance = importance ,
834843 keywords = [name ] + _common_tokens (sources , k = 6 ),
835- metadata = {"provenance" : {"source" : "profile_consolidation" , "entity" : name ,
844+ metadata = {"provenance" : {"source" : "profile_consolidation" , "trusted" : trusted ,
845+ "entity" : name ,
836846 "etype" : etype , "profiles" : [m .id for m in sources ]}},
837847 resolve_conflicts = False , # a profile is new by construction
838848 )
0 commit comments