The memory that froze at session start: graph_search served a load-once snapshot for days
Verification receipts written today were on disk but invisible to graph_search — the local MCP server loaded the operating-memory graph once at startup and served that snapshot for the whole multi-day agent session. Fixed with an mtime signature over exactly the files the loader reads, reloading only on real change; proven by unit tests and a stdio E2E against the built server.
DalkkakAI's operating memory is the product's moat: everything the founder and their agents do
becomes graph nodes, and agents are instructed to consult graph_search before answering any
question about past work. Today that memory turned out to be frozen in time.
The tell was a timestamp
Three verification receipts written at 17:24Z today were sitting in the graph JSONL on disk —
grep found them instantly. graph_search returned zero results, and every response carried
"generatedAt": "2026-07-01T20:50:20Z" — exactly when this agent session (and its MCP server)
had started, ~20 hours earlier.
The cause was one line: the stdio server loaded the graph once at startup into a
StaticMemoryStore and closed its request handler over that snapshot. One MCP server process is
spawned per agent session; founders keep sessions open for days; the app appends to the graph
continuously. Nothing ever re-read the disk.
The agent-facing effect is nastier than a stale search: the memory protocol tells agents to say "no record" when memory returns nothing — so a truthful agent reports the founder's own recorded history as nonexistent for anything captured after session start.
The fix: a snapshot that knows its shelf life
graphDirSignature()— size+mtime over exactly the files the loader reads (same listing helper, sameembeddings.jsonlsidecar exclusion, nodes + edges). Sharing the listing is the point: a freshness check that enumerates files differently from the loader drifts apart silently.- Before each request the server compares signatures and reloads only when something changed — a stat sweep is microseconds; the reload only runs on real writes. In-flight guard against duplicate reloads; on transient FS errors it serves the current snapshot instead of failing.
Proof: 49/49 unit tests (append detection, new-file detection, sidecar ignored, reload surfaces the late node) plus an end-to-end run of the built server over stdio — search, append a node, search again: the late node appeared without a restart.
Lesson
StaticMemoryStore was born for fixture data and inherited real, append-forever data without
anyone re-asking whether the data was static. A cache over live data needs its invalidation signal
wired the day it is created. And generatedAt in provenance is a diagnostic, not decoration — a
consumer comparing it to "now" would have turned silent blindness into a visible warning.