Skip to content

[OMEGA-311] feat: provenance-aware memory (remember-claim / query-claims) - #272

Closed
amiroussama wants to merge 1 commit into
singnet:mainfrom
amiroussama:contrib/memory-provenance
Closed

[OMEGA-311] feat: provenance-aware memory (remember-claim / query-claims)#272
amiroussama wants to merge 1 commit into
singnet:mainfrom
amiroussama:contrib/memory-provenance

Conversation

@amiroussama

Copy link
Copy Markdown

Description

Fixes #271. Adds a provenance schema for stored memories so claims carry structured attribution instead of ad-hoc metadata.

  • src/memory_schema.py — schema builders/validators (build_metadata, validate, claim-id) + a provenance-scoped store over the chroma collection (remember_claim_llm / query_claims_text), confidence defaults, min-confidence and supersession-aware filtering.
  • src/memory.mettaremember-claim (agent-emitted ⇒ llm source, default confidence 0.55) and query-claims (recall with inline provenance) tools.
  • src/rag.py — knowledge-prior chunks now carry the full provenance schema via build_metadata, keeping the legacy breadcrumb/type/time keys for back-compat. (Upstream's exception logging in init_knowledge/_get_stored_hash is left unchanged.)

Standalone: depends only on the existing rag._get_collection.

How Has This Been Tested?

Autotests/test_memory_schema.py (pure-Python; chroma-backed cases use an in-memory chromadb.EphemeralClient() and self-skip when chromadb is absent), registered in run_mandatory: schema shape + atoms_json, confidence defaults/overrides, validation, stable claim-id, where-clause scoping + supersession, filter parity, and round-trip provenance (remember → query, min-confidence exclusion, supersession exclusion, source-type filter). Run: cd Autotests && python3 test_memory_schema.py → passes (chroma cases skipped on hosts without chromadb; exercised in the Docker CI). The memory.metta tool wiring runs in the MeTTa/Docker runtime and is covered by build / common CI.

Checklist

  • The code generated by LLM is reviewed by the PR creator
  • Self-review completed
  • Test scenarios above are passed with the version of the code from PR

Adds a provenance schema for stored memories so claims carry structured
attribution — claim text, source, source_type, confidence, created_at,
atoms_json, and supersession links — instead of ad-hoc metadata.

- src/memory_schema.py: schema builders/validators + a provenance-scoped store
  over the chroma collection (remember_claim_llm / query_claims_text),
  confidence defaults, and supersession filtering.
- src/memory.metta: `remember-claim` / `query-claims` MeTTa tools.
- src/rag.py: knowledge-prior chunks now carry the full provenance schema via
  build_metadata (keeps the legacy breadcrumb/type/time keys for back-compat).
- Autotests/test_memory_schema.py (pure-Python; chroma-backed cases self-skip
  without chromadb) + run_mandatory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vsbogd vsbogd added the plugin label Jul 23, 2026
@alyona-snet alyona-snet changed the title feat: provenance-aware memory (remember-claim / query-claims) [OMEGA-311] feat: provenance-aware memory (remember-claim / query-claims) Aug 5, 2026
@alyona-snet alyona-snet added the in-jira The issue has been accepted for fixing label Aug 5, 2026

@paul-v-snet paul-v-snet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has several critical issues that need to be addressed before further review can be performed.

In addition, I have concerns about its compatibility with #284, which introduces the Context Frames mechanism and also changes the way ChromaDB is handled.

@alyona-snet, please consider whether it would be better to close this PR.

Comment thread Autotests/run_mandatory
mock/test_transition_metta_to_remember_mock.py
mock/test_transition_pin_to_remember_mock.py
mock_websocket/test_wschat_unit.py
test_memory_schema.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit-tests location: Autotests/unit/, so please move this.

Comment thread src/memory.metta
Comment on lines +69 to +74
(= (remember-claim $claim)
(progn (py-call (memory_schema.remember_claim_llm $claim (embed $claim)))
REMEMBER-CLAIM-SUCCESS))

(= (query-claims $str)
(py-call (memory_schema.query_claims_text (embed $str) (maxRecallItems))))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both expressions were not added to getStaticSkills and LLM_COMMANDS, so the agent will never see and use them.

Comment on lines +117 to +118
# NOTE: the action-protocol round-trip test for the remember-claim / query-claims tools lives
# with the action_protocol module (not part of this memory-provenance change).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned:

The memory.metta tool wiring runs in the MeTTa/Docker runtime and is covered by build / common CI.

But this is not the case - the repository does not contain tests covering the MeTTa tools added in this PR, and your request does not include adding such tests.

Comment thread src/memory_schema.py
Comment on lines +191 to +216
def remember_claim(claim, embedding, source_type, source=None, confidence=None,
session_id="", turn_id=None, atoms=None, supersedes=None):
"""Write a structured, provenance-tagged claim to the shared memories collection.

``embedding`` is computed MeTTa-side (``(embed $claim)``), mirroring ``remember``.
Returns the stable claim id.
"""
meta = build_metadata(
claim, source or f"{source_type}:adhoc", source_type, confidence=confidence,
session_id=session_id, turn_id=turn_id, atoms=atoms, supersedes=supersedes,
)
err = validate_metadata(meta)
if err:
raise ValueError(f"invalid claim metadata: {err}")
cid = claim_id(meta)
coll = _collection()
coll.upsert(ids=[cid], embeddings=[embedding], documents=[claim], metadatas=[meta])
# If this claim supersedes an earlier record, mark that record superseded so it is
# excluded from default recall. Best-effort: ignore if the id is absent.
if supersedes:
try:
coll.update(ids=[supersedes], metadatas=[{"superseded": True}])
except Exception as exc: # pragma: no cover - defensive
print(f"[memory_schema] WARNING could not mark superseded id={supersedes}: {exc}", flush=True)
print(f"[memory_schema] REMEMBER_CLAIM id={cid} source_type={source_type} confidence={meta['confidence']}", flush=True)
return cid

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember-claim accepts only $claim and calls only remember_claim_llm(claim, embedding), which never passes supersedes/session_id/turn_id. As a result, this mechanism does not work, and the agent will never be able to supersede an existing claim.

What use cases did you have in mind for this mechanism?

Comment thread src/memory_schema.py
Comment on lines +103 to +108
def claim_id(meta):
"""Deterministic, stable id so re-remembering an identical claim is idempotent."""
digest = hashlib.sha1((meta.get("claim") or "").encode("utf-8")).hexdigest()[:10]
turn = meta.get("turn_id", "")
src = re.sub(r"[^A-Za-z0-9_.-]", "_", str(meta.get("source") or "src"))
return f"claim_{src}_{turn}_{digest}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason as R191-R216:

The agent does not manage sessions or pass their IDs, so in practice two different claims from different sessions will be treated as the same claim and overwrite each other. In this case, idempotency creates a potential data leakage risk.

This mechanism should be designed more carefully

Comment thread src/memory_schema.py
Comment on lines +219 to +242
def query_claims(embedding, n=5, filters=None):
"""Similarity query returning provenance metadata.

Returns a list of ``{document, metadata, distance}``. By default only
provenance-bearing, non-superseded records are returned (see :func:`build_where`),
so legacy memories / hash sentinels and superseded claims are excluded. Pass
``filters={"any_source": True}`` / ``{"include_superseded": True}`` to widen.
"""
where = build_where(filters)
kwargs = {"query_embeddings": [embedding], "n_results": int(n)}
if where is not None:
kwargs["where"] = where
res = _collection().query(**kwargs)
docs = (res.get("documents") or [[]])[0]
metas = (res.get("metadatas") or [[]])[0]
dists = (res.get("distances") or [[]])[0]
out = []
for i, doc in enumerate(docs):
out.append({
"document": doc,
"metadata": metas[i] if i < len(metas) else {},
"distance": dists[i] if i < len(dists) else None,
})
return out

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With maxRecallItems = 20 (default) and MAX_CHUNK_CHARS = 6000 (src/rag.py), the maximum possible size of the response is ~120,000 characters.

At the same time, maxFeedback = 50,000 (loop.metta), so the response will be implicitly truncated, potentially displacing the results of other skills executed during the same cycle.

Comment thread src/memory_schema.py
"claim": claim,
"source": source,
"source_type": source_type,
"confidence": float(confidence),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The petta_lib_chromadb project dependency already implements and uses the confidence metadata key. These changes overwrite its existing value, which may alter the behavior expected by the dependency and lead to unintended side effects.

Comment thread src/memory_schema.py
Comment on lines +214 to +215
print(f"[memory_schema] WARNING could not mark superseded id={supersedes}: {exc}", flush=True)
print(f"[memory_schema] REMEMBER_CLAIM id={cid} source_type={source_type} confidence={meta['confidence']}", flush=True)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version of the project uses the logger for logging (src/logger.py), while this request still uses print.

@alyona-snet

Copy link
Copy Markdown
Collaborator

It seems that Context Frames can solve this issues, so I am closing the PR as non-actual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in-jira The issue has been accepted for fixing plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[OMEGA-311] Provenance-aware memory (attribution/confidence/supersession on stored claims)

4 participants