Files
zeekay a03cf8b5b9 brain: zapdb is the canonical native store — point at zap-proto/db, not luxfi/database
Correct positioning per the actual product hierarchy:

  • zapdb is the canonical Hanzo storage layer — ZAP-native, multi-
    language, generic. Canonical home is `zap-proto/db`. Currently
    mirrored at `luxfi/zapdb` (Go) and `~/work/luxcpp/zapdb` (C++);
    both are in-flight to migrate to `zap-proto/db`.

  • luxfi/database is the Lux-flavored extension of zapdb — adds
    blockchain concerns (chain heads, archival, validator sets) on top
    of the base zapdb. NOT a generic brain backend.

Changes:
  • ADVERTISED: rename "luxdb" → "zapdb" with the canonical zap-proto/db
    pointer.
  • Module header doc: list zapdb in the canonical-backend bullets and
    clarify luxfi/database is the Lux extension, not the brain backend.
  • README table: zapdb gets the canonical row pointing at zap-proto/db;
    luxdb gets a separate row labeled as the Lux extension.
  • README "native distributed-SQL story" section: ZAP repos under
    zap-proto org enumerated (one per language: c, cpp, go, py, rust,
    …). zapdb canonical home noted as zap-proto/db.
  • Routing table: multi-machine + team rows reference `zapdb`
    (zap-proto/db) instead of `luxfi/database`.

Rust crate mod.rs header similarly corrected to point at zapdb /
zap-proto/db as the canonical native store.
2026-05-10 19:50:03 -07:00

9.0 KiB

@hanzo/bot-memory

The Hanzo Brain memory layer. Pluggable BrainStore contract. SQLite default — single file, zero infra. Path shared across every Hanzo SDK at ~/.hanzo/brain/brain.db.

Canonical artifact locations

Every Hanzo SDK on a machine reads/writes the same paths so brains compose across the bot, hanzo-mcp, hanzo-dev, and the Python SDK:

Path What
~/.hanzo/brain/brain.db The brain — pages / edges / facts / FTS5
~/.hanzo/workspace/ Markdown source — auto-ingested
~/.hanzo/config.toml Per-machine bot/mcp config
~/.hanzo/cache/ Embedding cache, tool-output cache
~/.hanzo/logs/ Structured logs

What ships in core

  • SQLite backend (canonical default) — ~/.hanzo/brain/brain.db. FTS5 keyword. Optional sqlite-vec for ANN.
  • Pluggable interface — registerBackend("name", factory). Anyone can ship Qdrant / Meilisearch / Postgres / LanceDB / D1 / libSQL as a sibling extension.

Scale-out backends (sibling extensions, not in core)

Hanzo ships the heavy machinery, all open source — register them by name. Native stack uses ZAP (zero-copy transport) + hanzo-consensus (metastable agent agreement) + zapdb (storage primitives) end-to-end. No libSQL, no Turso — we ship our own.

Backend Repo License Use
qdrant ~/work/hanzo/vector Apache 2 Vector ANN at scale (millions of embeddings, multi-replica)
meilisearch ~/work/hanzo/search MIT Fast keyword FTS when SQLite FTS5 stops being enough
replicate ~/work/hanzo/replicate Apache 2 Background SQLite WAL → S3 backup, point-in-time restore
vfs ~/work/hanzo/vfs Apache 2 S3-backed virtual block FS with PQ encryption — unlimited write storage
zapdb zap-proto/db (canonical, in-flight migration from luxfi/zapdb) Apache 2 The canonical Hanzo storage layer. ZAP-native primitives, multi-language. Currently mirrored at luxfi/zapdb (Go, badger-derived) and ~/work/luxcpp/zapdb (C++) — both moving to zap-proto/db.
luxdb ~/work/lux/database BSD-3 Lux-flavored extension of zapdb. Adds blockchain-specific concerns (chain heads, archival, validator sets) on top of the base zapdb. Don't use for generic brain stores — pick zapdb directly.
postgres (sibling pkg) Multi-tenant team brain with pgvector

The native distributed-SQL story (we ship our own — not libSQL/Turso)

