llm memory research

8 topics next for Agentic Memory, plus one that keeps you Safe

· ~12 min read · by Steven Batchelor-Manning
Contents
  1. The storage engine is the only authority that holds
  2. Three more worth naming
  3. Four more, tighter
  4. Which ones universalise next
8 topics next for Agentic Memory, plus one that keeps you Safe. - hero image.

The six universal patterns in the 19 systems I’ve been digging through are the spine of this series. Write-time quality investment. Provenance travelling with the fact. RRF-fused hybrid retrieval. Tiered storage with heat-based promotion. Explicit context budgets. Tools-not-injections at the agent surface. Each earned its own article because three or more systems arrived at the same discipline independently.

The universal patterns stop here. From there, the emerging ones begin.

This article is about eight patterns that sit below the threshold, living in one or maybe two systems, where the implementation is so clearly addressing a real problem that it’s hard to believe they’ll stay rare. Seven appear in exactly one system. One appears in two and is one adoption away from graduating. The first gets the deepest treatment because it’s the most important.

Being early means some of these won’t universalise. Being late is worse: you build a system in 2026 that ships without storage-layer authorisation because a synthesis called it a one-off quirk, and you get a prompt-injection demo on Hacker News in 2027.


The storage engine is the only authority that holds

Last week’s article argued the agent should hold the tools. Give it a SQL tool and the question becomes immediate: what stops it querying the table it shouldn’t?

The naive approaches are well-trodden and all wrong.

Prompt-level instruction: “You are not permitted to read the conversations table.” Works against a cooperative model. Fails against any model that misreads the instruction, decides the prohibition doesn’t apply to its current task, or is operating under a jailbreak.

Application-level filter: the sql_query tool wraps the model’s SQL, parses it for forbidden table references, rejects the query before passing it to the database. Works against a naive model. Fails against any model that quotes table names, uses ATTACH, exploits a parse mismatch between the wrapper and the database, or routes through a view defined elsewhere.

ORM-mediated access only: the agent never touches raw SQL, it calls typed methods. Works until the system grows a debugging tool, an analytics tool, a migration tool, or a “let the agent join two tables” feature, at which point the rule breaks and the brokenness goes unnoticed.

Put plainly: none of these are enforcement. They’re hints. A system that wants real sub-agent isolation has to ask the storage engine itself to refuse the read, not the layer above it. This is the discipline capability-based security imposes on operating system resources: the kernel says no, not the application. It’s also the discipline PostgreSQL’s row-level security imposes on multi-tenant SaaS: the policy lives in the database, not the ORM, because “the engineer who built the new microservice forgot to apply the tenant filter” is a bug class that only a storage-engine policy can rule out.

second-brain is the corpus’s first worked example. Its scoped database has three layers, each necessary, none sufficient on its own.

A fresh in-memory SQLite connection per scoped agent. The constructor opens :memory: and attaches the real database in read only mode. The agent’s connection has no real main schema, there is nothing to read except what the next layer puts there.

TEMP VIEWs in the main schema redirecting to allowed tables in the source. The view definitions come from the agent’s profile and can encode column-level redaction or row-level filters. A view name validator prevents injection of malicious table names through the profile.

A SQLite C-API authorizer hook denying any read of the source schema that doesn’t pass through a view. The hook fires for every read SQLite is about to perform, before the optimiser even resolves the table name. A read inside a view body is allowed, the view is the scope filter. A top-level read is checked against the set of view names the scope created. Any read against the source schema directly is denied without exception.

The LLM can write any SQL it wants. It can quote table names, use UNION, use ATTACH, use SQLite’s full grammar. It cannot succeed in reading a row from a table that isn’t in the allowlist, because the authorizer intercepts the read at the C layer before the table name is resolved. The application-level filter is bypassable. The storage-engine authorisation is not.

About 50 lines of stdlib Python. No extra dependency, no extra process, no schema migration. Per-query overhead is one C callback per read, invisible against the cost of the query itself. The pattern composes cleanly with everything else: the agent’s tool registry can still be feature-gated, the view definitions can still encode column-level redaction, the conversation history can still be redacted at write time. None of those layers is weakened by the storage-layer enforcement. They’re reinforced by it.

