Metadata-Version: 2.4
Name: lbrain
Version: 0.1.1
Summary: LBrain by Metavolve Labs — AI-native engineering memory with the Lair Protocol.
Author: Metavolve Labs, Inc.
License: BSD-3-Clause
Project-URL: Homepage, https://lbrain.ai
Project-URL: Source, https://github.com/metavolve-labs/lbrain
Project-URL: Issues, https://github.com/metavolve-labs/lbrain/issues
Keywords: ai,llm,memory,rag,mcp,agents,retrieval,local-first
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sqlite-vec<0.2,>=0.1.6
Requires-Dist: python-frontmatter<2,>=1.1
Requires-Dist: httpx<1,>=0.27
Requires-Dist: click<9,>=8.1
Requires-Dist: tiktoken<1,>=0.7
Requires-Dist: mcp<2,>=1.0
Requires-Dist: tomli<3,>=2.0; python_version < "3.11"
Provides-Extra: archive
Requires-Dist: cryptography<46,>=44; extra == "archive"
Provides-Extra: arweave
Requires-Dist: cryptography<46,>=44; extra == "arweave"
Requires-Dist: arweave-python-client<2,>=1.0; extra == "arweave"
Provides-Extra: local
Requires-Dist: fastembed<1,>=0.3; extra == "local"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Provides-Extra: rerank
Requires-Dist: fastembed<1,>=0.3; extra == "rerank"
Dynamic: license-file

<p align="center">
  <a href="https://lbrain.ai"><img src="https://lbrain.ai/assets/lockup.jpg" alt="LBrain — a dragon coiled around a circuit-etched L" width="620"></a>
</p>

<h1 align="center">LBrain</h1>

<p align="center">
  <img src="https://img.shields.io/badge/status-BETA-c9a227?style=flat-square" alt="Status: Beta">
  <img src="https://img.shields.io/badge/license-BSD--3--Clause-555?style=flat-square" alt="BSD-3-Clause">
  <img src="https://img.shields.io/badge/python-3.10%E2%80%933.13-555?style=flat-square" alt="Python 3.10-3.13">
</p>

> **BETA — use at your own risk.** This is early software from a small team. It has not yet been through an
> independent security review. It runs on your machine against your files: **keep backups, and don't point it
> at anything you can't afford to have read by a tool that is still being hardened.** LBrain never deletes
> your source files, but that is a design commitment, not yet an audited guarantee.

**Memory for AI agents that cites its sources — and says when it doesn't know.**

Your agent reads a pile of your notes and answers confidently from the wrong one. LBrain serves each
record with its **source, its date, and a flag for whether it actually answers the question asked**.

```bash
pip install "lbrain[local]"
lbrain init --source ~/notes
lbrain import && lbrain embed --stale
lbrain query "what did we decide about the deploy flag"
```

No API key. No account. Indexing and search run on-device — your documents and queries are never
transmitted. LBrain downloads its ~67 MB embedding model once on first run; after that it works offline.

```
⟪note⟫
│ Deploy runbook          runbook.md · chunk 0 · dated 2026-05-14 · binds
│ The staging deploy uses tag v2 and the rollback flag is --safe.
⟪/note⟫
```

`binds` means the record answers the question. `near-miss` means it's the right subject but doesn't
contain the answer — the case where retrieval quietly hands over the neighbour's value and the model
presents it as fact.

## Why

We profiled **eight model architectures from seven organizations** on the same near-domain retrieval
task. Failure rates swung **1.3% / 35.7% / 16.7%** depending only on how the *records* were
structured — a **34.4 percentage-point** absolute difference — while architecture explained ≈**0%** of the
variance, with identical
ordering in 8 of 8 models. Changing models didn't remove the effect. Telling the model not to guess
didn't remove it either.

**Across the models we tested, record structure dominated the failure pattern.** So the fix belongs before generation, on the
input side, and it has to be deterministic — a gate judged without another model call.

## Related work — read these too

Four 2026 papers staked adjacent ground while we were building, and they deserve the citation:

