agent operations · domain memory
How I (Lucas van Staden / ProxiBlue) give my AI coding agents long-term domain knowledge with a temporal knowledge graph. Code and git tell an agent what exists. The graph tells it why things are the way they are, and that is what changes how work gets scoped and planned.
AI coding agents wake up amnesiac. Every session starts from zero. The code is there, the git history is there, but the actual domain knowledge of a business is not in either. Why a vendor's modules are banned. Which server IPs are allowed through the firewall, and why. Why the checkout was built the way it was, three years ago, after an incident nobody wrote down.
Where it really bit was issues and planning. When something breaks, or when a new project gets planned, I bring twenty years of prior knowledge to the table: meetings, emails, chats, old tickets, decisions made and reversed. Things I, the human, generally carry around in my head when I plan out a solution. My amnesiac AI had no clue of the whys, the whats, the reasons. Its plans were technically fine and contextually blind, and that was a major failing. Every plan started from a world where none of that history had happened.
That was the point where "the agent should just know this" stopped being a wish and became a project.
So, the fix: a temporal knowledge graph (Graphiti on top of Neo4j, both open source), running on my host, wired into every agent session (host and per-project containers) via MCP. Facts go in as episodes, entities and relationships get extracted automatically, and any session can query it on demand.
The graph is bi-temporal. Every fact records when it was ingested and when it was true, and a fact can be superseded by newer information without losing the history. That matters more than it sounds. Businesses change mid-year: a checkout swaps payment gateways, a policy flips, a server gets a new IP. A plain notes file overwrites itself. The graph keeps both states, with validity windows.
fact: "checkout uses gateway A"
valid_at: 2024-03-10 invalid_at: 2026-02-01
fact: "checkout uses gateway B, A dropped after fee change"
valid_at: 2026-02-01 invalid_at: —
Ask "what did checkout run on in 2025" and you get the old answer, with the why of the change attached. Ask "what does it run on now" and you get the current one. Both true, both kept.
Facts arrive two ways: in-conversation ("remember this"), and bulk ingestion channels that run on cron. Each channel is a script that condenses a source down to its signal and writes episodes:
The pairing I lean on most: module docs answer "what exists", tickets answer "why we built it that way". An agent planning a change needs both, and only one of them is in the codebase.
Where that lands today, live counts pulled from my graph while writing this:
queried 2026-09-01 · one cypher call, no estimates
Bolting a memory onto an agent is easy. Keeping it trustworthy is the actual work. My rules:
No silent writes. Before any in-conversation save, the agent must confirm scope with me in one line: fleet-wide fact, host fact, or project fact? One keystroke to approve. A memory full of misfiled facts is worse than no memory. (And this rule is itself eval-tested; see my falsifiable rulebook article. The probe asks the agent to "remember something" and asserts it confirms scope instead of writing.)
Namespaced by project. Every fact lives in a group: one per client project, one for the host, one fleet-wide. Queries from a project see that project plus fleet, nothing else. Client A's constraints never bleed into client B's plans.
Facts, not rules. The graph holds domain knowledge, queried on demand. Anything that must load every session (style rules, guard hooks, invariants) stays in files and hooks. Wrong tool for that job.
Thin results are not missing data. Before an agent may claim something is "not in the graph", it has to run a proper search discipline: facts and nodes, synonyms, entity names, widened time ranges. "Not found on the first query" and "not known" are different claims.
Cite what you recall. When an agent acts on a recalled fact, it appends the source (episode or origin). Recall without provenance is just confident guessing with extra steps.
This is the payoff, and it is bigger than "the agent remembers stuff".
When an agent plans work without domain knowledge, you get generic plans. Technically plausible, blind to the business. With the graph wired in, plan time starts with a query: what do we know about this area? What went wrong here before? What did the client decide? The plan that comes out is scoped against reality, not against what the code alone suggests.
Real examples from my fleet:
That last one is worth seeing. Below is a real neighbourhood from my graph, drawn as stored (entity names verbatim, ticket reference anonymised). One incident: a mid-task git stash by a parallel worker wiped sibling agents' edits in a shared working tree. The graph holds the causes on one side and the three defences that came out of it on the other:
Scoping a job is mostly knowing what you are walking into. The graph is how my agents know.
Local LLM extraction did not survive contact with my hardware. Entity extraction needs an LLM, and I wanted it local (cost, privacy). Tried it on my own GPU. The machine kept hard-freezing under load, so I reverted to a small cloud model for extraction and queued a proper GPU purchase. Point is: the extraction layer is swappable, run it wherever it is stable for you, and a cheap small model is fine for this job.
Ingest quality beats ingest quantity. Early email ingestion pulled in auto-replies and quoted-reply noise, and the extraction happily made entities out of it. Now every channel filters hard before writing, and there is a wipe tool to remove one channel's episodes cleanly (with orphaned-entity pruning) when an ingest goes bad. You will get a bad ingest. Plan for the undo.
Namespace hygiene needs enforcement, not intention. I ended up with the same project under three different group names (a nickname, a case variant, and one misfiled default). Merged them, lowercased everything, and put the normalisation into the scripts so it cannot drift again. Same lesson as everywhere else in my tooling: intention decays, enforcement does not.
Memory you cannot restore is not memory. The graph gets a nightly dump, encrypted, pushed offsite, pruned on a schedule. It took deliberate work to get dumps working on the community edition of the database. Worth it. This thing now holds years of business reasoning, losing it would hurt more than losing code (code has git).
The stack is open source (Graphiti by Zep, Neo4j underneath) and none of the discipline depends on my setup. The recipe:
I am not claiming to have invented any of this. Graphiti is someone else's excellent open source work, and "give the agent memory" is a whole product category now. What I have done is treat domain memory as operational infrastructure: scoped, disciplined, ingested from the real sources, tested by evals, and pointed at the place it pays off most, which is planning. An agent that knows why your systems are the way they are plans like a colleague. One that does not, plans like a contractor on day one, every day.
I use my tooling predominantly on Mage-OS (Adobe Commerce / Magento) e-commerce projects, and my own AI Booking Agent. If you have not swapped to Mage-OS yet, you are falling behind ;)