The framing matters. Every other security pattern in the 19 systems is a hint. The storage engine is the authority.


Three more worth naming

Async cleanup race protection (llm-wiki)

Background memory maintenance is fundamentally racy with foreground user actions. A sweep that started against project A and finishes against project B has corrupted both. It’s moved A’s decisions into B’s review store, or marked B’s items resolved against A’s data. This is a bug class that’s easy to introduce, hard to detect, and impossible to recover from cleanly because the corrupted state looks legitimate.

llm-wiki runs a two-stage background review loop and, at every yield point, re-checks two race-protection signals: an abort signal fired by the project-switch handler, and a path comparison against the current project in the UI store. Either check fails, the sweep returns mid-flight without applying decisions. The project-switch handshake on the queue side completes the picture: it flushes the active project’s state to disk before clearing memory, reverts processing items back to pending, aborts both the in-flight LLM call and the in-flight sweep judgment, and only then writes to the paused project’s path.

The meta-pattern is the takeaway: deterministic where you can, LLM where you must, abortable everywhere. The two-stage structure keeps the LLM out of cases that simple existence checks can handle. The race protection keeps both stages abortable. The combination is a template for any background memory maintenance loop in any system.

The auto-degraded no-op constructor (graymatter)

Library API design has a recurring tension. The simplest “hello world” wants the library to just work, one line to construct, one to call. The most defensible production posture wants it to fail loudly at construction with a structured error the caller can’t ignore.

graymatter picks fail-silent, but with a discipline that turns the trade productive. The constructor never returns an error. If init fails, bbolt is locked, the data directory is unwritable, the vector store can’t be opened, it logs to stderr and returns a degraded Memory whose methods are all no-ops. Production callers verify through Healthy() before trusting the handle. The library is go get-able, importable in three lines, and works in the demo. Healthy() is the production discipline tax.

The pattern makes the library safe to embed in agent harnesses that have their own startup ceremony. An agent harness that calls graymatter.New(...) during boot, ignores the error path because there is no error path, and continues, gets a working memory layer in the happy path and a no-memory fallback when the data directory is read-only. Either way the harness boots. That’s a specific kind of defensive composition that fail-loud constructors can’t offer without explicit error handling at every embedding site.

Shadow-mode duplicate detection (mem9)

Every system that ships duplicate suppression has to pick a cosine similarity threshold. Above 0.95 is almost certainly a duplicate. Below 0.7 is almost certainly not. The space between is contested, and the right cut depends on the embedding model, the domain, the query distribution, and the cost of false positives versus false negatives in this particular system.

The temptation is overwhelming to pick one based on intuition and ship. mem9 doesn’t. It runs the duplicate-detection query for every fact, records the cosine score in a Prometheus histogram, and takes no action. The threshold is deferred until production data justifies it. “Ship the observation, not the heuristic.”

The same logic applies to every thresholded decision in every memory system. Rerank threshold. Recall confidence cutoff. Tier-promotion heat gate. Insight-merge similarity gate. Most systems in the 19 ship these values guessed. mem9 ships with the value deferred. The discipline is rare and the result is better.


Four more, tighter

Per-tenant physical database isolation (mem9). Instead of a WHERE tenant_id = ? filter on a shared store, mem9 provisions a separate TiDB cluster per tenant through TiDB Zero. Isolation is storage-engine-side. The application can’t accidentally query across tenants because there is no shared store to query. It’s a coarser-grained version of the same end-state as storage-layer authorisation: isolation enforced at the engine, not the application. The infrastructure cost that historically made this impractical is gone. TiDB Zero auto-provisions. Neon does the same for PostgreSQL. Cloudflare D1 does the same for SQLite.

Source-turn decoration with explicit context budget (mem9). A retrieved memory is a string. “User prefers Postgres.” Correct, terse, impossible to ground without context. mem9 attaches the originating conversation turns as decoration, scored against the query and capped by a budget triple: minimum score, per-memory limit, total limit. The agent reading “User prefers Postgres” gets the turn where the user said “we tried MongoDB but the joins killed us so I switched to Postgres last quarter.” No second tool call required. The grounding is in the result. The prerequisites are already universal: provenance plus hybrid retrieval. Most systems in the 19 could implement this in two days.

