Explainable, auditable
memory infrastructure for AI
An old fact is never overwritten, every recall can say why it was selected, and delete, export and audit are each an API call.
Explainable · Auditable · Controllable · Provable
Measured performance
Numbers you can trust,
because the basis is printed beside them.
Anyone can claim SOTA. The judge model, the question set, the exclusion rule and the number of runs — we print all four under every figure. Evidence is what you can reproduce.
The problem
Users never say "your recall is low."
They say "you forgot what I told you."
"What about that thing I mentioned?"
Memory gets pruned without recording why. It was stored — and then it quietly disappeared in some compaction pass. You cannot find where it went, and "I forgot" is not an answer the user accepts.
"Its impression of me changed for no reason."
Profiles are written by overwriting: today’s extraction buries yesterday’s. In March you said the budget was 200k; in June you revised it to 500k. After the overwrite, "what did you think back then" has no answer at all.
"Why did you bring that up?"
Retrieval is a black box. It serves an entirely irrelevant memory, and you can neither ask why it was selected nor tell it that this one is wrong. Next turn it comes back again.
"I do not work there any more."
With a single timestamp you cannot separate when something was true from when you learned it. So the 2023 employer and this year’s employer get packed into the same context.
Models change. Vendors change. Regulators do not relax.
“Only memory you can audit is memory you can ship.”
Same question. With and without memory, these are not the same answer.
「I'm negotiating a partnership with Lao Zhou next week. There's real risk in this deal — how should I play it?」
Returns the negotiation advice you can find anywhere: BATNA, whether to anchor first. It does not know who Lao Zhou is, what this went wrong for you before, or how you make decisions.
Lao Zhou is impatient and likes to settle things verbally — and a verbal agreement already cost you once with him. Consistent with your standing rule of drawing the risk boundary first and never committing verbally: affirm the direction, then put risk and responsibility in writing. Keep the tone warm and leave yourself room.
- "a verbal agreement already cost you"→ back to the original conversation on 2025-11-02
- "draw the risk boundary first"→ profile slot decision-style/cautious · drills down to every fact supporting it
The difference is not the model. It is whether the model has your ledger — and whether every line in it can be traced.
Mechanisms
Three mechanisms on one foundation
How the ledger records, how recall explains itself, and who the memory belongs to — these three decide whether you can audit it. The foundation decides something else: what you are left holding when something fails.
backend/src/memcore/models.py:307-311 (valid_from / valid_to / ingested_at / expired_at + invalidated_by_message_id)
Red-ink reversal: three time axes turn edits into inserts
A fact hangs on two axes at once — the reality axis says when it was true, the system axis says when we learned it and when it was invalidated. Only once they are separated can you claim nothing is silently lost or silently altered.
| Record | Fact | valid_from | valid_to | ingested_at | expired_at |
|---|---|---|---|---|---|
| #1041 | Works at Company A | 2023-03-06 | — | 2023-06-12 | — |
| #1041 | Works at Company A | 2023-03-06 | 2024-01-20 | 2023-06-12 | 2024-02-03 |
| #2288 | Works at Company B | 2024-01-21 | — | 2024-02-03 | — |
#1041 was neither deleted nor rewritten — it was stamped with expired_at and invalidated_by=#2288, and the original row stays on the books.
In an overwrite-based system these two questions share a single answer.
Every memory can explain why it came to mind
Retrieval runs six paths in parallel — vector, keyword, graph, temporal, spatial, recency — fused with RRF. The fusion is transparent to the caller: not one opaque score, but the rank and contribution of every path.
{
"statement": "Melanie plays clarinet.",
"why": {
"matched_paths": { "vector": {"rank": 2}, "keyword": {"rank": 2}, "graph": {"rank": 2} },
"rrf_contribution": { "vector": 0.016129, "keyword": 0.016129, "graph": 0.012903 },
"validity": { "state": "current", "valid_from": "2023-08-28", "valid_to": null }
},
"confidence": 1.0,
"confirmed_times": 1
}All three content paths hit with consistent ranks → high confidence. If only the recency path hits, the memory is not returned at all — prior paths may not introduce evidence on their own.
Your memory belongs to you
Every fade-out carries a reason
Every pruned memory is written with a forget_reason and can be restored; the pruning itself lands in the audit ledger. By default we only propose candidates — nothing runs automatically.
Deletes close over derivatives
Delete a session and its derived facts and vector entries close with it. Without a lineage chain, deletion only removes the surface and derived memories become ghosts.
One-click export
Profiles (Markdown) and the fact ledger (open format) export in full, lineage fields included. We do not hold your data hostage.
One source of truth, plus an index you can throw away
Postgres is the single source of truth; the vector store is a shadow index. Lose the index and you rebuild it; lose the ledger and it is gone. That boundary decides what you still have when things break.
| Component | Responsibility | Rebuildable |
|---|---|---|
| PostgreSQL | Fact ledger · tri-temporal · audit log | No · source of truth |
| Vector index | Semantic retrieval | Yes · rebuildable |
| Redis | Hot layer / queues / distributed locks | Yes · rebuildable |
| Object storage | Profiles and journals / export bundles | No · DB holds an index copy |
Integration
Two paths: change nothing, or use five verbs
Existing apps go through the OpenAI-compatible proxy and gain long-term memory without touching a line of business code. When you need lineage, forgetting and audit, use the SDK — each of the four properties is a method, not an optional parameter buried in the docs.
from openai import OpenAI
client = OpenAI(
base_url="https://api.reglos.ai/v1", # ← change only this line
api_key="mk_live_…",
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
user="alice", # ← who the memory belongs to
messages=[{"role": "user", "content": "What instrument do I like most?"}],
)from memcore import Memcore
user = Memcore(api_key="mk_live_…").subject("alice")
user.remember("I live in Shanghai and hike on weekends.") # write
hits = user.recall("where does he live", explain=True) # retrieve + why
user.explain(hits.facts[0].id) # trace to the source
user.forget(hits.facts[0].id, reason="extracted wrong") # void, keep the trace
user.audit(limit=5) # the audit ledgerWhen ownership is ambiguous we return 400 and say what to set — never a silent shared anonymous bucket. Memory like that is useless to everyone and a privacy incident waiting to happen.
Product shape
Three surfaces, one kernel, two deployments
The top row changes the surface, the bottom row changes where it runs. The layer between them — ledger, recall, lineage, audit — is shared by all three. There is no separate "app memory" and "API memory".
Reglos App
Companion / assistant. A profile that evolves with conversation, daily review, proactive reminders on commitments.
Memory API / SDK
Write, retrieve, trace, export and cascade-delete, all open. Python / TypeScript / MCP.
Voice wearables
Anchored to time and place. Always-on, long-lived, one brain across devices.
Reglos Cloud
Hosted API, integrated in minutes. Multi-tenant isolation and row-level security implemented at the database.
Private deployment
Deployed inside your VPC, so the data stays on your own network. Bring your own model keys (BYOK); the vector layer runs on five engines, so you can keep the store you already have.
Why these four properties
Silence is the number one enemy of a memory system
All six of the following actually happened in our own system, and all six are fixed. What they share is not that something broke — it is that something broke and said nothing. The four properties are not a philosophy; they are what these six incidents forced on us.
- Silent under-recall01
Filtering happened after retrieval
pgvector's hnsw index covered only the embedding column, not the tenant field — so it fetched neighbours first and filtered tenants afterwards. How many rows you lost, nothing will tell you.
- Silent disappearance02
12 points gone, zero alerts
A multi-tenant refactor changed how vector tenant names were derived, orphaning every vector written before it. The vector store had auto tenant creation on, so querying a non-existent tenant did not fail — it quietly created an empty one and returned nothing. Accuracy went 65.3% → 53.3%.
- Silent set-swap03
A group of 191 questions dropped; the mean was computed anyway
In a third-party harness, one empty judge response raised, an entire group of 191 questions was discarded, and the mean was still computed over the remaining 1,349 and written to the results file — with one line at the end reading "1 groups had errors".
- Silent corruption04
Called upsert, only ever did insert
It raised 422 on an existing id, and callers wrapped it in try/except (a shadow index must not block the source of truth). So every write that meant to *update* a vector failed for a long time, and vectors drifted out of sync with the facts.
- Silent pollution05
Substring matching on single-character aliases
Several unrelated Chinese words share one character with the word for "home", and substring matching classified them all as the home scene. Retrieval was dirty the whole time, and not one log line was red.
- Silent under-metering06
Silently missing metering is silently missing revenue
A metering failure should not turn our Redis blip into the customer’s 5xx, so it does not block the request — but it must be logged. Without the log, a charge simply goes missing and nobody knows.
Not one of these six raised an error. Explainable, auditable, controllable, provable — that is the problem those four properties exist to solve: make the silent things speak.
Use cases
One kernel, dropped into different industries
What memory looks like differs by industry, but three requirements are shared — traceable, correctable, cleanly deletable. The more regulated the buyer, the earlier those three questions arrive.
Companions and consumer hardware
1 / 5Preferences and commitments persist across sessions, and the "it remembers me" moment is designed for. A commitment goes into its own task table with a due time; when it comes due it lands in the /v1/reminders queue, and your product decides how to raise it.
Evidence
Every number carries its basis
The figures below come from different rulers. Reporting them as one would be dishonest, so we report them apart and print the ruler alongside.
We ran the competitors ourselves
every variable aligned, only the memory system swapped| Memory system | LoCoMo accuracy | Our lead |
|---|---|---|
| Reglos | 59.8% | — |
| MemOS | 51.8% | +8.0 pt |
| mem0 OSS | 47.2% | +12.6 pt |
Basis · Industry basis (cat5 excluded, consistent with MemOS / OpenViking / memobase / supermemory / mem0) · judge gemini-2.5-pro · extraction and answering model gpt-4o-mini through one gateway · every variable but the memory system held fixed
Changing the judge changes the ruler. The same data measured under four judges spans 55.3%–63.5%, so any absolute figure must name its judge — the table above is gemini-2.5-pro.
The lead holds under both bases, with and without cat5 (+7.7 and +8.0). We adopted the correction that was less flattering to us, not the arithmetic that suited us.
An external benchmark we never tuned against
LongMemEval-S · MIT-licensed datasetTogether these are 211 questions, 42% of the set, and they are precisely the design targets of the tri-temporal ledger and conflict resolution. On an external benchmark we never tuned against, they are still our two strongest categories.
A third-party harness — judge and prompt not ours to choose
OmniMemEval · same framework as 15 memory productsBasis · OmniMemEval · LoCoMo full set, 1,540 questions · judge and answer prompt fixed by the third party · single run (2026-09-02)
2,321tokens/questionAverage injected contextBasis · OmniMemEval · LoCoMo full set, 1,540 questions · 3,574,112 tokens total · this column is largely insensitive to the judge
An accuracy figure without its measurement basis is not a number.
We benchmarked two open-source implementations ourselves and got scores more than 30 percentage points away from their self-reported figures — the gap was not capability, it was measurement basis. So every number on this page states its basis, and comparisons we cannot pin a basis to, we do not publish.
Judge failure → void the whole run
When the judging model fails, every category that needs LLM scoring goes uniformly to zero while the run "finishes normally" and writes a results file that looks completely fine and is false. The rule now: failure rate above 2% and the results are not saved.
Empty context → void the whole run
Under high concurrency, retrieval times out and the context arrives empty; the answering model correctly says "no relevant information" and is marked wrong — depressing the score by roughly 23 points with no error raised. Now a single question with empty context voids the entire run.
These two guardrails are not paper policy: both fired on our own runs and overturned conclusions we had already written down — which is when they got added to the code.
Where we are not there yet
Temporal is the weakest of the four categories and the one furthest behind the field — and tri-temporal reasoning is precisely the capability we claim as our differentiator. We put that on the record: the next round prioritises classifying temporal failure cases.
Not a logo wall — things you can reproduce
A digital-twin product team
They brought a six-layer architecture and 13 cognitive models. The two layers they themselves marked as the core moat — lifelong memory and the storage/security foundation — we can take on directly. The surrounding client, gateway and orchestration layers are ordinary engineering, not a moat, but they would genuinely have to be built.
The comparison scripts are in the repo
Every table behind the vector-store decision can be re-run. These scripts were first written in /tmp and would have vanished after the run — which would have turned "measured" back into "a pile of numbers".
Naming a customer requires their permission, so none is listed. Nothing in this section depends on a customer relationship; all of it can be verified on its own.
Pricing
Usage-based, with private deployment quoted per deployment
Memory is a long-lived asset and billing should not push you to delete it. Writes and retrievals are priced separately, and stored data does not get more expensive just for sitting there.
Free tier
- 20,000 writes / month
- 100,000 retrievals / month
- explain=1 lineage in responses, fully enabled
- One-click export and cascade delete
- Community support
Usage-based
- Multi-tenant isolation and row-level security
- Audit log retention and export
- Bring your eval set — we run it
- Ticketing and a direct engineering channel
Dedicated deployment
- Private deployment inside your VPC
- Data stays in-country, compliance pack included
- Dedicated SLA and release channel
- Kernel customisation and joint evaluation
Prices are confirmed by sales. Enterprise plans can be tailored by deployment scope, device fleet, annual usage and QPS.
Run it on the same ruler first. Everything else comes after.
If you have an eval set, we plug into it. If you do not, we use a shared third-party harness where neither the judge nor the answer prompt is ours to choose. Only a result both sides can reproduce is worth comparing.