Forgetful Memory Lab
A benchmark for remembering the right version and deleting its downstream traces
The problem worth solving
Useful agent memory must distinguish an outdated preference from a current fact, answer historical questions, respect the purpose for which information was retained, and remove derived content when its source is deleted. A retrieval benchmark that measures only recall misses these conflicts. Build an experimental memory backend for synthetic personal-assistant histories. The central task is to measure what happens to accuracy, abstention, and prohibited retrieval after updates, consent changes, and deletion across raw records, summaries, search indexes, and caches.
What could make it stand out
LongMemEval and LoCoMo already test important long-history abilities. This proposal adds an explicit event contract tying valid time, ingestion time, purpose scope, and derivation lineage to each memory artifact. Its distinctive evaluation pairs ordinary question answering with adversarial post-deletion probes and retained-memory controls. The system produces a deletion receipt describing the backend surfaces actually covered. It does not claim to erase a language model's learned weights, third-party backups, or previously exported answers; those lie outside the declared local-memory boundary.
A temporal memory index with purpose filtering and transitive provenance deletion will reduce stale-fact answers by at least 30% relative to a recency-only retrieval baseline, while leaving no deleted synthetic canary in the declared active stores after deletion and reducing retained-fact answer accuracy by no more than five percentage points. Reject the hypothesis if stronger abstention alone explains the stale-answer improvement or if derived summaries permit deleted facts to reappear.
System architecture
| Component | Responsibility |
|---|---|
| Synthetic history generator | Create coherent fictional people, preferences, moves, project changes, and purpose-specific permissions. Generate question labels from hidden event graphs rather than from the memory backend's own answers. |
| Bitemporal fact store | Store event-valid intervals separately from ingestion timestamps, with subject, predicate, value, purpose, source IDs, and supersession edges. Keep unknown intervals explicit instead of inventing dates. |
| Retrieval and reading pipeline | Filter by permitted purpose and requested time before lexical or vector ranking. Require the reader to cite active source IDs and abstain when a unique supported answer cannot be selected. |
| Derivation and deletion service | Track summaries, embeddings, cached answers, and extracted facts as derivatives of source records. Traverse this graph on deletion, remove covered artifacts, invalidate affected caches, and block resurrection from tombstoned sources. |
| Memory experiment console | Display history events, current and historical answers, deletion impact, and retained controls. Export content-free deletion receipts and an inventory of storage surfaces checked by each probe. |
Data and reproducibility
Create 50 fictional histories with 80 to 120 events each, producing at least 400 questions across current facts, historical facts, updates, unknown answers, purpose conflicts, and deletion. Use public memory benchmarks as task-design references or separately labeled evaluation subsets, subject to their licenses. Never mix this project's synthetic scores with a benchmark's published leaderboard results.
Start with a synthetic benchmark
Generate source events before producing summaries and questions, then insert late-arriving corrections, conflicting facts, expiry, consent withdrawal, and deletion requests. Assign unique fictional canary values to deletion targets and create indirect summaries that paraphrase them. Hold out entire personas and event templates. Pair every deleted target with an unrelated retained fact so broad database clearing cannot count as a successful deletion strategy.
Baselines you must beat
- Recency-only lexical retrieval over append-only history, with the same reader and context size.
- Temporal filtering without purpose scope or derivative lineage, exposing whether time handling alone addresses the failure.
- Source-record deletion with no summary or cache invalidation, plus a full-clear control that reveals the cost of overbroad forgetting.
Measure the claim
Targets below are proposed success criteria. No results have been achieved on your behalf.
| Metric | Definition and target |
|---|---|
| Temporal answer error | Fraction of answered current and historical questions containing a value invalid at the requested time; report coverage and separate late-arriving correction cases. Target, not achieved result: at least 30% relative reduction versus recency-only retrieval at matched answer coverage. |
| Post-deletion exposure | Presence of deleted canary facts or their adjudicated paraphrases in any declared active store, retrieval result, summary, cache, or generated answer after the deletion barrier completes. Target, not achieved result: zero exposure in the frozen local-store suite; this is a scoped benchmark target, not a claim of universal erasure. |
| Retained utility and scope compliance | Answer accuracy on unrelated retained facts plus the rate of retrievals that violate a requested purpose; compare before and after each deletion operation. Target, not achieved result: retained accuracy loss no greater than five percentage points and zero purpose violations in deterministic access-filter fixtures. |
Experiments and ablations
- Replay the same questions before an update, after an update, and after a late correction. Compare valid-time filtering with simple newest-record selection and inspect ambiguous overlapping intervals.
- Delete one source whose facts appear in a direct extraction, a summary, a summary-of-summary, and a cached answer. Probe each surface separately and test attempted reingestion of the deleted source.
- Vary history length and summary compression while fixing retrieval budget. Report temporal accuracy, deletion work, latency, and retained utility rather than selecting whichever memory setting maximizes one metric.
Your execution plan
0 of 12 deliverables checked. Tick a deliverable after recording evidence in your project repository.
Specify the memory and deletion boundary
Build histories and baseline retrieval
Add temporal and purpose semantics
Implement provenance-aware forgetting
Run the memory impact study
Release a clear memory benchmark
Working seed
Run this small, deterministic core first. It demonstrates the central mechanism. The complete system, experiments, and deployment are your capstone work.
"""Forgetful Memory Lab: temporal reads and transitive in-memory erasure."""
from dataclasses import dataclass
import json
@dataclass(frozen=True)
class Fact:
id: str
key: str
value: str
valid_from: int
valid_to: int
purpose: str
parents: tuple = ()
class Memory:
def __init__(self):
self.facts = {}
self.cache = {}
self.tombstones = set()
def add(self, fact):
if fact.id in self.tombstones or any(p in self.tombstones for p in fact.parents):
raise ValueError("Cannot resurrect erased provenance")
self.facts[fact.id] = fact
self.cache.clear()
def retrieve(self, key, day, purpose):
cache_key = (key, day, purpose)
if cache_key not in self.cache:
choices = [f for f in self.facts.values() if f.key == key
and f.valid_from <= day < f.valid_to and f.purpose == purpose]
chosen = max(choices, key=lambda f: (f.valid_from, f.id), default=None)
self.cache[cache_key] = chosen.value if chosen else None
return self.cache[cache_key]
def erase(self, source_id):
doomed = {source_id}
while True:
expanded = doomed | {f.id for f in self.facts.values()
if any(p in doomed for p in f.parents)}
if expanded == doomed:
break
doomed = expanded
for fact_id in doomed:
self.facts.pop(fact_id, None)
self.tombstones.update(doomed)
self.cache.clear()
return sorted(doomed)
def main():
memory = Memory()
memory.add(Fact("old", "city", "Pune", 1, 10, "travel"))
memory.add(Fact("new", "city", "Bengaluru", 10, 99, "travel"))
memory.add(Fact("summary", "profile", "Bengaluru traveller", 10, 99, "travel", ("new",)))
memory.add(Fact("derived", "greeting", "Welcome from Bengaluru", 10, 99, "travel", ("summary",)))
assert memory.retrieve("city", 5, "travel") == "Pune"
assert memory.retrieve("city", 12, "travel") == "Bengaluru"
assert memory.retrieve("city", 12, "marketing") is None
removed = memory.erase("new")
assert removed == ["derived", "new", "summary"]
assert memory.retrieve("city", 12, "travel") is None
assert memory.retrieve("profile", 12, "travel") is None
assert memory.retrieve("city", 5, "travel") == "Pune"
print(json.dumps({"deleted_ids": removed, "remaining_ids": sorted(memory.facts),
"current_city": memory.retrieve("city", 12, "travel"),
"historical_city": memory.retrieve("city", 5, "travel")}, sort_keys=True, indent=2))
if __name__ == "__main__":
main()
Failure modes to investigate
- Deleting raw text alone leaves summaries and embeddings behind. Make the storage inventory part of the experiment and fail the receipt if any declared surface cannot be checked.
- An exact string scan misses paraphrased information. Add fixture-derived semantic probes and manual adjudication, and report their coverage separately from deterministic canary checks.
- A system can achieve perfect forgetting by erasing everything. Pair deletion probes with unrelated retained-memory controls and measure the resulting utility loss.
Your demo, moment by moment
- Ask the synthetic assistant where a fictional person lived on an earlier date and where they live now; inspect the two different source intervals.
- Change the permitted purpose and show that a fact available for travel planning is unavailable to a marketing request.
- Delete a recent location source and display removal of its extracted fact, nested summary, and cached answer, followed by a post-deletion abstention.
- Ask an unrelated retained question to prove useful memory remains, then show the before-and-after benchmark and the exact deletion boundary.
Write the resume bullet after the experiment
Replace every placeholder with your actual measurements. Keep the dataset size, baseline, and evaluation conditions available for interview questions.
A research extension
Extend the backend to multiple local workers and study deletion barriers under concurrent reads and cache refreshes. Define when deletion is acknowledged and test whether a request started earlier can publish an answer afterward. A separate research extension compares selective summary rebuilding with wholesale invalidation, measuring compute savings against the risk of retaining a deleted fact.
Related work to challenge your idea
Tests long-term assistant memory, including temporal reasoning and updates. The proposed benchmark adds an explicitly scoped deletion and purpose-control axis with retained-utility controls.
Uses long conversations grounded in temporal event structures. The capstone borrows the principle of event-grounded labels while creating original fictional histories and deletion interventions.
Provides an established provenance vocabulary. A small derivative graph inspired by it makes source-to-summary deletion testable; using the vocabulary alone does not establish complete erasure.