Open source · zero dependencies

Your agent remembers.
lattice proves it.

Claude Code, Cursor, claude-mem — your agent already captures memory. The problem is it fills with speculation it later cites as fact, goes stale, and nobody can prove where a "fact" came from. lattice is the gate that keeps memory honest: every claim carries a citation, uncited claims are blocked (lattice lint), and lattice verify checks the source still backs the claim — runnable in CI. A tiny CLI + markdown convention. No database, no server.

pipx install · no API keys works in Claude Code, Cursor, Aider plain .md — grep-able forever
~/knowledge — lattice
The drift problem

One file. Growing unbounded.
Quietly lying to your agent.

Loose memory rots. Facts go stale, speculation hardens into "truth," and a 50K-token wall of context dominates every new session — most of it irrelevant to the task at hand.

◆ CLAUDE.md, six months in

CLAUDE.md 47,300 tokens
────────────────────────────
“PaymentGateway uses Redis…” uncited
“the queue retries 3×…” stale?
“auth tokens last 24h…” who said?
… +1,900 more lines the model skims

◆ A lattice vault

flows/checkout.md cited ✓
components/payment-gateway.md verified ✓
api/billing.md fresh ✓
speculation → quarantined in ## Open questions
lattice context → only ~2,140 tokens loaded
How it works

Three guarantees, enforced mechanically.

A linter, a retriever, and a graph — each running locally over plain markdown.

The verification gate

Every named service, endpoint, or fact must carry a citation. Uncited claims can't enter the body — lattice lint blocks them. Speculation lives in a quarantined section.

Token-aware retrieval

lattice context "…" returns only the smallest relevant subgraph — BM25 over headings, expanded one hop along [[wikilinks]], trimmed to a token budget. Not the whole vault.

A graph, not a folder

[[wikilinks]] form the edges. lattice link maintains bidirectional Referenced by backlinks automatically — idempotently, never destroying an edge. Works in Obsidian, in grep, in any agent.

Architecture

One engine. Three faces.

You, your agent, and your CI all reach the same core in-process — over a plain-markdown vault on disk. No server, no database.

The toolbox

Small surface. Sharp edges.

Fifteen commands, one plain-markdown vault underneath — adapt it to any system, any team, any agent.

lattice lint

The cited-fact checker. Flags un-cited claims, missing sections, and token-budget breaches. Your pre-commit hook for memory — it stays out of the way until your facts drift, then yells.

lattice context

Deterministic, embedding-free retrieval over the link graph. Emits a token-bounded manifest your agent can read directly — load 2K of a 50K vault, not all of it.

lattice link

Bidirectional backlinks, rebuilt idempotently. Never destroys an edge.

lattice stale

Surfaces every note older than N days. Your memory has a freshness date.

lattice digest

Compresses an unbounded session history into a re-loadable index. ~80% smaller.

lattice doctor

One-command health check: note count, tokens, stale, orphans, budget breaches, lint status. Exits non-zero on real problems.

lattice used

Tell it which notes actually helped; context learns and ranks them higher. Fully local — no telemetry ever leaves your machine.

lattice refresh

Pluggable source adapters draft candidate notes from your activity. Built-in git adapter, zero network. Opt-in, review-gated.

memlattice[embeddings]

Want semantic ranking? Install the optional extra and context uses a local embedding model — no API, no server. Not installed? It silently falls back to BM25. The core stays dependency-light either way.

lattice schedule · lattice budget

No daemon — schedule prints a cron/launchd snippet you install yourself. A [budget] max_usd_per_day cost circuit-breaker guards every LLM path and defaults to $0 — never spends without your explicit override.

Config-driven, for any system you use

Citation schemes and note types are yours to define. Ship with vendor-neutral defaults (file doc url commit pr) and add your own — jira, linear, notion — in one line of config.toml. No vendor is baked into the core. Tool-agnostic by design: Claude Code, Cursor, Windsurf, Aider, Continue all read the same files.

Self-building, safely

Memory that writes itself —
but never without your sign-off.

Source adapters draft notes from your activity, but a draft is uncited and lands in a review gate. It cannot reach your verified corpus until you promote it — and even then it still has to earn its citations.

Nothing runs unattended: refresh is explicit, and the only paths that can spend money are guarded by a [budget] ceiling that defaults to zero. Silence is never green.

The five opinions

Opinionated where it prevents drift.

Structure by construction

Configurable layers — components, flows, api, or your own — so loose memory becomes organized automatically.

Verification gates

Every fact cites a source. Speculation is physically quarantined and can't pollute the body.

Graph via markdown

[[wikilinks]], not a database. Works in Obsidian, in grep, in any LLM.

Tool-agnostic

One vault, every agent. Per-tool entry stubs are thin pointers, not lock-in.

Token-aware

Load the smallest relevant subgraph. Frontmatter budgets keep files from running away.

Why not just…

Where lattice sits.

A convention plus a small CLI — not a service, not a runtime, not vendor lock-in.

latticeCLAUDE.md / AGENTS.mdHosted memory runtimesObsidian + RAG plugin
File-native plain markdown● yes● yes○ opaque store● yes
Citation / verification gate● enforced○ none○ none○ none
Token-bounded retrieval● built-in○ loads all● yes● yes
No server / no database● none● none○ hosted○ plugin runtime
Multi-tool (CC / Cursor / Aider)● any○ per-tool○ single SDK○ Obsidian only
Bounded file growth● lint budgets○ unbounded● managed○ manual
Get started

Shrink your CLAUDE.md from
1,800 lines to 30.

Install, run init, and within 15 minutes your agent is reading verified memory — selectively, by relevance, on every query.

$ pipx install memlattice