Two ideas adapted from studying Curion, a competitor MCP memory tool — kept dependency-free. Curion's LLM-controller architecture (an API call on every store and recall) was deliberately not adopted; context-keeper stays zero-dependency and offline by default.
Abstention: get_context can now say "I don't have anything relevant"
Previously it always returned its top-scored entries. But the composite score banks ~55 points from recency/status/origin regardless of query relevance, so a query with no relevant memory silently got a confident-looking top result. Measured confabulation was 100% on no-answer queries (evals/abstention.py).
Now the response carries top_relevance, and when the top entry's tag/text relevance falls below min_relevance (config, default 0.20), no_confident_match: true with guidance telling the agent not to present the entries as established fact. It annotates, never suppresses — weak matches are still returned, so the vocabulary-mismatch recall that retrieval_hints and the semantic blend preserve survives. 0.20 is the highest floor with 0% false-abstention on the eval set (TNR 38%). Honest limit documented: hard-negatives sharing real topic vocabulary still slip through — a field-wide hard problem for lexical and dense retrieval.
Supersession as a ranking signal, not just a filter
record_decision accepts supersedes: [ids]: the prior decisions become superseded — demoted in ranking but still recallable ("why did we change from X?"), distinct from deprecate_entry which removes an entry from retrieval entirely. Superseded entries are skipped by prune_stale/verify_quality (intentional history, not stale work) and marked **SUPERSEDED** by dec-NNN in the DECISIONS.md projection. Reuses infrastructure already present — score_entry already demoted superseded, get_context already only filtered deprecated; the gap was that nothing ever set the status.
146 tests passing (15 new). tools/list payload 2493/2500. Retrieval eval unchanged.