purpose.md as a fourth file (llm-wiki). The Karpathy LLM Wiki pattern has three canonical files: raw sources, the wiki working set, and schema.md for structural rules. llm-wiki adds a fourth: purpose.md, filled in by the user, inlined into every LLM call the system makes. Every ingest prompt, every generation prompt, every chat retrieval reads it. The effect is a stable directional prior that conditions every downstream behaviour. The LLM is going to read the system prompt anyway. Adding the user’s intent costs nothing and lifts everything. The absence from most other systems is harder to explain than its presence in llm-wiki.

AGENTS.md as authoritative agent contract (Tolaria, OpenContext). Most repositories with an AGENTS.md or CLAUDE.md treat it as a hint file. Tolaria and OpenContext treat it as a contract, backing every binding clause with a mechanical check that fails the build if the agent violates it. “Do not skip pre-commit hooks” isn’t a polite request, it’s a rule the CI enforces. “Test coverage must stay above threshold” isn’t a guideline, it’s a bar the test runner aborts on. A hint can be ignored. A contract backed by a check cannot. Two systems already do it. One more and it graduates.


Which ones universalise next

Storage-layer authorisation will universalise first. This is the most confident prediction in the source analysis. Every memory system that gives a sub-agent SQL access is one prompt injection away from a confidentiality breach without storage-layer enforcement. The infrastructure is already in place. SQLite has had set_authorizer since the early 2000s. PostgreSQL RLS is mainstream. LanceDB and ClickHouse have policy hooks of their own. The barrier isn’t technical, it’s awareness. second-brain has provided the worked example. The next generation of managed APIs will copy the discipline because the alternative is indefensible.

Source-turn decoration will universalise second. The prerequisites are universal already. The implementation is two queries plus a budget. The agent-side information gain is large enough that whoever ships it first in a managed API is going to be visibly better at grounding answers in source dialogue than whoever ships it second. The pressure to copy is high. graymatter has the source per fact. supermemory has lineage. Hindsight has full conversational provenance. Any of these is one PR away from the pattern.

The auto-degraded no-op constructor will universalise third, and in a different language. Go’s cultural conditions make the pattern safe. The next adopter is unlikely to be Python, the culture is too eager about exceptions, but might be Rust. It’s a library-API design choice, not a memory choice, and it will spread wherever “demo aesthetic plus production discipline” is the right trade.

Shadow-mode deployment is the dark horse. Technically trivial, culturally hard. If a second system instruments a threshold before gating on it, the pattern graduates immediately, and the third and fourth follow within a release cycle because the engineering ergonomics are unanswerable once demonstrated.

The remaining four are each conditional on a specific deployment shape becoming more common. Race protection universalises when more systems grow multi-conversation parallelism. Per-tenant physical isolation universalises when regulated enterprise customers start asking for it. purpose.md universalises when the Karpathy LLM Wiki paradigm gets its third or fourth implementation. AGENTS.md as contract universalises when the “agents are colleagues” framing becomes the dominant harness metaphor. None is implausible. None is certain.


The unifying thread across all eight is the same position: the application layer is not a trustworthy isolation boundary. Storage-layer authorisation is the per-agent expression. Per-tenant physical databases are the per-tenant expression. AGENTS.md as contract is the per-agent-behaviour expression. The next iteration of this corpus will, in this prediction, contain a new universal pattern by that name.

Last week’s article made the case that the agent should hold the tools and decide what to retrieve. This one is about what holds when the agent turns those tools somewhere you didn’t expect. The six universal patterns are consensus. The eight here are the leading indicators of where consensus moves next. Storage-layer authorisation is the leading edge of the leading edge, and the cost of missing it is the kind of cost that shows up on Hacker News.

Part 10 of 10 in the agent memory series. Each article stands alone.


Have thoughts? Share and discuss: Share on X | Discuss on X

Previous: 2026-06-02-llm-memory-research-09

Share & discuss

The X Article covers the same ground in a different form. The site version is the canonical one; the X version exists for the conversation in the replies.