memfix
# memfix
[](LICENSE)
[](pyproject.toml)
**The memory layer that can be corrected.**
Agent memory leaders store facts they cannot update, cannot source, and cannot delete. A community audit of 10,134 mem0 entries found **97.8% junk**, produced *by the architecture*: no provenance (once a fact is extracted, the link to the source conversation is severed), no UPDATE path (contradictions are stored forever), and unmeasured recall.
memfix is provenance-first memory: every fact is a versioned claim with a source pointer, timestamps, and supersession links. Corrections are real operations, not wishes. Nothing is ever hard-deleted.
- **Provenance on every fact** — conversation/run ID, turn, origin. The severed link, fixed.
- **Real corrections API** — `assert` / `retract` / `supersede` with tombstones. "Forget that I prefer tea" compiles to a deterministic invalidation.
- **Contradiction detection** — the materialized current-truth view flags facts that disagree, instead of storing both forever.
- **Recall instrumentation** — every injection is logged (what, tokens, which query). The metric nobody measures, measured.
- **`memfix audit`: the wedge** — point it at a memory store and get the junk report: duplicates, contradictions, orphans, stale facts. Then `--fix` tombstones them.
- **Migration importers** — pull in mem0, claude-mem, or JSONL stores, then audit *their* junk on *your* machine.
- **Namespaces + per-tenant encryption** — multi-agent isolation; SQLite by default, Postgres via `MEMFIX_DATABASE_URL`.
- **MCP server** — memory tools for any agent host.
## The audit
```
$ memfix import --format mem0 ./mem0-export.json
imported 10134 facts from ./mem0-export.json (format mem0)
$ memfix audit
audited 10134 active facts in namespace 'default'
junk: 9911 (97.8%)
contradiction: 312
duplicate: 4210
orphan: 5389
$ memfix audit --fix --yes
fixed: {"duplicates": 4210, "orphans": 5389, "stale": 0, "contradictions_flagged": 312}
```
Contradictions are flagged, never auto-fixed. Picking the true fact needs a human or a newer assertion.
## Quick start
```bash
pip install memfix
```
```python
from memfix import Memory
mem = Memory() # ~/.memfix/memfix.db
fid = mem.assert_fact("the user prefers tea",
source={"conversation_id": "c1", "turn": 4})
mem.search("what does the user like to drink")
# [{'id': 'mem_...', 'fact': 'the user prefers tea'}]
# the user changes their mind: no duplicate, no contradiction stored forever
mem.supersede(fid, "the user prefers coffee", reason="user corrected")
# natural language, deterministic result
mem.correct_nl("forget that I prefer coffee")
# every recall is instrumented
mem.stats()
# {'active': 0, 'retracted': 1, 'superseded': 1, 'recalls': 2, 'tokens_injected': 14, ...}
```
```bash
memfix add "the deploy key expires Friday" --source run-42
memfix search "deploy key"
memfix correct "forget about the deploy key"
memfix history --id mem_9f3a...
memfix audit --fix
```
## How it compares
| | mem0 | claude-mem | hindsight | **memfix** |
|---|---|---|---|---|
| Provenance (source pointer per fact) | No | Partial | No | **Yes** |
| Real UPDATE / corrections API | No (ADD-only v2) | No | Delete is a no-op | **assert / retract / supersede** |
| Tombstones (nothing hard-deleted) | No | No | No | **Yes** |
| Contradiction detection | No | No | No | **Yes** |
| One-command junk audit | No | No | No | **`memfix audit`** |
| Recall instrumentation | No | No | No | **Yes** |
| Importers from rivals | n/a | n/a | n/a | **mem0 / claude-mem / JSONL** |
| Per-tenant namespaces | Broken (#4126) | Manual merges | ID collisions | **Yes** |
## MCP server
```bash
memfix-mcp # or: python -m memfix.mcp_server
```
Tools: `memory_assert`, `memory_search`, `memory_correct`, `memory_retract`, `memory_audit`.
## Layout
| File | Job |
|---|---|
| `memfix/ledger.py` | Provenance-first ledger, corrections API, search, recall logging |
| `memfix/audit.py` | Junk detection: duplicates, contradictions, orphans, stale |
| `memfix/corrections.py` | Deterministic NL correction parsing |
| `memfix/importers.py` | mem0 / claude-mem / JSONL migration |
| `memfix/crypto.py` | Per-namespace encryption (with `MEMFIX_MASTER_KEY`) |
| `memfix/db.py` | SQLite default, Postgres via `MEMFIX_DATABASE_URL` |
| `memfix/cli.py` | `add search get retract supersede correct history stats audit import` |
| `memfix/mcp_server.py` | MCP server for any agent host |
Set `MEMFIX_MASTER_KEY` to encrypt fact payloads per namespace. Set `MEMFIX_DATABASE_URL=postgresql://...` for Postgres.
MIT licensed. Not affiliated with mem0, Anthropic, or hindsight.
TDQS
Scored across 5 tools
Each tool targets a distinct action on memory facts: search reads, assert creates, retract tombstones, audit reports quality, correct applies natural-language fixes. The only mild overlap is between memory_correct and memory_retract, since a natural-language correction may imply a retraction, but the descriptions distinguish them (NL correction vs. explicit tombstone).
All five tools use a consistent memory_verb snake_case pattern with clear, distinct verbs. No mixing of conventions or verb styles.
Five tools is well-scoped for a memory/fact-management server, covering the essential lifecycle operations without redundancy or bloat. Each tool earns its place.
The surface covers create (assert), read (search), update/delete (correct, retract), and quality (audit), which is solid lifecycle coverage. A direct fetch-by-id or explicit fact update tool is missing, though assert returning an id partially mitigates this.