Citation-backed memories with just-in-time verification
Citation backed memories with verification at read time
Problem
Recalled memories go stale silently. A memory saying the API version is v2.1.4 gets injected as fact with no link to the code behind it. When the code moves on, the memory keeps asserting the old world. The store has dedup, reinforce and supersede, but nothing fills supersede edges on the write path and recall has no freshness check. Copilot's memory system solved this without offline curation: memories carry citations, and on retrieval the harness rereads the cited lines and compares. Verification is a handful of local reads.
Design (no branch yet, holding for maintainer direction)
I promote MemoryEntry.source (free text today) to structured citations: path, line hint, hash. Serde defaulted and skipped when empty, so old entries load unchanged with no citations.
On the write path, when the sidecar or a tool call creates a memory from code it just read, it attaches the file and line it came from. No new model call, the paths are already in context.
On the read path at session start (not on write, not every turn), I reread the cited spans for memories about to be injected. Hash mismatch marks the memory stale and skips injection. It surfaces in logs, not as an error. A few local file reads, fully deterministic, zero model cost.
Stale is advisory only. The memory stays in the store and can be re-verified or superseded later. That pairs with the existing active and superseded_by fields.
Four semantics pinned from the review discussion: the fingerprint is exact span bytes with no normalization (I first suggested stripping whitespace, then withdrew it, because a change inside a string literal or indentation in Python/YAML/Make is a real change and must read as one). Span relocation tries the exact window first, then searches the file for it elsewhere before calling it stale. Paths are repo relative only, absolute paths and .. rejected, resolved under the repo root. Stale never deletes, never rewrites memory, never blocks recall, and never touches memories with no citation.
Why this shape
Verification at read time beats curation at write time, because code changes after the memory is stored. Session start cadence keeps it off the hot loop. It works on the no LLM hybrid path too, where stale defense is thinnest today. Small change: one schema addition, one read path check, roughly 50 lines plus tests. No new services or migrations.
Limits
The hash check is deliberately naive. It detects that the cited lines changed, not that the meaning changed. A changed citation marks stale for the next garden pass to adjudicate. The filter reduces judge load, it does not replace judgment. Memories without citations (preferences, decisions) are unaffected.
Source: 1jehuang/jcode