feat(memory): preserve corroborating episode evidence
Summary
- add content-versioned per-session evidence rows for TypeScript and Rust memory stores
- make exact repeats idempotent within one session while distinct sessions increase corroboration
- preserve evidence through update, merge, move/copy collisions, v22 backfill, identity merge, Pi merge, deletion, and TS↔Rust authority transfer
- keep
seen_countmonotonic and based on distinct corroborating sessions without reducing legacy aggregate counts - document the cross-runtime source contract and migration v79/v51
Attribution boundary
OpenCode supplies the assistant message that owns the tool call, not a verified originating user message. Primary writes therefore remain source_type=agent; the dormant user variant is not falsely populated. source_message_id is the host-native assistant tool owner on OpenCode and null on Pi/Rust. A future verified host user-message link can activate user safely.
Semantic boundary
Evidence records observations of exact content versions. It does not claim paraphrased memories are the same assertion; explicit merge retains the original hashes.
Verification
- plugin provenance/migration/authority/identity/backfill/tool suites: 121 pass
- complete Pi ctx_memory suite, including restored pre-existing coverage: 25 pass
- plugin and Pi typecheck/build pass
- plugin lint passes; Pi has one pre-existing non-null warning
- Rust
mc-storecompiled against publiccortexkit\/commons; 136/136 store tests pass. Fullmc-moduleworkspace tests remain blocked by unavailablesubconsciouspath dependencies - three Oracle reviews found and verified fixes for false user attribution, lifecycle evidence loss, non-atomic writes, content-version drift, distinct-session counting, legacy count monotonicity, and TS/Rust merge parity
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
Summary by cubic
Preserves content-bound, per-session episode evidence for memories and makes duplicate writes idempotent within a session. Old: duplicate writes bumped seen_count without provenance and evidence-only updates sometimes didn’t sync; new: evidence keyed by content hash and session recomputes seen_count from distinct sessions, and evidence-only changes now sync and seed mirrors in all runtimes.
- Review and migration
- Schema v79: create
memory_evidence(PK:memory_id, content_hash, source_session_id) with a session index; backfill frommemories; bumpLATEST_SUPPORTED_VERSIONto 79; replay-safe for armed stores. - Behavior: use
insertMemoryIdempotentandrecordMemoryEvidenceinstead of ad‑hoc seen_count bumps; same-session repeats are no-ops; distinct sessions add corroboration. Attribution requires a verified owner forsource_message_id; tool writes defaultsource_type=agentand never inferuser. - Lifecycle and counts: updates, rekeys/collision merges, identity merges, v22 backfill, copies, and deletes union or cascade evidence; when evidence exists, seen_count derives from distinct-session evidence, otherwise the legacy max is preserved.
- Cross‑runtime: state‑sync payloads and authority seeds carry evidence arrays; mirror sync reinstalls evidence snapshots; evidence‑only updates rewind watermarks to force resend; TypeScript and Rust stores persist/union evidence and maintain distinct‑session counts.
- Schema v79: create
Greptile Summary
The PR adds content-versioned, per-session evidence for durable memories across the TypeScript, Pi, and Rust stores.
- Adds evidence schemas and migrations for both storage implementations.
- Preserves and unions evidence across memory lifecycle operations and authority transfers.
- Makes same-session repeats idempotent while distinct sessions increase corroboration.
- Updates state synchronization to include evidence and resend evidence-only changes to existing memory rows.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
| Filename | Overview |
|---|---|
| packages/plugin/src/tools/ctx-memory/tools.ts | Duplicate writes now request Rust synchronization before returning, covering both existing-row and unique-constraint-race outcomes. |
| packages/plugin/src/features/magic-context/memory/storage-memory.ts | Adds idempotent per-session evidence recording and monotonic distinct-session corroboration accounting. |
| packages/plugin/src/hooks/magic-context/module-state-sync.ts | Includes memory evidence in cross-runtime state payloads so synchronized rows preserve provenance. |
| packages/plugin/src/hooks/magic-context/rust-mode-transform.ts | Rewinds memory-specific watermarks when a tool mutation requests synchronization, ensuring evidence-only changes to existing IDs are resent. |
| crates/mc-store/src/lib.rs | Adds the Rust evidence schema and lifecycle handling needed for TypeScript-to-Rust parity. |
| packages/pi-plugin/src/tools/ctx-memory.ts | Adopts the shared idempotent memory insertion and evidence semantics for Pi writes. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
W[Memory write or repeat] --> TS[(TypeScript memory store)]
TS --> E[(Per-session evidence)]
E --> C[Recompute monotonic seen_count]
E --> Q[Request Rust memory sync]
Q --> R[Rewind memory watermarks]
R --> P[Build state-sync payload]
P --> RS[(Rust memory store)]
RS --> M[Mirror or authority transfer]
M --> TS
Reviews (7): Last reviewed commit: "style(pi): format memory evidence regres..." | Re-trigger Greptile
Context used (3)
- Knowledge Base — Plugin memory, notes, and context tools
- Knowledge Base — Rust memory and context engine
- Knowledge Base — Pi plugin runtime: adapting Magic Context to Pi