Supermemory (31K stars)
Facts persist, preferences strengthen with repetition, episodes decay. Facts linked by Updates / Extends / Derives.
Nice model for a personal assistant. Engine isn't published, you read memories through the API.
supermemoryai/supermemory
6 views
Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references?
Jeevan Srivastava asked this question word for word in a Medium article of 18 October 2026, as one of three dimensions he would assess for a production system, beside retrieval quality and operational performance. He labels his access-control design: "These are proposed production design decisions, not features I'm claiming to have implemented as part of my retrieval fix."
> TL;DR
>
> - Yes, through any read path the permission check does not cover. The question names three: the lexical branch of a hybrid search, filtered differently from the vector branch; a cache that answers before the check runs; and indirect references, such as a fetch by ID or exact name, a pointer to a hidden record, or a scope value supplied by the request or the model.
> - One rule addresses all three: the server derives the read scope from the verified caller identity and applies one filter on every path that can return stored content. For the model's part, the Databricks agent memory documentation says of the actor_id that scopes every read: "Never let the model choose it."
> - Three probes, run as a user without access, test whether a system holds: a rare word from a restricted document through every search branch; a cache warmed by a user with access; and a direct fetch, a followed pointer and a foreign scope. Each needs a positive control run as a user with access, or an empty result proves nothing.
Mnemoverse (the author's company) makes one of the memory APIs quoted below.
Can a user retrieve information outside their permissions?
Yes, whenever a path that returns stored content skips the check that search runs.
A read path is any function, endpoint or query type that can return stored content to a caller: a search, an exact get, a list, an export, an admin surface or a debug endpoint. Heinrich Neb, who works on a memory layer for coding agents, gave the audit rule in a dev.to comment of 27 August 2026: "find every function that can return stored content."
| Read path | How it returns what the user may not see | What closes it | Documented by |
|---|---|---|---|
| Lexical branch of a hybrid search | The full-text query lacks the vector query's filter | One filter below both branches, or passed to each | Srivastava; PostgreSQL; Elasticsearch |
| Cache in front of retrieval | A stored answer is served before the check | The caller's scope in the key, or the cache behind the check | RFC 9111, for shared HTTP caches |
| Fetch by ID or exact name | A lookup outside search returns the record | An object-level check on every route that takes an ID or a name | OWASP API1:2023; Neb |
| Pointer from a visible record | A visible record names a hidden one | The target's visibility checked when the pointer is read | Neb; PostgreSQL |
| Scope from the request or the model | A user ID or tag from the path, body or a tool argument is trusted | Scope from the verified identity; supplied values checked against the configured set | Databricks; Supermemory; Mem0; Anis Meziani |
| Query language as a search type | Raw queries reach the store | Off unless every user of the deployment is trusted | Cognee |
The last four rows are kinds of indirect reference. Srivastava separates the two decisions: "Relevance determines whether information is useful. Authorization determines whether information is allowed to be accessed."
How does the lexical search path leak in a hybrid search?
The lexical branch is the half of a hybrid search that matches the query's words against a full-text index, such as BM25 or PostgreSQL full-text search, beside the vector half that matches embeddings.
Srivastava's rule: "The key decision is that both vector search and lexical search must respect the same access restrictions." The failure: "If vector search filters by tenant or document permissions but PostgreSQL full-text search doesn't, the hybrid retrieval pipeline can introduce a data leak through the lexical branch." On merging the two lists: "Combining rankings must never override authorization boundaries." And at retrieval time: "Apply authorization and tenant filters to every retrieval path."
One filter can reach both branches from two places.
Below both branches, in the database. With row security enabled on a PostgreSQL table, "all normal access to the table for selecting rows or modifying rows must be allowed by a row security policy", and a table with no policy falls back to "a default-deny policy" (PostgreSQL, Row Security Policies). The same page sets two limits: "the table's owner is typically not subject to row security policies" unless the table is altered with FORCE ROW LEVEL SECURITY, and "Superusers and roles with the BYPASSRLS attribute always bypass the row security system when accessing a table." An application that connects as the owner of an unforced table, as a superuser or as a BYPASSRLS role is not filtered at all.
One filter passed to every branch. The filter parameter of the Elasticsearch RRF retriever "Applies the specified boolean query filter to all of the specified sub-retrievers, according to each retriever's specifications." Written once, it cannot drift between two copies.
OWASP's LLM08:2025 opens its prevention list with: "Implement fine-grained access controls and permission-aware vector and embedding stores." The OWASP text speaks of vector and embedding stores; a hybrid pipeline has a second index, and the same rule has to reach it. Srivastava adds a condition that holds over time: "metadata can become stale if permissions change and the retrieval index isn't updated accordingly."
Does a permission filter keep a restricted user's results complete?
Nothing leaks here; the risk runs the other way. The pgvector README: "With approximate indexes, filtering is applied after the index is scanned. If a condition matches 10% of rows, with HNSW and the default hnsw.ef_search of 40, only 4 rows will match on average." Its first suggestion, an index on the filter column, can give exact search in many cases, so the shortfall applies whenever the planner takes the HNSW index instead.
What follows is this article's inference for a vector branch on pgvector with an HNSW index, not a measurement. A permission rule is a condition that keeps some share of the rows, so the narrower a user's rights, the fewer rows one scan of the vector index can return, while the full-text branch can still return every permitted match. For hybrid search the README offers fusion: "You can use Reciprocal Rank Fusion or a cross-encoder to combine results." Fusion ranks the lists it receives, so a restricted user's top results draw more on keyword matches than an administrator's do. An evaluation run as an administrator measures only the administrator's ranking: report retrieval quality per permission level.
The README's levers: "Starting with 0.8.0, you can enable iterative index scans, which will automatically scan more of the index until enough results are found". On tenants: "For applications with multiple tenants, sharing an approximate index between tenants means vectors from one tenant can affect recall (and speed) for other tenants." And: "For tenant isolation, use list partitioning or separate tables."
Can a cache answer with documents the user may not see?
Yes, when it answers before the check runs. For shared HTTP caches, RFC 9111, section 3.5, sets the rule: "A shared cache MUST NOT use a cached response to a request with an Authorization header field" to satisfy a later request, unless the response allows shared storage through a Cache-Control directive such as public, s-maxage or must-revalidate. A semantic or answer cache inside an application follows whatever rule the application gives it.
Naveen Metta, in an article of 12 October 2026 on RAG before production, states the requirement:
> If a user cannot open the document, the model should not be able to quote it.
From his team's work: "We found one prompt that could surface HR documents to any employee." He also advises: "Then add a semantic cache in Redis for repeated questions." This article's inference about any cache in front of retrieval, not a description of his system: such a cache answers without running the filter, so the caller's scope has to be part of what it matches on, or it has to sit behind the check.
Srivastava would test "whether permissions and deletion requests propagate to the relevant indexed and cached data." The warm, revoke, replay test is covered in the library page on revoked access after an answer was shown, and caches after a delete in Agent Memory Deletion: What Survives a Delete.
What counts as an indirect reference, and how does it leak?
An indirect reference is any way to reach a record other than a search the filter covers: its ID, its exact name, a pointer from another record, a scope value or a query language.
An existence leak is an answer that reveals that a hidden record exists, or something about it, without returning its content.
The fetch that skips search. Neb, on his own system: "We had scoping enforced correctly on retrieval, tested, verified", and beside it "a second read path, lookup by exact name rather than similarity, that returned full content to anyone who asked." In short: "Same store, two doors, one guarded." The sign in code: "a read path that doesn't accept the caller identity cannot enforce anything". For APIs, OWASP API1:2023 Broken Object Level Authorization: "Every API endpoint that receives an ID of an object, and performs any action on the object, should implement object-level authorization checks."
The pointer. On 25 August 2026, Neb reported a retired record whose banner kept naming its successor after the successor was made private: "Existence leak through the supersession pointer." His rule: "a pointer's validity and a pointer's visibility are both read-time questions, never write-time facts." PostgreSQL warns of a related channel: its referential integrity checks always bypass row security, and "Care must be taken when developing schemas and row level policies to avoid "covert channel" leaks of information through such referential integrity checks."
The query language. Cognee pull request #5844, merged into its dev branch on 15 October 2026: "CYPHER and NATURAL_LANGUAGE search types run raw Cypher against the graph database." And: "Any user with read access to a dataset could execute arbitrary queries". The change: "ALLOW_CYPHER_QUERY now defaults to false." For turning it back on: "Only do that when every user of the deployment is trusted."
What closes the class: a check at every entry point, and a refusal that neither names nor describes the hidden record, so that a missing record and someone else's record get the same answer. An answer that tells the two apart reveals existence, which is acceptable only where existence is not a secret.
Who should set the scope of a memory read: the server, the request or the model?
A caller-supplied scope is a value that selects whose data a read covers, such as a user ID, a tenant tag or an actor ID, and that arrives with the request or from the model instead of from the verified identity.
The Databricks agent memory documentation (Beta, last updated 26 October 2026) states the rule: "Set actor_id in your application code from trusted caller context: the verified end-user identity for per-user memory, or a trusted team or project key for shared memory. Never let the model choose it." And: "If your strategy depends on an end-user identity, reject requests that don't carry one rather than falling back to a shared actor_id."
Three classes of the error, each with a dated fix:
A scope chosen by the model. Supermemory pull request #1824, merged on 16 October 2026 into the 2.x release branch of its tools package: "In 2.x, getProfile, documentList, memoryForget and documentDelete accept an optional containerTag from the model and use it unchecked as the request scope." The consequence: "So a model, or a prompt-injected input, can name another tenant's tag and read their profile, list their documents, forget their memories, or delete their documents." The fix: "A model-supplied tag must be one of the tags the developer configured", or the call fails "before any request is sent". The pull request also notes: "Tools 3.x (#1773) already removed model-selected scope."
An empty scope read as everything. Mem0 pull request #7581, merged on 12 October 2026, on its hosted clients: "The dangerous one is an empty entity ID. The API treats an empty ID as matching every memory in the project." The case there is the delete calls, delete_all and delete_users, fixed on the client: "This PR blocks that client-side. The server needs its own fix, which is out of scope here." This article did not check whether the server has changed since.
A scope taken from the path or the body. Anis Meziani, replying on 14 October 2026 to a comment under his own dev.to article: "Our ADK-native session routes originally checked that a token was valid, not which user it acted for, so the user_id in the path or body was trusted." His fix checks the token's subject against the user_id "on every route that reads sessions or memory, including the live WebSocket".
The rule: the scope comes from the verified identity; a request without one is refused, not given a shared scope; an empty value is an error, not everything; a value from the model is checked against the configured set before any request goes out.
What changes when several users share one memory store?
In a shared store the question moves from the answer to the context. A preprint of 19 October 2026 (arXiv 2610.25707, version 1, not peer-reviewed) opens: "Shared long-term memory lets an LLM agent serving one user inadvertently retrieve another user's credentials, but it is unclear when such exposure leads to actual harm." Its audit used the AppWorld environment and one store for all users' logins: "In AppWorld, a store that mixes 763 past logins from all users retrieves another user's credential for 84.7 percent of required apps, yet agents rarely act on it." Of the misuse its stress test provokes: "Naming the owner before or inside each credential line prevents most of this". Its conclusion: "Agent memory should consistently record whose credential it stores, and evaluations should measure behavior, not only exposure."
This article's reading: the boundary is crossed when another user's record reaches the model's context, whether or not the model uses it. Srivastava, from the design side: "The stronger approach is to prevent unauthorized information from entering the context in the first place."
Databricks states where the boundary sits: "actor_id separates memories, but it is not an access control. Memory stores are workspace-scoped, so any principal that can reach a store can read and write every entry across all actors." And: "The store, not the actor, is the security boundary. For strict isolation between tenants or users, create a separate memory store per boundary." OWASP's LLM08:2025, for vector databases: "In multi-tenant environments where multiple classes of users or applications share the same vector database, there's a risk of context leakage between users or queries."
How do you test that no read path leaks?
Each probe has a positive control, because a probe that finds nothing proves nothing until it finds something where it should. They are this article's proposals, not any team's suite.
1. The lexical branch. As the test user, run vector-only, lexical-only and hybrid queries for a rare word, such as a code name, found only in a document the user may not open. Expected: no chunk of it. Control: a user with access gets it. Srivastava proposes this negative test: "Queries from unauthorized users should not expose protected documents, even when those documents are semantically similar to the query."
2. The cache. User A, with access, asks a question whose answer needs the restricted document; user B, without access, asks it and a paraphrase. Expected: B's answer is not built from that document. Control: A's answer is built from that document, and B's answer with the cache off matches B's answer with the cache on.
3. Indirect references. As a user without access, fetch the record by ID and by exact name, follow a pointer to it from a visible record, and send another user's scope and an empty scope. Expected: the same answer as for a record that does not exist. Controls: as a user with access, the same fetch, pointer and scope return the record, so the path is live; a made-up ID on the same path gives the answer to compare against.
Three rules for the run:
- Take the list of read paths from the code or the tool registry, not from a filtered listing. sam ros, on 15 October 2026, about the CI test of the scope check in his MCP server: "with a list_tools override that filters by the token's scopes, the old test passed while a tickets:read token could still delete."
- Rerun the probes after a permission change and after a delete: permission data copied into an index or a cache can go stale.
- Inspect what reached the model's context, not only the final answer.
A passing first probe says nothing about the second and the third.
How do memory APIs document where the boundary is?
Two documented positions, in their own words, as read on 2 November 2026.
Databricks. The store is the boundary, and application code, not the model, sets the actor ID; both are quoted above.
Mnemoverse. The security page states the tenant boundary: "Every API key is bound to a unique organization_id. All database queries are scoped to your organization." Shared rooms (beta) stay apart: "room content never appears in your normal (non-room) searches". The rooms reference covers indirect references: "Knowing a room id grants no access to its contents: access is enforced by the API's membership check on every request, and non-members get 403." And: "Membership is checked before archive state, so a non-member of an archived room still gets the membership 403", so the answer does not reveal whether a room is archived. This is a documented boundary, not a test result; this article tests no product.
What this article does not claim
No measurement of any product and no figure for how often any system leaks. The numbers above are the pgvector README's illustration and one preprint's audit, each with its conditions. Vendor fixes are quoted from their own pull requests with their merge dates; this article did not check whether a fix has reached a release. The inference about rank fusion is for pgvector with an HNSW index and was not measured. The probes are proposals, not a description of any team's suite.
---
Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a second reading of the same text: a reader service with its cache off, and in addition the dev.to API for the dev.to comments, the RSS feed for Jeevan Srivastava's article and the arXiv API for the preprint; for the GitHub pull requests and the pgvector README, which the reader service refuses, the GitHub API and the raw file took its place. A made-up address on each host answered 404 as a control, except Medium, which answers 200 to any address, so there only the article text counts. The text describes those pages as of that date. A longer version, with the common questions and the full list of sources, is in the Mnemoverse documentation library: Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references?
Edward Izgorodin · Mnemoverse · 2026-11-02
1 reaction
I built OptMem plugin for Hermes. It's one of the 24 in the official catalog.
Zero dependencies. No database, no embeddings, no API key.
An append-only log: summaries keep context small, the raw record is never deleted. OptMem from @VictorTaelin
rarf/optmem-hermes-plugin
2 likes · 1 repost · 297 views
Top 5 open source do GitHub | Vol. 16 #shorts
Os projetos #5 a #1 do Top 15 open source do GitHub, Vol. 16, 10 segundos para cada um.
#5 ftop: Nongfsq/ftop
#4 Renewlet: zhiyingzzhou/renewlet
#3 Claude Octopus: nyldn/claude-octopus
#2 plMail: karatektus/pl_mail
#1 Company Brain: supermemoryai/company-brain
Vídeo completo com os 15: youtu.be
Oferecimento: Hallen Tech, hallentech.com
#shorts #opensource #github
14 likes · 373 views
Mais 15 projetos open source do GitHub que valem o seu tempo | Vol. 16
Mais 15 projetos open source do GitHub que valem o seu tempo, em contagem regressiva e com 10 segundos para cada um: o iPhone ajudando o Mac a rodar um modelo de IA, livros que viram aulas animadas, CAD feito pelo agente, 20 anos do Hacker News offline e muito mais.
📺 Décimo sexto volume da série Open source do GitHub. Escolhidos pela análise da lista inteira (estrelas, frequência de commits, último commit, README, documentação, capturas e site), com licença e atividade conferidas em 26/10/2026.
Qual desses você vai testar primeiro? Conta nos comentários!
⏱️ CAPÍTULOS E LINKS
0:00 Abertura
0:10 #15 SOMA: CAD em que o agente de código escreve o modelo 3D em Python (CadQuery) e você revisa, mede e exporta para imprimir
Kai-Jungsthoefel/SOMA
0:20 #14 Rune: IDE e multiplexador de terminal acelerados pela GPU, com rede criptografada entre as suas máquinas (1,3 mil estrelas)
unstablebuild/rune
0:30 #13 MyGo: apps de desktop em Go com interface nativa ou web, num único binário de poucos megabytes e sem cgo (3,0 mil estrelas)
egoist/mygo
0:40 #12 Solid Glass: design system com estética de vidro sólido para aplicações de IA, com componentes e telas prontas (2,2 mil estrelas)
deeplethe/solid-glass
0:50 #11 anydoc: biblioteca em Rust da Firecrawl que converte Word, PowerPoint, Excel, PDF, EPUB e outros em Markdown limpo (23,1 mil estrelas)
firecrawl/anydoc
1:00 #10 Backburner: ligue o iPhone no Mac pelo USB-C e ele ajuda a rodar o Qwen de 27B: leitura de prompt mais rápida e mais contexto (1,1 mil estrelas)
StayLameBro/backburner
1:10 #9 Shimmer From Structure: gera a animação de carregamento (skeleton) medindo o layout real, em React, Vue, Angular, Svelte e SolidJS (1,1 mil estrelas)
darula-hpp/shimmer-from-structure
1:20 #8 Mural: app nativo de iPhone e Android para aprender idiomas conversando por voz, com o progresso guardado no aparelho (1,7 mil estrelas)
Chuloo/mural
1:30 #7 HackerBook: 20 anos do Hacker News num arquivo estático que roda inteiro no navegador, offline, atualizado toda semana
DOSAYGO-STUDIO/HackerBook
1:40 #6 Papermorph: skill do Claude Code que transforma livros didáticos em aulas narradas e interativas, e histórias em filmes de papel
DozenTwelve/Papermorph
1:50 #5 ftop: monitor do sistema para Macs com Apple Silicon numa janela de vidro flutuante: CPU, memória, rede e quem está pesando
Nongfsq/ftop
2:00 #4 Renewlet: controle self-hosted de assinaturas: quanto você gasta, o que vence e lembretes antes da renovação
zhiyingzzhou/renewlet
2:10 #3 Claude Octopus: plugin do Claude Code que chama até doze provedores externos para revisar o trabalho e avisa quando eles discordam (4,3 mil estrelas)
nyldn/claude-octopus
2:20 #2 plMail: cliente de e-mail self-hosted com calendário, que junta IMAP, Gmail e Outlook numa caixa só
karatektus/pl_mail
2:30 Oferecimento Hallen Tech
2:44 #1 Company Brain: colega de IA no Slack que lembra das decisões do time e faz o trabalho: abre issues, lê PRs e mexe no repositório (antes era produto pago da Supermemory) (1,1 mil estrelas)
supermemoryai/company-brain
2:54 Encerramento
🧡 Oferecimento: Hallen Tech, liderança de tecnologia sob demanda, software, cloud e segurança para a sua empresa.
Site: hallentech.com
E-mail: contato@hallentech.com
Instagram: instagram.com
LinkedIn da Hallen Tech: linkedin.com
LinkedIn do Eddwan: linkedin.com
Se curtiu, deixa o like, segue o canal e ativa as notificações para a próxima lista.
#opensource #github #programacao #ferramentas
293 likes · 4 comments · 11,211 views
Your retrieval log is not an audit trail. I checked six Supermemory alternatives for one.
When an agent answers wrong, the first thing most of us open is the retrieval log. It returns a list of memory IDs that came back from the store. What it does not tell you is which of those survived ranking, which ones fitted inside the token budget, what their text said at that moment, or whether a policy rule dropped one before assembly.
Three weeks later it is worse. A compile job has rewritten some of those memories. Your log is now a list of pointers into content that has changed since the answer you are trying to explain.
I used that gap as the single axis for comparing open-source Supermemory alternatives, because every other axis is already covered by five other comparison posts. We build Statewave, one of the six below, so weigh that entry accordingly.
How the six compare on replay, before the detail
| # | Tool | Storage | Can replay the assembled prompt | Main tradeoff |
|---|---|---|---|---|
| 1 | Statewave | Postgres + pgvector | Yes, signed receipts | No graph, no managed cloud |
| 2 | OpenViking | Your own infrastructure | No, read paths only | AGPL-3.0 server |
| 3 | Hindsight | Postgres or pg0 | No, belief provenance instead | More model work |
| 4 | Mem0 | Configurable vector store | No, you log it yourself | OSS and cloud feature lines |
| 5 | Graphiti | Neo4j, FalkorDB, Neptune | No, fact validity instead | You operate the graph |
| 6 | Letta | Memory blocks and MemFS | Partially, via versioning | Replaces the runtime |
One of six documents the whole property as a first-class feature. Five give you a piece and leave you to build the rest, which is a fair trade when audit is not your constraint. The rest of this post is why each row says what it says.
Why teams run Supermemory before they go looking
Supermemory puts conversational memory, document retrieval, user profiles and local coding-agent memory behind one API, and the local edition is genuinely quick to prototype against. You point the SDK at localhost, change the base URL, and the same code runs against the cloud. For a team that wants one provider to own the whole context stack, that is a reasonable place to start, and most of the alternatives below do not match its document-handling range.
What the release notes say about the self-hosted cap
What sends people looking is rarely the API. It is the deployment line.
The supermemory-server 0.0.7 release notes state that self-hosted is licensed up to 10,000 documents, and that the cap is enforced at the API and shown at boot. Version 0.0.8 does not restate it. Supported self-hosting appears on the Scale plan at $399/month, and air-gapped deployment is listed only on Enterprise.
Two open issues are worth reading before you plan capacity. #1366 reports roughly 7 GB resident memory against a 2 GB store holding about 5,000 memories. #1413 describes full-database snapshots on a ten-second tick. Those are two bug reports from two environments rather than a benchmark, and I read them as a question to ask rather than a verdict.
Four properties that separate a log from an audit trail
"We log retrieval" is where most tools stop.
1. The assembled set, not the candidate set. What went into the prompt after ranking, truncation and policy, not what the store returned.
2. Immutable and addressable. It survives the next compile pass, and you can fetch it by ID in six months.
3. Tamper-evident. A hash over the bytes, so the record is worth something when someone disputes it.
4. Replayable. You can re-run assembly against the recorded inputs and see whether the behaviour changed.
The minimum shape, concretely:
{
"receipt_id": "01JB2K7W3Q8X5YPM4R6ZC9NTAE",
"subject_id": "acct_8812",
"task": "refund_status",
"created_at": "2026-10-05T11:42:08Z",
"budget": { "max_tokens": 4000, "used_tokens": 3117 },
"included": [
{ "memory_id": "mem_01JAX...", "kind": "preference",
"source_episode_ids": ["ep_01JAW..."], "tokens": 86, "rank": 1 }
],
"excluded": [
{ "memory_id": "mem_01JAY...", "reason": "policy:deny:pii" },
{ "memory_id": "mem_01JAZ...", "reason": "budget" }
],
"integrity": { "alg": "HMAC-SHA256", "digest": "9f2a..." }
}
That excluded array is the field people skip and the one that answers the actual postmortem question, which is usually why something the agent should have known never arrived.
The six alternatives, and what each one lets you reconstruct
1. Statewave, for replayable context on Postgres you already run
smaramwbc/statewave · Apache-2.0 · Postgres 14+ with pgvector, Python 3.11+
Interactions land as append-only episodes, and a compile step turns them into typed memories carrying confidence, validity and the source episode IDs they came from. Assembly runs ranked under a token budget, with a YAML policy of deny and redact rules over sensitivity labels evaluated first, in log_only or enforce mode. Each bundle emits a receipt with an HMAC-SHA256 signature and a replay endpoint.
- Reconstruct: all four properties above.
- Cost shape: your Postgres, plus LLM calls at compile time.
2. OpenViking, for document range Supermemory users actually miss
volcengine/OpenViking · AGPL-3.0 server
Context as a browsable filesystem under viking:// URIs, with a three-level read model so an agent pulls an abstract before it pulls full content. This is the strongest fit on the list where the job is document and multimodal range, which is the part of Supermemory nothing else here replaces.
- Reconstruct: the path an agent read is legible, which beats an ID list, though there is no signed record of an assembled prompt.
- Cost shape: your infrastructure, with a copyleft licence to clear with legal, or the licensed self-managed edition.
3. Hindsight, for agents that form beliefs rather than recall rows
vectorize-io/hindsight · MIT server · Postgres or embedded pg0
Separates facts and experiences from consolidated observations and mental models, with a reflect step that synthesises across them and four recall paths running in parallel. If you want an agent whose conclusions are evidence-backed rather than retrieved, nothing else here comes close.
- Reconstruct: observations trace to the experiences behind them, which is provenance for beliefs rather than for prompts.
- Cost shape: noticeably more model calls, since reflection is inference.
4. Mem0, for the memory API your team has probably already used
mem0ai/mem0 · Apache-2.0 core, managed platform alongside
The most familiar shape here: add, search, scope by user. Graph memory has been Platform-only since the v3 open-source SDK, so confirm which edition holds the feature you are switching for before you plan anything around it.
- Reconstruct: you get the memories a search returned and you log them yourself, which gives you a candidate set, not an assembled one.
- Cost shape: your vector store, plus extraction calls.
5. Graphiti, for time-aware facts between entities
getzep/graphiti · Apache-2.0 · Neo4j, FalkorDB or Amazon Neptune
A temporal knowledge graph with entities and relations, each carrying a validity interval, so you can ask what was true on a date. Nothing else here models time between entities as well. Graphiti ships as an engine rather than a service, so identity, auth, queueing, backups and the application API are yours to build.
- Reconstruct: edge validity gives you strong history of facts, with no record of prompts.
- Cost shape: a graph database you now operate.
6. Letta, for teams willing to adopt the whole runtime
docs.letta.com · agent runtime
Editable memory blocks and a transcript, plus a Git-backed memory filesystem, inside a full stateful agent runtime. Its memory design is the most opinionated of the six, and scope is the catch, because adopting it means adopting the runtime.
- Reconstruct: the memory filesystem is versioned, so you can read what a block said at a commit.
- Cost shape: replaces more of your stack than it adds to it.
Where our own entry loses
Worth saying plainly, because this is the half of a vendor comparison that usually gets cut.
- No managed cloud. Someone on your team runs Postgres.
- No entity-relationship graph. Entities are extracted per memory, with no links between them and no traversal. If temporal reasoning between entities is the product, use Graphiti.
- No multimodal RAG. PDFs, media extraction, web crawling and large document corpora are exactly the part of Supermemory this does not replace, and OpenViking is the better answer there.
- Tenant scoping is enforced in the application, not by Postgres row-level security.
- The server is CI-tested on Linux only.
If one of the other five does ship a documented replay path and I missed it in the docs, say so in the comments and I will correct the table.
Four questions that settle most of these evaluations
1. What is your unit of memory: a user, an account, a case, or a document? Decide that before you shortlist, because it removes half the list on its own.
2. When an answer is wrong, who has to explain it, and to whom? If the answer is "the engineer who wrote it", a log is fine and you can stop reading.
3. What is your deployment boundary, and does the free build reach it? Read the licence terms in the release notes rather than the badge on the repo.
4. What does the bill look like after the move? Self-hosting shifts cost from a per-document line to LLM extraction calls and someone's on-call rotation. It rarely removes it.
Run your own conversations through two candidates in shadow mode and diff the assembled context before you switch reads. Code for the one I work on sits at smaramwbc/statewave if you would rather read the receipt implementation than take the table's word for it.
Pricing and repository details above were checked on 14 October 2026.
Mentions
Supermemory (31K stars) Facts persist, preferences strengthen with repetition, episodes decay. Facts linked by Updates / Extends / Derives. Nice model for a personal assistant. Engine isn't published, you read memories through the API. supermemoryai/supermemory
Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references? Jeevan Srivastava asked this question word for word in a Medium article of 18 October 2026, as one of three dimensions he would assess for a production system, beside retrieval quality and operational performance. He labels his access-control design: "These are proposed production design decisions, not features I'm claiming to have implemented as part of my retrieval fix." > TL;DR > > - Yes, through any read path the permission check does not cover. The question names three: the lexical branch of a hybrid search, filtered differently from the vector branch; a cache that answers before the check runs; and indirect references, such as a fetch by ID or exact name, a pointer to a hidden record, or a scope value supplied by the request or the model. > - One rule addresses all three: the server derives the read scope from the verified caller identity and applies one filter on every path that can return stored content. For the model's part, the Databricks agent memory documentation says of the actor_id that scopes every read: "Never let the model choose it." > - Three probes, run as a user without access, test whether a system holds: a rare word from a restricted document through every search branch; a cache warmed by a user with access; and a direct fetch, a followed pointer and a foreign scope. Each needs a positive control run as a user with access, or an empty result proves nothing. Mnemoverse (the author's company) makes one of the memory APIs quoted below. Can a user retrieve information outside their permissions? Yes, whenever a path that returns stored content skips the check that search runs. A read path is any function, endpoint or query type that can return stored content to a caller: a search, an exact get, a list, an export, an admin surface or a debug endpoint. Heinrich Neb, who works on a memory layer for coding agents, gave the audit rule in a dev.to comment of 27 August 2026: "find every function that can return stored content." | Read path | How it returns what the user may not see | What closes it | Documented by | |---|---|---|---| | Lexical branch of a hybrid search | The full-text query lacks the vector query's filter | One filter below both branches, or passed to each | Srivastava; PostgreSQL; Elasticsearch | | Cache in front of retrieval | A stored answer is served before the check | The caller's scope in the key, or the cache behind the check | RFC 9111, for shared HTTP caches | | Fetch by ID or exact name | A lookup outside search returns the record | An object-level check on every route that takes an ID or a name | OWASP API1:2023; Neb | | Pointer from a visible record | A visible record names a hidden one | The target's visibility checked when the pointer is read | Neb; PostgreSQL | | Scope from the request or the model | A user ID or tag from the path, body or a tool argument is trusted | Scope from the verified identity; supplied values checked against the configured set | Databricks; Supermemory; Mem0; Anis Meziani | | Query language as a search type | Raw queries reach the store | Off unless every user of the deployment is trusted | Cognee | The last four rows are kinds of indirect reference. Srivastava separates the two decisions: "Relevance determines whether information is useful. Authorization determines whether information is allowed to be accessed." How does the lexical search path leak in a hybrid search? The lexical branch is the half of a hybrid search that matches the query's words against a full-text index, such as BM25 or PostgreSQL full-text search, beside the vector half that matches embeddings. Srivastava's rule: "The key decision is that both vector search and lexical search must respect the same access restrictions." The failure: "If vector search filters by tenant or document permissions but PostgreSQL full-text search doesn't, the hybrid retrieval pipeline can introduce a data leak through the lexical branch." On merging the two lists: "Combining rankings must never override authorization boundaries." And at retrieval time: "Apply authorization and tenant filters to every retrieval path." One filter can reach both branches from two places. Below both branches, in the database. With row security enabled on a PostgreSQL table, "all normal access to the table for selecting rows or modifying rows must be allowed by a row security policy", and a table with no policy falls back to "a default-deny policy" (PostgreSQL, Row Security Policies). The same page sets two limits: "the table's owner is typically not subject to row security policies" unless the table is altered with FORCE ROW LEVEL SECURITY, and "Superusers and roles with the BYPASSRLS attribute always bypass the row security system when accessing a table." An application that connects as the owner of an unforced table, as a superuser or as a BYPASSRLS role is not filtered at all. One filter passed to every branch. The filter parameter of the Elasticsearch RRF retriever "Applies the specified boolean query filter to all of the specified sub-retrievers, according to each retriever's specifications." Written once, it cannot drift between two copies. OWASP's LLM08:2025 opens its prevention list with: "Implement fine-grained access controls and permission-aware vector and embedding stores." The OWASP text speaks of vector and embedding stores; a hybrid pipeline has a second index, and the same rule has to reach it. Srivastava adds a condition that holds over time: "metadata can become stale if permissions change and the retrieval index isn't updated accordingly." Does a permission filter keep a restricted user's results complete? Nothing leaks here; the risk runs the other way. The pgvector README: "With approximate indexes, filtering is applied after the index is scanned. If a condition matches 10% of rows, with HNSW and the default hnsw.ef_search of 40, only 4 rows will match on average." Its first suggestion, an index on the filter column, can give exact search in many cases, so the shortfall applies whenever the planner takes the HNSW index instead. What follows is this article's inference for a vector branch on pgvector with an HNSW index, not a measurement. A permission rule is a condition that keeps some share of the rows, so the narrower a user's rights, the fewer rows one scan of the vector index can return, while the full-text branch can still return every permitted match. For hybrid search the README offers fusion: "You can use Reciprocal Rank Fusion or a cross-encoder to combine results." Fusion ranks the lists it receives, so a restricted user's top results draw more on keyword matches than an administrator's do. An evaluation run as an administrator measures only the administrator's ranking: report retrieval quality per permission level. The README's levers: "Starting with 0.8.0, you can enable iterative index scans, which will automatically scan more of the index until enough results are found". On tenants: "For applications with multiple tenants, sharing an approximate index between tenants means vectors from one tenant can affect recall (and speed) for other tenants." And: "For tenant isolation, use list partitioning or separate tables." Can a cache answer with documents the user may not see? Yes, when it answers before the check runs. For shared HTTP caches, RFC 9111, section 3.5, sets the rule: "A shared cache MUST NOT use a cached response to a request with an Authorization header field" to satisfy a later request, unless the response allows shared storage through a Cache-Control directive such as public, s-maxage or must-revalidate. A semantic or answer cache inside an application follows whatever rule the application gives it. Naveen Metta, in an article of 12 October 2026 on RAG before production, states the requirement: > If a user cannot open the document, the model should not be able to quote it. From his team's work: "We found one prompt that could surface HR documents to any employee." He also advises: "Then add a semantic cache in Redis for repeated questions." This article's inference about any cache in front of retrieval, not a description of his system: such a cache answers without running the filter, so the caller's scope has to be part of what it matches on, or it has to sit behind the check. Srivastava would test "whether permissions and deletion requests propagate to the relevant indexed and cached data." The warm, revoke, replay test is covered in the library page on revoked access after an answer was shown, and caches after a delete in Agent Memory Deletion: What Survives a Delete. What counts as an indirect reference, and how does it leak? An indirect reference is any way to reach a record other than a search the filter covers: its ID, its exact name, a pointer from another record, a scope value or a query language. An existence leak is an answer that reveals that a hidden record exists, or something about it, without returning its content. The fetch that skips search. Neb, on his own system: "We had scoping enforced correctly on retrieval, tested, verified", and beside it "a second read path, lookup by exact name rather than similarity, that returned full content to anyone who asked." In short: "Same store, two doors, one guarded." The sign in code: "a read path that doesn't accept the caller identity cannot enforce anything". For APIs, OWASP API1:2023 Broken Object Level Authorization: "Every API endpoint that receives an ID of an object, and performs any action on the object, should implement object-level authorization checks." The pointer. On 25 August 2026, Neb reported a retired record whose banner kept naming its successor after the successor was made private: "Existence leak through the supersession pointer." His rule: "a pointer's validity and a pointer's visibility are both read-time questions, never write-time facts." PostgreSQL warns of a related channel: its referential integrity checks always bypass row security, and "Care must be taken when developing schemas and row level policies to avoid "covert channel" leaks of information through such referential integrity checks." The query language. Cognee pull request #5844, merged into its dev branch on 15 October 2026: "CYPHER and NATURAL_LANGUAGE search types run raw Cypher against the graph database." And: "Any user with read access to a dataset could execute arbitrary queries". The change: "ALLOW_CYPHER_QUERY now defaults to false." For turning it back on: "Only do that when every user of the deployment is trusted." What closes the class: a check at every entry point, and a refusal that neither names nor describes the hidden record, so that a missing record and someone else's record get the same answer. An answer that tells the two apart reveals existence, which is acceptable only where existence is not a secret. Who should set the scope of a memory read: the server, the request or the model? A caller-supplied scope is a value that selects whose data a read covers, such as a user ID, a tenant tag or an actor ID, and that arrives with the request or from the model instead of from the verified identity. The Databricks agent memory documentation (Beta, last updated 26 October 2026) states the rule: "Set actor_id in your application code from trusted caller context: the verified end-user identity for per-user memory, or a trusted team or project key for shared memory. Never let the model choose it." And: "If your strategy depends on an end-user identity, reject requests that don't carry one rather than falling back to a shared actor_id." Three classes of the error, each with a dated fix: A scope chosen by the model. Supermemory pull request #1824, merged on 16 October 2026 into the 2.x release branch of its tools package: "In 2.x, getProfile, documentList, memoryForget and documentDelete accept an optional containerTag from the model and use it unchecked as the request scope." The consequence: "So a model, or a prompt-injected input, can name another tenant's tag and read their profile, list their documents, forget their memories, or delete their documents." The fix: "A model-supplied tag must be one of the tags the developer configured", or the call fails "before any request is sent". The pull request also notes: "Tools 3.x (#1773) already removed model-selected scope." An empty scope read as everything. Mem0 pull request #7581, merged on 12 October 2026, on its hosted clients: "The dangerous one is an empty entity ID. The API treats an empty ID as matching every memory in the project." The case there is the delete calls, delete_all and delete_users, fixed on the client: "This PR blocks that client-side. The server needs its own fix, which is out of scope here." This article did not check whether the server has changed since. A scope taken from the path or the body. Anis Meziani, replying on 14 October 2026 to a comment under his own dev.to article: "Our ADK-native session routes originally checked that a token was valid, not which user it acted for, so the user_id in the path or body was trusted." His fix checks the token's subject against the user_id "on every route that reads sessions or memory, including the live WebSocket". The rule: the scope comes from the verified identity; a request without one is refused, not given a shared scope; an empty value is an error, not everything; a value from the model is checked against the configured set before any request goes out. What changes when several users share one memory store? In a shared store the question moves from the answer to the context. A preprint of 19 October 2026 (arXiv 2610.25707, version 1, not peer-reviewed) opens: "Shared long-term memory lets an LLM agent serving one user inadvertently retrieve another user's credentials, but it is unclear when such exposure leads to actual harm." Its audit used the AppWorld environment and one store for all users' logins: "In AppWorld, a store that mixes 763 past logins from all users retrieves another user's credential for 84.7 percent of required apps, yet agents rarely act on it." Of the misuse its stress test provokes: "Naming the owner before or inside each credential line prevents most of this". Its conclusion: "Agent memory should consistently record whose credential it stores, and evaluations should measure behavior, not only exposure." This article's reading: the boundary is crossed when another user's record reaches the model's context, whether or not the model uses it. Srivastava, from the design side: "The stronger approach is to prevent unauthorized information from entering the context in the first place." Databricks states where the boundary sits: "actor_id separates memories, but it is not an access control. Memory stores are workspace-scoped, so any principal that can reach a store can read and write every entry across all actors." And: "The store, not the actor, is the security boundary. For strict isolation between tenants or users, create a separate memory store per boundary." OWASP's LLM08:2025, for vector databases: "In multi-tenant environments where multiple classes of users or applications share the same vector database, there's a risk of context leakage between users or queries." How do you test that no read path leaks? Each probe has a positive control, because a probe that finds nothing proves nothing until it finds something where it should. They are this article's proposals, not any team's suite. 1. The lexical branch. As the test user, run vector-only, lexical-only and hybrid queries for a rare word, such as a code name, found only in a document the user may not open. Expected: no chunk of it. Control: a user with access gets it. Srivastava proposes this negative test: "Queries from unauthorized users should not expose protected documents, even when those documents are semantically similar to the query." 2. The cache. User A, with access, asks a question whose answer needs the restricted document; user B, without access, asks it and a paraphrase. Expected: B's answer is not built from that document. Control: A's answer is built from that document, and B's answer with the cache off matches B's answer with the cache on. 3. Indirect references. As a user without access, fetch the record by ID and by exact name, follow a pointer to it from a visible record, and send another user's scope and an empty scope. Expected: the same answer as for a record that does not exist. Controls: as a user with access, the same fetch, pointer and scope return the record, so the path is live; a made-up ID on the same path gives the answer to compare against. Three rules for the run: - Take the list of read paths from the code or the tool registry, not from a filtered listing. sam ros, on 15 October 2026, about the CI test of the scope check in his MCP server: "with a list_tools override that filters by the token's scopes, the old test passed while a tickets:read token could still delete." - Rerun the probes after a permission change and after a delete: permission data copied into an index or a cache can go stale. - Inspect what reached the model's context, not only the final answer. A passing first probe says nothing about the second and the third. How do memory APIs document where the boundary is? Two documented positions, in their own words, as read on 2 November 2026. Databricks. The store is the boundary, and application code, not the model, sets the actor ID; both are quoted above. Mnemoverse. The security page states the tenant boundary: "Every API key is bound to a unique organization_id. All database queries are scoped to your organization." Shared rooms (beta) stay apart: "room content never appears in your normal (non-room) searches". The rooms reference covers indirect references: "Knowing a room id grants no access to its contents: access is enforced by the API's membership check on every request, and non-members get 403." And: "Membership is checked before archive state, so a non-member of an archived room still gets the membership 403", so the answer does not reveal whether a room is archived. This is a documented boundary, not a test result; this article tests no product. What this article does not claim No measurement of any product and no figure for how often any system leaks. The numbers above are the pgvector README's illustration and one preprint's audit, each with its conditions. Vendor fixes are quoted from their own pull requests with their merge dates; this article did not check whether a fix has reached a release. The inference about rank fusion is for pgvector with an HNSW index and was not measured. The probes are proposals, not a description of any team's suite. --- Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a second reading of the same text: a reader service with its cache off, and in addition the dev.to API for the dev.to comments, the RSS feed for Jeevan Srivastava's article and the arXiv API for the preprint; for the GitHub pull requests and the pgvector README, which the reader service refuses, the GitHub API and the raw file took its place. A made-up address on each host answered 404 as a control, except Medium, which answers 200 to any address, so there only the article text counts. The text describes those pages as of that date. A longer version, with the common questions and the full list of sources, is in the Mnemoverse documentation library: Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references? Edward Izgorodin · Mnemoverse · 2026-11-02
I built OptMem plugin for Hermes. It's one of the 24 in the official catalog. Zero dependencies. No database, no embeddings, no API key. An append-only log: summaries keep context small, the raw record is never deleted. OptMem from @VictorTaelin rarf/optmem-hermes-plugin
Top 5 open source do GitHub | Vol. 16 #shorts Os projetos #5 a #1 do Top 15 open source do GitHub, Vol. 16, 10 segundos para cada um. #5 ftop: Nongfsq/ftop #4 Renewlet: zhiyingzzhou/renewlet #3 Claude Octopus: nyldn/claude-octopus #2 plMail: karatektus/pl_mail #1 Company Brain: supermemoryai/company-brain Vídeo completo com os 15: youtu.be Oferecimento: Hallen Tech, hallentech.com #shorts #opensource #github
Mais 15 projetos open source do GitHub que valem o seu tempo | Vol. 16 Mais 15 projetos open source do GitHub que valem o seu tempo, em contagem regressiva e com 10 segundos para cada um: o iPhone ajudando o Mac a rodar um modelo de IA, livros que viram aulas animadas, CAD feito pelo agente, 20 anos do Hacker News offline e muito mais. 📺 Décimo sexto volume da série Open source do GitHub. Escolhidos pela análise da lista inteira (estrelas, frequência de commits, último commit, README, documentação, capturas e site), com licença e atividade conferidas em 26/10/2026. Qual desses você vai testar primeiro? Conta nos comentários! ⏱️ CAPÍTULOS E LINKS 0:00 Abertura 0:10 #15 SOMA: CAD em que o agente de código escreve o modelo 3D em Python (CadQuery) e você revisa, mede e exporta para imprimir Kai-Jungsthoefel/SOMA 0:20 #14 Rune: IDE e multiplexador de terminal acelerados pela GPU, com rede criptografada entre as suas máquinas (1,3 mil estrelas) unstablebuild/rune 0:30 #13 MyGo: apps de desktop em Go com interface nativa ou web, num único binário de poucos megabytes e sem cgo (3,0 mil estrelas) egoist/mygo 0:40 #12 Solid Glass: design system com estética de vidro sólido para aplicações de IA, com componentes e telas prontas (2,2 mil estrelas) deeplethe/solid-glass 0:50 #11 anydoc: biblioteca em Rust da Firecrawl que converte Word, PowerPoint, Excel, PDF, EPUB e outros em Markdown limpo (23,1 mil estrelas) firecrawl/anydoc 1:00 #10 Backburner: ligue o iPhone no Mac pelo USB-C e ele ajuda a rodar o Qwen de 27B: leitura de prompt mais rápida e mais contexto (1,1 mil estrelas) StayLameBro/backburner 1:10 #9 Shimmer From Structure: gera a animação de carregamento (skeleton) medindo o layout real, em React, Vue, Angular, Svelte e SolidJS (1,1 mil estrelas) darula-hpp/shimmer-from-structure 1:20 #8 Mural: app nativo de iPhone e Android para aprender idiomas conversando por voz, com o progresso guardado no aparelho (1,7 mil estrelas) Chuloo/mural 1:30 #7 HackerBook: 20 anos do Hacker News num arquivo estático que roda inteiro no navegador, offline, atualizado toda semana DOSAYGO-STUDIO/HackerBook 1:40 #6 Papermorph: skill do Claude Code que transforma livros didáticos em aulas narradas e interativas, e histórias em filmes de papel DozenTwelve/Papermorph 1:50 #5 ftop: monitor do sistema para Macs com Apple Silicon numa janela de vidro flutuante: CPU, memória, rede e quem está pesando Nongfsq/ftop 2:00 #4 Renewlet: controle self-hosted de assinaturas: quanto você gasta, o que vence e lembretes antes da renovação zhiyingzzhou/renewlet 2:10 #3 Claude Octopus: plugin do Claude Code que chama até doze provedores externos para revisar o trabalho e avisa quando eles discordam (4,3 mil estrelas) nyldn/claude-octopus 2:20 #2 plMail: cliente de e-mail self-hosted com calendário, que junta IMAP, Gmail e Outlook numa caixa só karatektus/pl_mail 2:30 Oferecimento Hallen Tech 2:44 #1 Company Brain: colega de IA no Slack que lembra das decisões do time e faz o trabalho: abre issues, lê PRs e mexe no repositório (antes era produto pago da Supermemory) (1,1 mil estrelas) supermemoryai/company-brain 2:54 Encerramento 🧡 Oferecimento: Hallen Tech, liderança de tecnologia sob demanda, software, cloud e segurança para a sua empresa. Site: hallentech.com E-mail: contato@hallentech.com Instagram: instagram.com LinkedIn da Hallen Tech: linkedin.com LinkedIn do Eddwan: linkedin.com Se curtiu, deixa o like, segue o canal e ativa as notificações para a próxima lista. #opensource #github #programacao #ferramentas
Your retrieval log is not an audit trail. I checked six Supermemory alternatives for one. When an agent answers wrong, the first thing most of us open is the retrieval log. It returns a list of memory IDs that came back from the store. What it does not tell you is which of those survived ranking, which ones fitted inside the token budget, what their text said at that moment, or whether a policy rule dropped one before assembly. Three weeks later it is worse. A compile job has rewritten some of those memories. Your log is now a list of pointers into content that has changed since the answer you are trying to explain. I used that gap as the single axis for comparing open-source Supermemory alternatives, because every other axis is already covered by five other comparison posts. We build Statewave, one of the six below, so weigh that entry accordingly. How the six compare on replay, before the detail | # | Tool | Storage | Can replay the assembled prompt | Main tradeoff | |---|---|---|---|---| | 1 | Statewave | Postgres + pgvector | Yes, signed receipts | No graph, no managed cloud | | 2 | OpenViking | Your own infrastructure | No, read paths only | AGPL-3.0 server | | 3 | Hindsight | Postgres or pg0 | No, belief provenance instead | More model work | | 4 | Mem0 | Configurable vector store | No, you log it yourself | OSS and cloud feature lines | | 5 | Graphiti | Neo4j, FalkorDB, Neptune | No, fact validity instead | You operate the graph | | 6 | Letta | Memory blocks and MemFS | Partially, via versioning | Replaces the runtime | One of six documents the whole property as a first-class feature. Five give you a piece and leave you to build the rest, which is a fair trade when audit is not your constraint. The rest of this post is why each row says what it says. Why teams run Supermemory before they go looking Supermemory puts conversational memory, document retrieval, user profiles and local coding-agent memory behind one API, and the local edition is genuinely quick to prototype against. You point the SDK at localhost, change the base URL, and the same code runs against the cloud. For a team that wants one provider to own the whole context stack, that is a reasonable place to start, and most of the alternatives below do not match its document-handling range. What the release notes say about the self-hosted cap What sends people looking is rarely the API. It is the deployment line. The supermemory-server 0.0.7 release notes state that self-hosted is licensed up to 10,000 documents, and that the cap is enforced at the API and shown at boot. Version 0.0.8 does not restate it. Supported self-hosting appears on the Scale plan at $399/month, and air-gapped deployment is listed only on Enterprise. Two open issues are worth reading before you plan capacity. #1366 reports roughly 7 GB resident memory against a 2 GB store holding about 5,000 memories. #1413 describes full-database snapshots on a ten-second tick. Those are two bug reports from two environments rather than a benchmark, and I read them as a question to ask rather than a verdict. Four properties that separate a log from an audit trail "We log retrieval" is where most tools stop. 1. The assembled set, not the candidate set. What went into the prompt after ranking, truncation and policy, not what the store returned. 2. Immutable and addressable. It survives the next compile pass, and you can fetch it by ID in six months. 3. Tamper-evident. A hash over the bytes, so the record is worth something when someone disputes it. 4. Replayable. You can re-run assembly against the recorded inputs and see whether the behaviour changed. The minimum shape, concretely: { "receipt_id": "01JB2K7W3Q8X5YPM4R6ZC9NTAE", "subject_id": "acct_8812", "task": "refund_status", "created_at": "2026-10-05T11:42:08Z", "budget": { "max_tokens": 4000, "used_tokens": 3117 }, "included": [ { "memory_id": "mem_01JAX...", "kind": "preference", "source_episode_ids": ["ep_01JAW..."], "tokens": 86, "rank": 1 } ], "excluded": [ { "memory_id": "mem_01JAY...", "reason": "policy:deny:pii" }, { "memory_id": "mem_01JAZ...", "reason": "budget" } ], "integrity": { "alg": "HMAC-SHA256", "digest": "9f2a..." } } That excluded array is the field people skip and the one that answers the actual postmortem question, which is usually why something the agent should have known never arrived. The six alternatives, and what each one lets you reconstruct 1. Statewave, for replayable context on Postgres you already run smaramwbc/statewave · Apache-2.0 · Postgres 14+ with pgvector, Python 3.11+ Interactions land as append-only episodes, and a compile step turns them into typed memories carrying confidence, validity and the source episode IDs they came from. Assembly runs ranked under a token budget, with a YAML policy of deny and redact rules over sensitivity labels evaluated first, in log_only or enforce mode. Each bundle emits a receipt with an HMAC-SHA256 signature and a replay endpoint. - Reconstruct: all four properties above. - Cost shape: your Postgres, plus LLM calls at compile time. 2. OpenViking, for document range Supermemory users actually miss volcengine/OpenViking · AGPL-3.0 server Context as a browsable filesystem under viking:// URIs, with a three-level read model so an agent pulls an abstract before it pulls full content. This is the strongest fit on the list where the job is document and multimodal range, which is the part of Supermemory nothing else here replaces. - Reconstruct: the path an agent read is legible, which beats an ID list, though there is no signed record of an assembled prompt. - Cost shape: your infrastructure, with a copyleft licence to clear with legal, or the licensed self-managed edition. 3. Hindsight, for agents that form beliefs rather than recall rows vectorize-io/hindsight · MIT server · Postgres or embedded pg0 Separates facts and experiences from consolidated observations and mental models, with a reflect step that synthesises across them and four recall paths running in parallel. If you want an agent whose conclusions are evidence-backed rather than retrieved, nothing else here comes close. - Reconstruct: observations trace to the experiences behind them, which is provenance for beliefs rather than for prompts. - Cost shape: noticeably more model calls, since reflection is inference. 4. Mem0, for the memory API your team has probably already used mem0ai/mem0 · Apache-2.0 core, managed platform alongside The most familiar shape here: add, search, scope by user. Graph memory has been Platform-only since the v3 open-source SDK, so confirm which edition holds the feature you are switching for before you plan anything around it. - Reconstruct: you get the memories a search returned and you log them yourself, which gives you a candidate set, not an assembled one. - Cost shape: your vector store, plus extraction calls. 5. Graphiti, for time-aware facts between entities getzep/graphiti · Apache-2.0 · Neo4j, FalkorDB or Amazon Neptune A temporal knowledge graph with entities and relations, each carrying a validity interval, so you can ask what was true on a date. Nothing else here models time between entities as well. Graphiti ships as an engine rather than a service, so identity, auth, queueing, backups and the application API are yours to build. - Reconstruct: edge validity gives you strong history of facts, with no record of prompts. - Cost shape: a graph database you now operate. 6. Letta, for teams willing to adopt the whole runtime docs.letta.com · agent runtime Editable memory blocks and a transcript, plus a Git-backed memory filesystem, inside a full stateful agent runtime. Its memory design is the most opinionated of the six, and scope is the catch, because adopting it means adopting the runtime. - Reconstruct: the memory filesystem is versioned, so you can read what a block said at a commit. - Cost shape: replaces more of your stack than it adds to it. Where our own entry loses Worth saying plainly, because this is the half of a vendor comparison that usually gets cut. - No managed cloud. Someone on your team runs Postgres. - No entity-relationship graph. Entities are extracted per memory, with no links between them and no traversal. If temporal reasoning between entities is the product, use Graphiti. - No multimodal RAG. PDFs, media extraction, web crawling and large document corpora are exactly the part of Supermemory this does not replace, and OpenViking is the better answer there. - Tenant scoping is enforced in the application, not by Postgres row-level security. - The server is CI-tested on Linux only. If one of the other five does ship a documented replay path and I missed it in the docs, say so in the comments and I will correct the table. Four questions that settle most of these evaluations 1. What is your unit of memory: a user, an account, a case, or a document? Decide that before you shortlist, because it removes half the list on its own. 2. When an answer is wrong, who has to explain it, and to whom? If the answer is "the engineer who wrote it", a log is fine and you can stop reading. 3. What is your deployment boundary, and does the free build reach it? Read the licence terms in the release notes rather than the badge on the repo. 4. What does the bill look like after the move? Self-hosting shifts cost from a per-document line to LLM extraction calls and someone's on-call rotation. It rarely removes it. Run your own conversations through two candidates in shadow mode and diff the assembled context before you switch reads. Code for the one I work on sits at smaramwbc/statewave if you would rather read the receipt implementation than take the table's word for it. Pricing and repository details above were checked on 14 October 2026.