{"id":51321865,"url":"https://github.com/ariaxhan/metabrain","last_synced_at":"2026-07-01T14:30:48.560Z","repository":{"id":362599491,"uuid":"1259905763","full_name":"ariaxhan/metabrain","owner":"ariaxhan","description":"A zero-dependency SQLite memory layer for AI agents that learns what works: patterns graduate to proven preferences via a built-in experiment loop.","archived":false,"fork":false,"pushed_at":"2026-06-05T02:24:20.000Z","size":77,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T04:09:50.203Z","etag":null,"topics":["agent-memory","agents","ai","llm","memory","python","self-improving","sqlite"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/metabrain/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ariaxhan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T01:23:38.000Z","updated_at":"2026-06-05T02:25:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ariaxhan/metabrain","commit_stats":null,"previous_names":["ariaxhan/agentbrain"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ariaxhan/metabrain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariaxhan%2Fmetabrain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariaxhan%2Fmetabrain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariaxhan%2Fmetabrain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariaxhan%2Fmetabrain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ariaxhan","download_url":"https://codeload.github.com/ariaxhan/metabrain/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariaxhan%2Fmetabrain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35011254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-memory","agents","ai","llm","memory","python","self-improving","sqlite"],"created_at":"2026-07-01T14:30:44.679Z","updated_at":"2026-07-01T14:30:48.555Z","avatar_url":"https://github.com/ariaxhan.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# metabrain\n\n**A SQLite memory layer for AI agents that learns what works.** Zero dependencies. One file.\n\nMost agent-memory tools store what you *tell* them and hand it back later. metabrain does that too — but it also closes the loop: a pattern you record enough times graduates into a **hypothesis**, every outcome you log becomes an **experiment** for or against it, and once the evidence clears the bar it graduates again into a proven **preference**. Your agent stops guessing and starts running on rules it earned.\n\n```\nlearn(pattern)  →  recurs  →  hypothesis (under test)\n        →  each verdict is an experiment (supports / refutes)\n        →  evidence clears the bar  →  preference  (a proven rule)\n```\n\nThat loop is the whole point. It runs on the Python standard library — no vector database, no server, no API keys.\n\n## Install\n\n```bash\npip install metabrain\n```\n\nPython 3.10+. No dependencies beyond the standard library. (Import name is `metabrain`.)\n\n## Quick start\n\n```python\nfrom metabrain import MetaBrain\n\ndb = MetaBrain(\"agent.db\")\n\nwith db.session(task=\"content\") as s:\n    # A hunch. Record it as you notice it — three times and it's worth testing.\n    s.learn(\"pattern\", \"question hooks lift saves\", domain=\"instagram\")\n    s.learn(\"pattern\", \"question hooks lift saves\", domain=\"instagram\")\n    s.learn(\"pattern\", \"question hooks lift saves\", domain=\"instagram\")\n\n    # It just graduated into a hypothesis. Now test it against reality.\n    h = db.hypotheses(status=\"testing\")[0]\n    post = s.unit(\"carousel with a question hook\", kind=\"contract\", hypothesis=h.id)\n    s.verdict(\"pass\", unit=post, evidence=\"1,240 saves\")\n\n# Next session: the proven rules come first.\nbrief = db.read_start()\nfor rule in brief.preferences:        # things metabrain has *proven*\n    print(\"PROVEN:\", rule.insight)\nfor h in brief.open_hypotheses:       # things it's still testing\n    print(\"testing:\", h.statement, f\"({h.confidence:.0%})\")\n```\n\nYou don't have to open a session — the flat API (`db.learn(...)`, `db.verdict(...)`) works too and attaches to an ambient session automatically, so the telemetry still fills.\n\n## Why it's different\n\n|  | metabrain | typical vector-memory store |\n| --- | --- | --- |\n| Remembers what you tell it | ✅ | ✅ |\n| **Proves which memories actually work** | ✅ the learn→experiment→graduate loop | ❌ |\n| Working state + telemetry, not just recall | ✅ units, checkpoints, sessions, events | ❌ |\n| Infrastructure | a single SQLite file | vector DB / server / API key |\n| Dependencies | none (stdlib `sqlite3`) | several |\n\nRecall stays deliberately simple — substring + a hit counter — because the moat is the loop, not embedding search. (Semantic recall may arrive later as an opt-in `metabrain[embeddings]` extra; the core will always be zero-dependency.)\n\n## Built for real, stateful products\n\nThe loop is general. Three shapes it was designed against:\n\n**Self-learning content engine.** Each post is a unit; engagement is the verdict. Hooks that keep winning graduate into the brand's proven playbook.\n```python\ns.learn(\"pattern\", \"carousels outperform single images\", domain=\"ig\")  # ...×3 → hypothesis\nfor saves, ok in [(1200,\"pass\"), (90,\"fail\"), (1500,\"pass\"), (1100,\"pass\")]:\n    post = s.unit(f\"carousel ({saves} saves)\", kind=\"contract\", hypothesis=h.id)\n    s.verdict(ok, unit=post, evidence=f\"{saves} saves\")\n# 3/4 supported → graduates into the playbook\n```\n\n**Lead capture.** Each lead is a unit with its own checkpoint trail; a tactic about what converts graduates once enough leads confirm it.\n```python\nlead = s.unit({\"name\": \"Acme\", \"source\": \"webinar\"}, kind=\"contract\")\ns.checkpoint({\"stage\": \"demo booked\"}, unit=lead)\ns.verdict(\"pass\", unit=lead, evidence=\"closed\")\n```\n\n**Self-improving job applications.** Each application is a unit; \"lead with a shipped metric\" stays a guess until enough replies prove it, then becomes a rule.\n```python\napp = s.unit({\"company\": \"Acme\"}, kind=\"contract\", hypothesis=h.id)\ns.verdict(\"pass\", unit=app, evidence=\"recruiter replied\")\n```\n\n## How the tables fill themselves\n\nmetabrain has seven tables, and you never write to them directly — **correct use of the API fills every one as a side effect.** Open a session and each write inherits its id, emits an event, and turns the loop:\n\n| Table | Filled by | When |\n| --- | --- | --- |\n| `sessions` | `db.session()` open/close | every run |\n| `events` | every write method | always (telemetry is automatic) |\n| `learnings` | `learn()` — `preference` rows are *graduated* | always |\n| `context` | `unit()`, `checkpoint()`, `handoff()`, `verdict()` | always |\n| `hypotheses` | a `pattern` crossing `promote_at` (default 3 hits) | automatic |\n| `experiments` | a `verdict()` on a unit/hypothesis under test | automatic |\n| `errors` | `capture_error()`, and any exception inside a session | automatic |\n\nThe thresholds are tunable and were calibrated on 5,066 real learnings, not guessed: `promote_at=3` (where the recurring-pattern tail actually begins), `graduate_at=0.8` over a minimum of 3 experiments so a single lucky result can't graduate.\n\n```python\ndb = MetaBrain(\"agent.db\", promote_at=3, graduate_at=0.8, min_experiments=3)\n```\n\n## API\n\n| Method | What it does |\n| --- | --- |\n| `session(*, task, tier, agent, meta)` | Open a session (context manager); records the outcome on close |\n| `learn(type, insight, *, evidence, domain, ...)` | Record/reinforce a lesson; recurring `pattern`s graduate to hypotheses |\n| `recall(query, *, limit)` | Substring-search lessons; bumps hit count (can trigger graduation) |\n| `learnings(*, type, domain, limit)` | Fetch lessons, newest first |\n| `forget(id)` | Delete a lesson |\n| `unit(statement, *, kind, acceptance, hypothesis)` | Open a unit of work; `kind=\"spec\"` requires `acceptance=[...]` |\n| `checkpoint(content, *, unit, agent)` | Record progress mid-work |\n| `handoff(content, *, unit, agent)` | Record a brief for the next session |\n| `verdict(result, *, unit, hypothesis, evidence)` | `\"pass\"`/`\"fail\"`; becomes an experiment when a hypothesis is in play |\n| `hypotheses(*, status, limit)` / `experiments(*, hypothesis)` | Inspect the loop |\n| `context(*, type, unit, limit)` | Fetch work-state entries |\n| `read_start(*, learnings_limit)` | The \"what to know\" digest — proven preferences first |\n| `capture_error(tool, error, ...)` / `errors(*, limit)` | Record / fetch failures |\n| `prune(*, keep)` / `stats()` | Trim old checkpoints / row counts per table |\n\nUse `MetaBrain(\":memory:\")` for an ephemeral in-process store (handy in tests).\n\n## Concurrency \u0026 safety\n\nBuilt for multiple agents sharing one file. SQLite runs in WAL mode with a busy timeout so several processes read and write concurrently; within a process a single connection is lock-guarded, and the verdict→graduation path is one critical section so racing verdicts can never double-graduate a hypothesis. Every value is bound as a query parameter — caller strings never reach the SQL text.\n\nIt can open and migrate an older metabrain / base-schema database (learnings, context, errors) forward in place. A database created by a different tool whose `events`/`hypotheses`/`experiments` tables have an incompatible shape is detected on open and rejected with a clear `IncompatibleDatabaseError`, rather than corrupting it.\n\n## Development\n\n```bash\npip install -e \".[dev]\"\npytest\n```\n\n## License\n\nMIT © Aria Han\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariaxhan%2Fmetabrain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fariaxhan%2Fmetabrain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariaxhan%2Fmetabrain/lists"}