- **Deceptive Grounding** — Caruzzo, Yoo & Kim ([arXiv:2607.09349](https://arxiv.org/abs/2607.09349)):
  named and measured the failure mode — RAG responses that pass standard quality checks while attributing
  evidence to the wrong entity, in 8–87% of cases across 13 models, with domain-specialized models
  failing *worse*.
- **MemStrata** ([arXiv:2606.26511](https://arxiv.org/abs/2606.26511)): deterministic supersession rules
  over a bi-temporal ledger, against stale-fact errors on evolving knowledge.
- **Engram** ([arXiv:2606.09900](https://arxiv.org/abs/2606.09900)): a bi-temporal memory graph tracking
  provenance and contradictions — a lean retrieved context beats the full history.
- **Don't Ask the LLM to Track Freshness** ([arXiv:2606.01435](https://arxiv.org/abs/2606.01435)):
  conflict resolution belongs in deterministic code, not model judgment — "the bottleneck … is assembly
  (post-retrieval aggregation), not storage."

We claim no priority over any of this. What our 8-model matrix adds is the controlled variable: it
reproduced the same failure class independently, in a different domain, before it had a name — and showed
the **serving format**, not the model, is the controlling variable. How a record is *presented* to the
generator is the axis these works leave open, and it is the axis LBrain operates on.

## Where it does *not* help

- **Not a hallucination fix.** This is about answering from *retrieved records*. It does nothing
  about a model inventing facts from its weights with no retrieval involved.
- **Small, clean corpora barely benefit.** If your notes are short and unambiguous, ordinary search
  is fine. The gain appears when records are numerous, overlapping, and stale in places.
- **Not a reasoning upgrade.** It changes what the model is given, not what it does with it.
- **The gate is conservative** — it will sometimes flag `near-miss` on a record you'd have accepted.
  That is the trade: fewer confident wrong answers, slightly more "I don't know."
- **A cold import of old notes will serve old decisions as current.** Records are `dated` only when the
  *filename* carries a date, and a bulk copy resets every mtime to today — so newest-wins has nothing to
  order by. Read [this first](docs/DEVELOPER-NOTES.md#10-importing-an-existing-pile-of-notes-yesterdays-doctrine-served-as-todays)
  before importing an archive: either vet it, restore the dates, or knowingly run a calibration period.

We also killed three of our own claims while building this, including a headline result that turned
out to be an artifact of our own prompt. The retractions are published with the findings.

## How it works

- **Hybrid retrieval** — vector + BM25 keyword, fused by reciprocal rank fusion.
- **Deterministic admissibility gate** — classifies each record against the question as admissible,
  near-miss, or irrelevant, without another model call.
- **Supersession** — a replaced note stops being *served* but is never deleted. Persistence and
  activation are separate concerns.
- **Honest dating** — each record states whether its date came from the content, the filename, or the
  filesystem. No invented timestamps.
- **Untrusted-data fencing** — retrieved text is fenced and labelled as data, never instructions, so
  a note can't hijack the agent reading it.

## Use it with your agent

Five MCP tools: `lair_query`, `lair_search`, `lair_protocol_check`, `lair_check_action`, `lair_stats`.

```bash
# Claude Code
claude mcp add -s user lbrain -- /path/to/lbrain/scripts/lbrain-mcp

# Any client speaking streamable-http
lbrain mcp --transport streamable-http --host 127.0.0.1 --port 7370
```

> ⚠️ The HTTP server has **no built-in auth** and exposes the whole corpus. Bind to `127.0.0.1`, or
> put authenticated TLS ingress in front. Never publish it on a public interface.

Or skip MCP entirely — `lbrain query`, `search`, `import`, `doctor` all work from the shell.

## Embeddings

| Provider | Setup | Where your text goes |
|---|---|---|
| `local` *(default)* | none | nowhere — on-device ONNX, 384-dim (one-time model download) |
| `gemini` | your own key | Google, under your key |
| `openai` | your own key | OpenAI, under your key |

`lbrain init` uses `local` unless you pass `--gemini-key`/`--api-key` **on the command line**. A key
sitting in your environment is never treated as consent to send your corpus to a third party.
See the [Privacy Policy](https://lbrain.ai/privacy.html) for every network call LBrain can make, and when — §3 lists them all. See [`docs/KEYS.md`](docs/KEYS.md).

## Something wrong?

```bash
lbrain doctor
```

Prints the **effective** config with per-setting provenance — `[config]` vs `[DEFAULT]` — and whether
your stored vectors match your current embedding settings. Include its output in any issue.

[`docs/DEVELOPER-NOTES.md`](docs/DEVELOPER-NOTES.md) covers the symptoms that look like bugs and aren't —
switching embedding providers on an existing brain, two brains on one machine, imported-but-not-embedded
records, and why a note can vanish from results without being deleted.

## More

- [`docs/DESIGN-binding-aware-serving.md`](docs/DESIGN-binding-aware-serving.md) — the serving design and its review record
- [`docs/lair-framework/`](docs/lair-framework/) — the organizing convention LBrain reads
- [`contrib/`](contrib/) — session-capture hooks, a shared-key proxy
- [`Dockerfile`](Dockerfile), [`docker-compose.kite.yml`](docker-compose.kite.yml) — containerized deployment

**Truth hierarchy:** your source files are authoritative; the index is a derivative cache. If they
disagree, trust the file and re-run `lbrain import && lbrain embed --stale`.

Requires Python 3.10+. SQLite + sqlite-vec + FTS5 — no daemon, no server, no WASM.

## License

BSD-3-Clause — see [LICENSE](LICENSE). Copyright (c) 2026 Metavolve Labs, Inc.

Patents pending. The licence covers the code; it does not grant patent rights.
