
memlineage
memlineage is an agent-memory firewall. Saved text is trusted on later turns, so one planted line can steer an agent for weeks. The check is the origin of the write. A lesson taken from a web page is quarantined. A preference the user typed is allowed. memlineage show prints the source, the taint, and the rule that fired. memlineage verify walks the hash chain.
The decision lives in memlineage-core. The Python package is a thin PyO3 binding built with maturin, so pip install memlineage runs the same engine. The CLI and the MCP proxy call that core too. A rewrite does not clean a record: a derived write lists its parents, and the taint is the union of theirs.
The policy file is YAML. The first matching rule wins. No match quarantines the write. A sample rule holds lessons, procedures, and goals that carry web or document taint, and another rule allows a write whose source is the user.
GitHub Repository: https://github.com/frdrckj/memlineage
PyPI: memlineage
Crates: memlineage-core · memlineage-cli · memlineage-mcp-proxy
Features
- Provenance on every write: Each record carries source, trust, principal, session, parent ids, a SHA-256, and a taint set. No mark means source
unknown, and the default policy quarantines it. - Taint that survives a rewrite: Derived writes keep the union of their parents' taint. Releasing a web record does not make a later lesson from that record clean.
- Policy engine: Allow, quarantine, or block. First match wins. Fail closed. The sample policy blocks instruction-shaped text from the web before the lessons rule, so a sentence with no instruction phrase can still be held.
- Store adapters: A Mem0 wrapper and a LangGraph
GuardedStorecall the core and keep quarantine and block out of the store. Provenance rides in store metadata and is stripped on read.apply_releasedwrites an approved record and keeps the original provenance. - MCP memory proxy: A stdio proxy in front of an MCP memory server. Write tools are checked. A quarantine or a block is not forwarded. Reads are forwarded, then scrubbed of held text.
- Hash-chained audit log: SQLite at
.memlineage/audit.db.verifyreports the first broken link, and it fails when the quarantine table does not match the log.review approveandreview rejectrecord the reviewer. - Attack suite: Twelve named scenarios, ML-001 through ML-012, cover a planted lesson, a poisoned document, a cross-principal read, a derived write, a store edit that skips the firewall, and a release that skips the audit. CI runs the suite on mem0, langgraph, and mcp-memory. The decision does not depend on the store name.
Stack
• Core
- Rust - Provenance, taint, the policy engine, and the audit log. No network calls in the core.
- rusqlite - The append-only hash chain and the quarantine table.
- serde - The record and policy types.
• Python package
- PyO3 and maturin - The
memlineagewheel. Prebuilt wheels for macOS, Linux, and Windows. - PyPI -
pip install memlineage.
• CLI and proxy
- clap -
memlineagecommands:ls,show,diff,review,rollback,trace,verify, andattack run. - crates.io -
memlineage-core,memlineage-cli, andmemlineage-mcp-proxy.
• Next to a content scanner
OWASP Agent Memory Guard scans what a memory says. memlineage records where it came from. Use both.