diff --git a/src/iai_mcp/capture.py b/src/iai_mcp/capture.py index 67ff704..d61f4d7 100644 --- a/src/iai_mcp/capture.py +++ b/src/iai_mcp/capture.py @@ -201,6 +201,13 @@ def capture_turn( log.exception("capture_turn insert failed") return {"status": "skipped", "record_id": None, "reason": f"insert-failed: {type(e).__name__}"} + # Wire temporal_next: link this insert to the previous same-session insert. + try: + from iai_mcp.retrieve import link_temporal_next + link_temporal_next(store, rec, session_id=session_id) + except Exception: + pass # diagnostic only; never block the write path. + return {"status": "inserted", "record_id": str(rec.id), "reason": f"tier={tier}"} diff --git a/src/iai_mcp/qdrant_store.py b/src/iai_mcp/qdrant_store.py index 9e1cc63..ec6222d 100644 --- a/src/iai_mcp/qdrant_store.py +++ b/src/iai_mcp/qdrant_store.py @@ -1335,10 +1335,10 @@ class QdrantStore: continue raw_data = p.get("data_json") or "{}" - try: - data = json.loads(raw_data) - except (TypeError, json.JSONDecodeError): - data = {} + # data_json is AES-GCM encrypted; pass it through as a raw string + # so query_events() in events.py can decrypt it properly. + # Pre-02-08 unencrypted rows are plain JSON — query_events() + # handles both paths via is_encrypted() / decrypt_field(). try: source_ids = json.loads(p.get("source_ids_json") or "[]") except (TypeError, json.JSONDecodeError): @@ -1350,7 +1350,7 @@ class QdrantStore: "severity": p.get("severity") or None, "domain": p.get("domain") or None, "ts": ts_dt, - "data": data, + "data": raw_data, "session_id": p.get("session_id", "-"), "source_ids": source_ids, }) diff --git a/src/iai_mcp/retrieve.py b/src/iai_mcp/retrieve.py index 72caac9..fdb46b5 100644 --- a/src/iai_mcp/retrieve.py +++ b/src/iai_mcp/retrieve.py @@ -278,6 +278,12 @@ def contradict( store.insert(new_rec) store.add_contradicts_edge(original_id, new_rec.id) + # Wire temporal_next: contradict inserts land in same session, link them. + try: + link_temporal_next(store, new_rec, session_id="-") + except Exception: + pass # diagnostic only; never block the write path. + # monotropic proactive check fires only in high-focus # domains. Hints aren't surfaced via contradict() (its signature is fixed # to ReconsolidationReceipt), but events land in the events table so the