A few weeks back, one of my AI agents quoted a client a price we had retired months earlier. It wasn't a hallucination. The dead number was sitting right there in my notes, and the agent's search ranked it above the current one, because a retired price list uses the word "price" just as often as a live one.
That was the moment I stopped trusting bolt-on "agent memory" and built my own.
Engram is an open-source, self-hosted memory layer for AI agents. It's an MCP server plus a dashboard over a plain folder of markdown files. Your agents (Claude Code, Cursor, Codex, whatever speaks MCP) read and write notes through one endpoint, the files are the source of truth, and git is the database. No vector store, no black-box "memories" you can't read.
The core idea, and the thing I'd genuinely love feedback on, is what I call authority-aware search. Normal search ranks by how well text matches your query and has no notion of which note is still true. So Engram gives every note an authority from its folder and frontmatter (locked, current, superseded, archived) and ranks by relevance x authority. A superseded note sinks below the live one, and every search result tells the agent how much to trust it. That one change is what stopped my agents from quoting dead data.
A few other things that came out of running it with several agents at once:
It's MIT, one Docker container, deploys to Railway or Render or any box with a volume.
Repo (deploy buttons in the readme): https://github.com/rwnalds/engram
The closest tools I found are hypermnesic and basic-memory, both git-backed markdown memory. The difference with Engram is the dashboard, the authority ranking, and the per-agent access control, rather than a headless server.
I'm still early and figuring out whether the authority-ranking idea generalizes past my own vault. If you run agents that keep resurfacing stale context, I'd really like to hear where this holds up or breaks for you.
the folder/frontmatter authority is a solid heuristic, and "git is the database, files are the truth" is the right call. the part i'd push on is that location-authority still can't see the one thing that actually went wrong in your price story: supersession. a retired price often lives in a perfectly legitimate note, sometimes the same note, so ranking by folder demotes low-authority junk but not a dead value sitting in a high-authority place.
the failure isn't "this note is untrustworthy," it's "this value was retired and the retirement didn't demote it." so the robust version keys authority to the value, not just the note: when you kill a price, that act has to mark the old number superseded, so a later search can't surface it even if its note still scores high on "price." authority-by-location handles the easy half, the retirement event handles the half that bit you.
we hit the identical wall building a local-first assistant, and the thing that generalizes is that "still true" can't be recovered from the text at read time, it has to be written on the supersession itself. cosine can't tell a contradiction from a duplicate. love that engram keeps it in readable files though, that's exactly where this belongs.
Interesting idea, although I think this is more of an information architecture problem than an AI problem.
A human could make exactly the same mistake if your notes are scattered everywhere and they happen to open an outdated document first.
My Obsidian vault has canonical documents that are updated whenever prices or other important information change. If I need to keep something for historical purposes, it gets moved into an Archive folder that's only used when I'm intentionally looking for historical context. Current information has a single source of truth, so there's nothing for Claude or another agent to "choose" between.
As someone who builds software, I've also built tools to solve pain points., but one thing I've learned is knowing when a problem needs a new system and when it just needs better organisation. To me, this feels like an organisation problem.
the read-side authority ranking is the easy 20% here. the part that decides whether this holds up is the write path: authority only saves you if something reliably flips the old price to superseded the moment you add the new one. if that flip is a human convention or a separate step, it gets skipped, and then authority-aware search confidently ranks a stale note as current again. the durable version is supersession as one atomic operation, the write that adds the new fact demotes its predecessor in the same commit, so add and retire can't drift apart. otherwise you've just moved the bug from retrieval to bookkeeping.
smaller second point: for facts-of-record like price or contract terms, relevance x authority is still a soft demotion, and soft loses sometimes. a thin one-line live price note can get out-ranked by a verbose retired price list that matches the query better, penalty and all. for that specific class i'd hard-exclude superseded by default and only surface it when history is explicitly asked for, rather than trusting it to sink far enough.
Treating authority as part of retrieval feels right. I would be careful about using folder location as the default authority signal, because the freshest commercial fact often lives in a working note while the polished doc is already stale. Requiring a current or superseded status, plus an expiry date for things like pricing, could make the failure visible before an agent sends it. The real test is whether an agent can explain which source it rejected and why.
I've hit the same failure with coding agents, they'll pull an old README or a doc for an API we changed months ago and treat it as equally true as the current one, because vector similarity has no concept of this used to be true. Ranking by authority instead of just recency or embedding distance is the right fix, recency alone breaks the moment someone re-saves an old doc and resets its timestamp. The part I like most is that changes are git backed, with diffs per file and rollback, because that means you can actually check what the agent's memory write changed instead of trusting a summary of it. That's the same reason I read every diff a coding agent produces rather than the commit message it writes for itself.
What I like here is that you treated the failure as an interpretation problem rather than a retrieval problem.
The agent already had the right information. It just couldn't distinguish between "historically true" and "currently true." That feels like a more fundamental issue than memory quality, and it's probably going to matter in a lot more agent workflows than pricing.