Make correction, expiry, and deletion propagate
How to study this lesson
Read one section, trace the worked example, and try the knowledge check. Bookmark saves a shortcut; notes appear in My notebook. Mark lesson complete is your own assessment and does not mark its lab passed.
By the end, you can
- Resolve competing versions before retrieval ranking.
- Prevent expired or deleted records from resurrecting older values.
- Track derived memories so corrections reach their dependents.
A memory store needs verbs beyond insert
A useful memory service supports adding, reading, correcting, superseding, expiring, and deleting records. These operations define product behavior, not merely database maintenance. If a user corrects a preference, the old value should not reappear because it has a higher relevance score. If a record expires, the retrieval index and prompt cache must respect that expiry. A write-only memory system accumulates contradictions that the model is then forced to resolve informally.
Define retention by record type and purpose. An incident episode may remain useful as history, while a temporary task preference may expire when the task ends. Keep the policy explicit and inspectable. This lesson describes engineering semantics for a local application, not a legal retention schedule. Actual organizational requirements can be represented as inputs to the same lifecycle mechanisms.
Resolve versions before scoring
Assign a logical key to a mutable fact or preference and append versions with stable IDs and recording times. Resolve the current version first, then apply relevance ranking. Otherwise an older high-scoring value can defeat a newer correction. For an educational deterministic policy, choose the greatest (created_at, id) pair within the same tenant and logical key. Production may need authority levels or explicit conflict states instead of arrival order.
Suppose preference P1 says long explanations, and later P2 corrects it to concise summaries. P2 should control the current preference even if the current query shares more words with P1. Keep P1 as superseded history if policy permits, but exclude it from current-value retrieval. A history view and a current-context view are different queries over the same ledger.
Expiry must not reveal an older version
Consider P1 with no expiry and a newer P2 that expires at time ten. At time ten, filtering expired records before version resolution can remove P2 and mistakenly restore P1. Decide the intended semantics explicitly. In this module, expiry of the latest version leaves no active value; it does not resurrect earlier versions. Therefore resolve latest versions first, then apply expiry and deletion.
A tombstone is a record stating that a logical value is deleted. The same ordering rule applies: if tombstones are filtered out before version resolution, a deleted record can reappear. An expiry boundary also needs precision. The lab defines an active interval ending just before expires_at, so a record with expiry ten is inactive when now equals ten. Boundary fixtures catch mistakes that ordinary recent-record tests miss.
Derived records form a dependency graph
A memory summary may depend on several episodes, and an embedding index may represent that summary. Deleting or correcting a source should invalidate or recompute dependent artifacts according to the application's policy. Store source IDs on derived records so the system can find them. Merely removing the original row leaves summaries, caches, and retrieved prompt fragments capable of reproducing the stale content.
For example, summary S1 combines episode E1 with preference P1. A correction P2 supersedes P1. Mark S1 stale and regenerate it using the new active preference, or stop retrieving S1 until it can be rebuilt. A dependency index makes this a targeted operation. Scanning every text blob for the old phrase is unreliable because summaries may paraphrase it or omit the exact wording.
Test memory behavior across time
Memory tests should advance an explicit clock instead of waiting for real time. Include just-before expiry, exact expiry, a newer tombstone, a correction with lower relevance, two tenants sharing a key, and a large record that exceeds the context budget. Test deletion through derived summaries as well as direct lookup. These scenarios establish observable behavior the user can rely on.
The code shows why version resolution precedes activity filtering. The latest preference has expired, so no value is returned even though an older one had no expiry. The lab combines this rule with tenant isolation and budget selection. For a portfolio artifact, include a lifecycle trace that explains which record replaced or invalidated another. This turns memory from a vague personalization feature into a reviewable data system with predictable change semantics.
Work through the code
The newest version is selected before checking expiry. At the exact expiry boundary, the logical preference becomes inactive and the old value stays superseded. The example assumes one tenant and an already valid record schema.
records = [
{"id": "p1", "key": "style", "created": 1, "expires": None, "deleted": False, "value": "long"},
{"id": "p2", "key": "style", "created": 5, "expires": 10, "deleted": False, "value": "short"},
]
def active_values(records, now):
latest = {}
for record in records:
previous = latest.get(record["key"])
if previous is None or (record["created"], record["id"]) > (previous["created"], previous["id"]):
latest[record["key"]] = record
active = {}
for key, record in latest.items():
unexpired = record["expires"] is None or now < record["expires"]
if not record["deleted"] and unexpired:
active[key] = record["value"]
return active
print(active_values(records, now=9))
print(active_values(records, now=10))
{'style': 'short'}
{}Run Python snippets locally with the prerequisites named above. The module coding lab runs directly in your browser.
Pause and reason
A deleted episode was incorporated into a summary and then embedded for retrieval. Which artifacts should the deletion workflow inspect?
Check your understanding
A newer memory version expires. Under this module’s policy, what happens to an older unexpired version?
Your notes
Explain the mechanism in your own words. Add a failure you want to test.