For multi-machine SQLite-shaped semantics with native replication, the canonical Hanzo stack is ZAP + hanzo-consensus + zapdb, not libSQL/Turso:

  • Wire: ZAP (zero-copy transport) — same protocol the rest of Hanzo speaks. Carries MCP, A2A, and ACP natively too. Repos live under zap-proto (one per language: zap-proto/c, zap-proto/cpp, zap-proto/go, zap-proto/py, zap-proto/rust, …).
  • Consensus: hanzo-consensus for metastable agent agreement. For storage-level write ordering we run the same metastable primitive on a node quorum (one quorum per brain shard).
  • Storage — zap-proto/db is the canonical home for zapdb. It's the base store, multi-language, ZAP-native. Currently mirrored at luxfi/zapdb (Go) and ~/work/luxcpp/zapdb (C++) pending the migration to zap-proto/db. luxfi/database is a separate Lux-flavored extension of zapdb that adds blockchain concerns (chain heads, archival, validator sets) — generic brain users want zapdb directly, not luxfi/database.
  • Backup: replicate ships SQLite WAL → S3 for the solo + small-team cases.
  • Streaming: vfs for unlimited-size brains backed by S3 blocks with PQ encryption.

We deliberately don't pull in libSQL or Turso; they'd force us off our own ZAP+consensus path. The multi-replica zapdb primitive is in-flight at luxfi/zapdb (Go) and ~/work/luxcpp/zapdb (C++), both migrating to zap-proto/db.

Default routing:

  • Solo dev, < 100K pages → SQLite + FTS5 (zero infra)
  • Solo dev, > 10K pages with vector → SQLite + sqlite-vec (requires better-sqlite3 driver — bun:sqlite has no extension loading)
  • Durable solo (offsite backup) → SQLite + replicate to S3
  • Multi-machine personal → zapdb over ZAP + hanzo-consensus (our native distributed-SQL story; canonical home is zap-proto/db, in-flight migration from luxfi/zapdb)
  • Team / Hanzo Node → Qdrant for vectors + Meilisearch for FTS + zapdb for facts/edges (or Postgres if multi-tenant + external)
  • Org-scale streaming → VFS-backed brain.db, lazy block-level fetch from S3, unlimited size

Schema

CREATE TABLE pages (
  slug         TEXT PRIMARY KEY,
  content      TEXT NOT NULL,
  frontmatter  TEXT,                   -- JSON
  updated_at   TEXT NOT NULL           -- ISO 8601
);

-- FTS5 virtual table over pages.content
CREATE VIRTUAL TABLE pages_fts USING fts5(content, content='pages', content_rowid='rowid');

CREATE TABLE edges (
  source    TEXT NOT NULL,             -- page slug
  target    TEXT NOT NULL,             -- entity slug
  type      TEXT NOT NULL,             -- mentions/attended/works_at/invested_in/founded/advises
  evidence  TEXT,                      -- verbatim phrase that triggered inference
  PRIMARY KEY (source, target, type)
);

CREATE TABLE facts (
  id          TEXT PRIMARY KEY,        -- subject::predicate::ts
  subject     TEXT NOT NULL,           -- entity slug
  predicate   TEXT NOT NULL,           -- preference/status/decision/replied/…
  object      TEXT NOT NULL,
  source      TEXT,                    -- originating page slug or session id
  ts          TEXT NOT NULL,           -- ISO 8601
  confidence  REAL DEFAULT 1.0
);

Anyone implementing BrainStore for another backend should mirror this shape — @hanzo/bot-graph-links and @hanzo/bot-recipes-brain Just Work against any conforming store.

Pluggability

import { registerBackend, open } from "@hanzo/bot-memory";

registerBackend("my-store", async (cfg) => {
  const store: BrainStore = makeMyStore(cfg);
  return store;
});

const store = await open({ backend: "my-store" });

Environment override: HANZO_BRAIN_BACKEND=my-store.

API surface

const store = await open(); // SQLite, ~/.hanzo/brain/brain.db

await store.upsertPage("people/alice", markdown, { type: "person" });
await store.upsertEdges("people/alice", edges);
await store.upsertFact({
  subject: "people/alice",
  predicate: "preference",
  object: "replies in under 2 hours",
});

const facts = await store.recall("people/alice", { limit: 50 });
const hits = await store.hybridSearch("Acme", 5);
const out = await store.edgesFor("people/alice", "out");

Config

interface MemoryConfig {
  backend?: string; // default "sqlite"
  dataDir?: string; // default ~/.hanzo/brain
  dbPath?: string; // explicit file; overrides dataDir
  embeddingModel?: string; // for the optional vector ANN path
  embeddingApiKey?: string;
}

Driver

  • bun:sqlite (canonical — already built into Bun, no install needed)
  • better-sqlite3 (fallback for Node-only deployments)

Either works. The init step tries bun:sqlite first.

Tests

cd ~/work/hanzo/bot && bun test extensions/memory

Covers: upsert + read pages, upsert + read edges, upsert + recall facts, FTS hybrid search, pluggability (register a stub backend), unknown-backend error message.