Workspace/Mini projects
Loading progress
All mini projects
MODULE 11 · 5 HOUR BUILD

Memory lifecycle workbench

Build a local memory workbench with typed records, scoped retrieval, corrections, deletion, expiry, and a provenance view showing which summaries depend on which records.

Build evidence Record your actual checks, results, and limitations.

Build it in stages

  1. Run the seed and inspect correction and deletion of a preference.
  2. Add episodic, semantic, and preference record types with stable IDs and source references.
  3. Implement deterministic clock-based retention and tenant-scoped retrieval.
  4. Track derived-summary dependencies and invalidate them after source correction or deletion.
  5. Create a report of current values, superseded history, expired records, and invalidated summaries.

Your acceptance criteria

Use these as your project review. Record commands, outputs, and failure cases in your repository.

  • At least 15 lifecycle fixtures cover exact expiry, tombstones, future records, and cross-tenant keys.
  • A correction cannot lose to an older record with a higher retrieval score.
  • Deleting a source prevents retrieval through a dependent summary.
  • A user can inspect the source and scope of every active preference.

A working starting point

The seed runs as supplied. Extend it to satisfy the full brief. It is a teaching starting point, not a finished portfolio submission.

main.py
python
import json

class MemoryLedger:
    def __init__(self):
        self.rows = []

    def add(self, identity, tenant, key, value, created, expires=None, deleted=False):
        self.rows.append({"id": identity, "tenant": tenant, "key": key, "value": value,
                          "created": created, "expires": expires, "deleted": deleted})

    def current(self, tenant, now):
        latest = {}
        for row in self.rows:
            if row["tenant"] != tenant or row["created"] > now:
                continue
            previous = latest.get(row["key"])
            if previous is None or (row["created"], row["id"]) > (previous["created"], previous["id"]):
                latest[row["key"]] = row
        result = {}
        for key, row in latest.items():
            alive = row["expires"] is None or now < row["expires"]
            if alive and not row["deleted"]:
                result[key] = {"value": row["value"], "source_record": row["id"]}
        return result

ledger = MemoryLedger()
ledger.add("p1", "A", "style", "long", 1)
ledger.add("p2", "A", "style", "concise", 2)
ledger.add("p3", "B", "style", "detailed", 2)
ledger.add("e1", "A", "temporary", "incident-17", 2, expires=4)
print(json.dumps(ledger.current("A", 3), sort_keys=True))
ledger.add("p4", "A", "style", None, 4, deleted=True)
print(json.dumps(ledger.current("A", 4), sort_keys=True))
print("history records:", len(ledger.rows))

Push it further

Add a transactional persistent store and a background reindex queue whose retries cannot revive deleted or superseded versions.