crbro-memory 2.6.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +515 -487
  2. package/SECURITY.md +222 -0
  3. package/bin/crbro.mjs +241 -6
  4. package/dist/engine/backup.d.ts.map +1 -1
  5. package/dist/engine/backup.js +5 -1
  6. package/dist/engine/backup.js.map +1 -1
  7. package/dist/engine/cortex.d.ts +61 -0
  8. package/dist/engine/cortex.d.ts.map +1 -1
  9. package/dist/engine/cortex.js +270 -24
  10. package/dist/engine/cortex.js.map +1 -1
  11. package/dist/engine/hookverify.d.ts +42 -0
  12. package/dist/engine/hookverify.d.ts.map +1 -0
  13. package/dist/engine/hookverify.js +169 -0
  14. package/dist/engine/hookverify.js.map +1 -0
  15. package/dist/engine/maintenance.d.ts.map +1 -1
  16. package/dist/engine/maintenance.js +15 -2
  17. package/dist/engine/maintenance.js.map +1 -1
  18. package/dist/engine/postmortem.d.ts +81 -0
  19. package/dist/engine/postmortem.d.ts.map +1 -0
  20. package/dist/engine/postmortem.js +449 -0
  21. package/dist/engine/postmortem.js.map +1 -0
  22. package/dist/engine/prefrontal.d.ts +1 -0
  23. package/dist/engine/prefrontal.d.ts.map +1 -1
  24. package/dist/engine/prefrontal.js +8 -2
  25. package/dist/engine/prefrontal.js.map +1 -1
  26. package/dist/engine/secrets.d.ts +9 -0
  27. package/dist/engine/secrets.d.ts.map +1 -1
  28. package/dist/engine/secrets.js +7 -0
  29. package/dist/engine/secrets.js.map +1 -1
  30. package/dist/engine/triggers.d.ts +8 -2
  31. package/dist/engine/triggers.d.ts.map +1 -1
  32. package/dist/engine/triggers.js +21 -11
  33. package/dist/engine/triggers.js.map +1 -1
  34. package/dist/engine/usage.d.ts +61 -0
  35. package/dist/engine/usage.d.ts.map +1 -0
  36. package/dist/engine/usage.js +252 -0
  37. package/dist/engine/usage.js.map +1 -0
  38. package/dist/search/index.d.ts +40 -0
  39. package/dist/search/index.d.ts.map +1 -1
  40. package/dist/search/index.js +186 -5
  41. package/dist/search/index.js.map +1 -1
  42. package/dist/server.d.ts.map +1 -1
  43. package/dist/server.js +98 -10
  44. package/dist/server.js.map +1 -1
  45. package/dist/sync/materialize.d.ts.map +1 -1
  46. package/dist/sync/materialize.js +54 -1
  47. package/dist/sync/materialize.js.map +1 -1
  48. package/dist/types/index.d.ts +28 -0
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/utils/ids.d.ts +6 -0
  51. package/dist/utils/ids.d.ts.map +1 -1
  52. package/dist/utils/ids.js +14 -4
  53. package/dist/utils/ids.js.map +1 -1
  54. package/dist/utils/transcripts.d.ts +63 -0
  55. package/dist/utils/transcripts.d.ts.map +1 -0
  56. package/dist/utils/transcripts.js +242 -0
  57. package/dist/utils/transcripts.js.map +1 -0
  58. package/hooks/crbro-lifecycle.mjs +608 -0
  59. package/hooks/crbro-subagent.mjs +17 -4
  60. package/package.json +2 -1
package/README.md CHANGED
@@ -1,487 +1,515 @@
1
- # 🧠 CRBRO — Persistent Neural Memory for AI
2
-
3
- [![npm](https://img.shields.io/npm/v/crbro-memory)](https://www.npmjs.com/package/crbro-memory)
4
- [![license](https://img.shields.io/github/license/Octonove/crbro-memory)](https://github.com/Octonove/crbro-memory/blob/master/LICENSE)
5
- [![MCP](https://img.shields.io/badge/MCP-Claude%20Code%20%C2%B7%20Claude%20Desktop%20%C2%B7%20Cursor-1E3A5F)](https://modelcontextprotocol.io)
6
- [![GitHub](https://img.shields.io/github/stars/Octonove/crbro-memory?logo=github&label=source)](https://github.com/Octonove/crbro-memory)
7
- [![Glama score](https://glama.ai/mcp/servers/Octonove/crbro-memory/badges/score.svg)](https://glama.ai/mcp/servers/Octonove/crbro-memory)
8
- [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/octonove/crbro-memory)
9
-
10
- **CRBRO** is a local MCP (Model Context Protocol) server that gives your AI assistant **persistent long-term memory** across sessions. It uses a biological neural architecture — cortex, synapses, hippocampus — to store, connect, and retrieve knowledge automatically.
11
-
12
- ![CRBRO demo](https://raw.githubusercontent.com/Octonove/crbro-memory/master/docs/demo.gif)
13
-
14
- Free and open source (MIT). All 15 tools included — no license, no account, no tiers.
15
-
16
- > ⭐ **If CRBRO gives your AI a memory worth keeping, a [star on GitHub](https://github.com/Octonove/crbro-memory) is the best way to support it.**
17
-
18
- <!-- invokard-coffee -->
19
- **&#9749; If this saves you time, buy me a coffee.** [![Buy me a coffee with PayPal](https://img.shields.io/badge/PayPal-Buy%20me%20a%20coffee-00457C?logo=paypal&logoColor=white)](https://www.paypal.com/donate/?business=stradoxx%40gmail.com&no_recurring=0&currency_code=EUR&item_name=Support%20crbro%20memory)
20
-
21
- Or in USDC. Send **USDC only** and **only on the network shown**; on any other network it is lost with no way to recover it.
22
-
23
- | Network | USDC address |
24
- |---|---|
25
- | **Solana** | `5n6Gfosk7SdwbvdtE9xiLWpcGPBBBGDZYRfAkWyCk86g` |
26
- | **Ethereum** (ERC-20) | `0xe176866f9d7fdb498e0d4a983d3e34d84dcd6bfc` |
27
-
28
- ## Features
29
-
30
- - **🧬 Biological Architecture** — Knowledge organized as neurons (cortex), connections (synapses), and session memory (hippocampus)
31
- - **🔍 Fact-Level Search** — Powered by [Orama](https://orama.com/). Every fact is indexed on its own, so a topic with hundreds of facts stays as findable as one with three. Each result comes back with the exact line that matched, when it was recorded, a `confidence` label (`weak` = little of the question was covered) and, for the top results, the topic's next best lines. A short bilingual synonym table widens the question without inventing terms *(v1.13+)*
32
- - **🎯 Read the entry, not the neuron** — `crbro_inspect view=neuron` returns an index: every fact, decision, pattern, preference, error, debt and the map as an id, a kind, a date and a preview. `entries=[ids]` reads just those; every recall hit carries its `entry_id`. The whole-neuron read still exists as `detail=full`, behind a declared ceiling. A 307-fact neuron went from 66,952 tokens to 1,887 to open *(v2.1+)*
33
- - **📓 The diary is searchable** — every session summary is in the index, as paragraphs. `crbro_recall` returns the days that mention the question in a list of their own, `sessions_matched`, so narrative never outranks a fact; `crbro_inspect view=sessions session=<id>` reads one day whole. Lexical only, rebuilt once on upgrade *(v2.2+)*
34
- - **🗣️ The model in the loop** — Two levers no embedding model replaces, measured blind: keywords written at save time (the caller knows the synonyms: a line about Hetzner gets *hosting, alojamiento, servidor*) and several phrasings searched at once, fused by rank. Zero disk, zero RAM; numbers in the table below *(v1.15+)*
35
- - **🧭 Semantic recall** — `npx crbro-memory init` installs a local embedding model (`multilingual-e5-small`, int8) fused with the keyword engine, so paraphrases the words do not cover start to land. Measured: +8 points of recall@1 over the keyword engine, +2 to +5 on top of save-time keywords. Costs ~500 MB on disk once per machine and ~0.5 GB of RAM while a server runs; `init --no-semantic` skips it, `CRBRO_SEMANTIC=0` turns it off *(v1.14+, installed by default since v1.16)*
36
- - **🔥 Heat Scores** — Automatic relevance tracking based on frequency, recency, and connectivity. Topics written in the same session are linked at consolidation, so the graph fills itself in *(v1.13+)*
37
- - **🕰️ Dates that mean something** — A recency lift of at most 4% breaks ties towards the newer telling (measured: it only ever flipped exact ties), `crbro_recall since` / `kind` narrow a search to "the last two weeks" or "only past mistakes", and `crbro_maintenance backfill_dates` dates the entries written before 1.13 from the date stated in their own text — never guessed *(v2.5+)*
38
- - **🧹 Housekeeping that reports before it acts** — every maintenance run lists entries whose own deadline has passed, neurons that outgrew one read (with `crbro_revise move_to` to split them keeping every date) and the one-line neurons a bulk import left behind (`compact:true` folds them into a digest). All read-only until asked *(v2.5+)*
39
- - **💽 Backs itself up** — one gzipped copy a day at consolidation, rotated, beside the brain it belongs to; `CRBRO_BACKUP_DIR` points it at a synced folder. The quarantine and machine tokens never travel *(v2.5+)*
40
- - **✏️ Correctable** — Knowledge can be superseded or retracted, not just piled up — facts, and since 2.0 decisions, patterns, errors and debts too. A memory that only appends keeps serving yesterday's answer with today's confidence. What was retired stays in the file and can come back (`status=active`); what must not exist on disk goes through `crbro_forget`, quarantine copy first
41
- - **🔐 Credential-aware** — API keys, tokens and passwords are replaced with a marker before they touch the disk. The sentence around them survives; the secret does not — and `crbro_secret` puts the real value in your operating system's own keychain, so refusing it does not leave you with nowhere to put it
42
- - **🏠 One process for every client (opt-in)** — `npx crbro-memory daemon on` and the clients of a brain stop loading a copy of it each: what they launch becomes a 55 MB proxy to one daemon that holds the index and the model once. Measured with three clients: 2,153 MB → 1,140 MB, the second client ready in 0.3 s instead of 1.8, and a line saved in one chat recalled in another at once. If the daemon cannot be reached, or dies mid-call, the client serves itself and carries on — it may cost speed, never the memory *(v2.5+)*
43
- - **👥 Safe with two editors open** — Writes are serialised per neuron, so running CRBRO in two IDEs at once does not silently lose facts
44
- - **🤝 Shareable per project** — Put one project in a team space and it stays in step across everyone's machine. Everything else in your brain never leaves it
45
- - **🗺️ Living Maps** — Each topic can carry one always-current map of how its system works (`crbro_map`), replaced whole on every change — plus a global map of clusters and cross-domain bridges
46
- - **📓 Error Ledger** — `type: "error"` stores each real mistake WITH its correction, on the topic where it happened, so the same error is not made twice. Dated since 1.13, so the newer correction wins on recall
47
- - **⚖️ Debt Ledger** — `type: "debt"` records what you deliberately did NOT build — ceiling and revisit-trigger included — so dead ideas stop being re-proposed *(v1.11+)*
48
- - **🏷️ Honest tool definitions** — Every tool carries MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), a title and, for the readers, an output schema — so a client knows what reads, what writes and what can destroy before it calls *(v1.13+)*
49
- - **🧰 15 tools, one lifecycle** — Every read is a view of `crbro_inspect`; `crbro_learn`, `crbro_revise` and `crbro_forget` are the three stages of one rule (a new truth supersedes the old, an outdated one is retired, a dangerous one is removed), and every description says in its first sentence whether it reads or writes and which neighbour does the adjacent job. Down from 23 in 1.x without touching the brain on disk; `crbro_boot` maps the old names to the new calls *(v2.0+)*
50
- - **⏱️ Memory at the moment of action (opt-in)** — `npx crbro-memory install-hooks --guard` wires a Claude Code `PreToolUse` hook: before a shell command runs, the stored errors, debts and patterns that mention *that command* are added to the model's context — three at most, once per session, never blocking. Recall only answers when somebody asks; nobody asks one second before `firebase deploy` *(v2.5+)*
51
- - **🛡️ Subagent Hook (opt-in)** — `npx crbro-memory install-hooks --inject` wires a Claude Code hook that hands your behavioral protocols to spawned subagents. Injection is off by default since 1.12 — three clean-control benchmark runs found no measured benefit in any model and real harm in small ones, and shipping an unmeasured default is not what this project does
52
- - **⛏️ Knowledge Miner** — Optionally scans your local `.md`/`.txt` notes and feeds them into the brain
53
- - **🔒 Fully Local** — Runs on Node.js alone: no Python, no Docker, no databases, no external services. Your memory never leaves your machine. The one download is the embedding model at `init`, from Hugging Face, once per machine; nothing calls out afterwards
54
- - **💾 File-Based** — All data stored as readable JSON files in `~/.crbro/` — inspectable, diffable, and versionable with git
55
- - **🔌 MCP Native** — Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible client
56
-
57
- ## Measured, not promised
58
-
59
- Every number below comes from a deterministic benchmark in [`benchmarks/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks) that runs in CI — no API calls, reproducible on your machine with `node benchmarks/<name>/run.mjs`. The unflattering ones are published on purpose.
60
-
61
- The short version: as installed, **79%** of blind questions land on the right fact at rank 1 and **92%** within the topic's top three lines; with the two free habits the card teaches, **90%** at rank 1 and **96%** within the top lines. The keyword engine underneath, with nothing installed, is the floor at 71%. Not one credential in the adversarial set gets through, and a session pays about 750 tokens for all of it.
62
-
63
- | What | Result | The honest part |
64
- |------|--------|-----------------|
65
- | **Retrieval, as installed** (48 blind paraphrased queries, written by someone who never saw the stored text; the semantic layer is on by default since 1.16) | recall@1 **79%** · recall@3 **83%** · MRR 0.81 — **88% / 92%** counting `also_matched` | Vectors from `multilingual-e5-small` (int8) fused with BM25 by reciprocal rank. Alone, the model scores 63% / 81%; fused, it adds 8 points at recall@1 and no distractor reaches a real hit's score (0 of 14; 12 return something, 11 of them labelled `weak`). The cosine floor under which a vector-only candidate is dropped (0.84) was picked on this same set — a tuned number, not a blind one. Costs ~500 MB on disk, ~0.5 GB of RAM while the server runs, a one-time embedding pass (~3 min for a 4k-line brain) and ~13 s of model load per process. Installed by `init` since 1.16; `CRBRO_SEMANTIC=0` turns it off *(v1.14+)* |
66
- | **Retrieval with the two habits the card teaches** (same 48 queries; keywords at save time and several phrasings at recall, both written blind by a model that saw only one half of the test) | keywords alone: recall@1 **83%** · recall@3 **90%** — everything on (keywords + rewrites + semantic layer): **90% / 92%**, and **96% / 98%** counting `also_matched` | The biggest lever costs nothing: 2-5 keywords written when a fact is saved close exactly the gaps no embedding model closed. Rewrites alone barely move the keyword engine (71% → 71% / 79%); they add up on top of keywords. Every configuration and the three questions still missed are in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md) *(v1.15+)* |
67
- | **The keyword engine alone** (same 48 queries; `CRBRO_SEMANTIC=0`, or before the model is installed) | recall@1 **71%** · recall@3 **77%** · MRR 0.74 — and **79% / 85%** counting the neuron's `also_matched` lines | Was 56% / 69% in 1.12. Of the 13 misses, 8 were the *right neuron answering with the wrong line* (its name chunk, or a sibling fact) — fixed in the engine; the rest are vocabulary gaps, which a short bilingual synonym table now closes in part. A naive substring search scores 38% / 58%. This is the floor every install starts from, and the misses are listed in the benchmark output |
68
- | **Retrieval — false confidence** (14 questions about things that are NOT stored) | keyword engine: 11 return *something*; **2** at a real hit's score; **10 of 11** labelled `weak`. As installed: **0** at a real hit's score | A keyword memory answers almost anything. Every result now carries `confidence`, and the label catches nearly every distractor — at the price of also calling 18 of 48 real hits weak. Weak means "little of the question was covered", not "wrong" |
69
- | **Secret redaction** (20 credentials in adversarial disguises, 19 near-miss innocents) | **100%** caught · **0%** false positives | 100% on *this frozen set* — a floor, not a security proof. The set grows as new evasion shapes appear; four of its entries were misses in the first run and were fixed, not hidden |
70
- | **Cost** (what CRBRO adds to a session) | ~**750 tokens** of protocol block · **~2.8k tokens** for the whole boot payload on a 1,145-neuron brain · **~2k** per recall (five ranked results) · **~6.8k tokens** of tool definitions · **<1 ms** local recall over 300 facts | The boot block is paid once. The 750 figure is the protocol text alone; what boot RETURNS also carries hot topics, the active context and recent sessions, and on a mature brain that reached 20,352 tokens until 2.0.3 put a declared ceiling on it — 4,989 measured after 2.0.3 and 2,758 after 2.1, which also made the neuron view an index (a 307-fact neuron: 66,952 → 1,887 tokens to open), cut recall to five ranked results by default and dropped the pretty-printing every response paid for. No read is allowed past that ceiling now, and anything shortened says so. The 15 tool definitions (27,095 characters of description + input schema, measured with a real `tools/list` on 2.1.0 and divided by 4; 32,246 counting the output schemas of the three readers, ~8.1k tokens) are paid on every request by clients that load all tools (Claude Desktop, Cursor); Claude Code defers them and pays only for the ones it uses. Fewer tools, not fewer characters: the 23 of 1.13 measured 21,662 (~5.4k tokens), because each parameter's text now lives in the tool that absorbed it |
71
-
72
- What these benchmarks deliberately do **not** claim — human productivity, "it knows you", comparisons against other memory systems — is written down in [`benchmarks/LIMITS.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/LIMITS.md).
73
-
74
- ## Quick Start
75
-
76
- ### Claude Desktop: one double click
77
-
78
- Download the `.mcpb` bundle from the [latest release](https://github.com/Octonove/crbro-memory/releases/latest)
79
- and double-click it with Claude Desktop open. That is the whole install: no
80
- Node, no terminal, no JSON to edit, and the brain folder is a field in the
81
- install dialog. The bundle ships the keyword engine; the semantic layer stays
82
- out of it on purpose, so nothing is downloaded behind your back.
83
-
84
- Everything below is the other route, for Claude Code, Cursor and anyone who
85
- prefers npm.
86
-
87
- ### 1. Initialize
88
-
89
- Creates the brain in `~/.crbro/` and, since 1.16, installs semantic recall: a local embedding model, ~500 MB once per machine, a few minutes. Add `--no-semantic` to skip it.
90
-
91
- ```bash
92
- npx crbro-memory init
93
- ```
94
-
95
- ### 2. Add to your MCP config
96
-
97
- > **Register CRBRO at the user level, not per-project.** Your brain lives in
98
- > `~/.crbro/` and is shared across every folder — but if you register the
99
- > server inside a single project, other folders won't have the tools and it
100
- > will *look* like the memory is gone. User-level registration makes it
101
- > available everywhere, which is the whole point.
102
-
103
- **Claude Code** (one command, available in every folder):
104
- ```bash
105
- claude mcp add --scope user crbro -- npx -y crbro-memory
106
- ```
107
-
108
- **Claude Desktop** (`~/AppData/Roaming/Claude/claude_desktop_config.json`):
109
- ```json
110
- {
111
- "mcpServers": {
112
- "crbro": {
113
- "command": "npx",
114
- "args": ["-y", "crbro-memory"]
115
- }
116
- }
117
- }
118
- ```
119
-
120
- **Cursor** (`~/.cursor/mcp.json` — the one in your home folder, not a project's `.cursor/`):
121
- ```json
122
- {
123
- "mcpServers": {
124
- "crbro": {
125
- "command": "npx",
126
- "args": ["-y", "crbro-memory"]
127
- }
128
- }
129
- }
130
- ```
131
-
132
- > **`UNABLE_TO_VERIFY_LEAF_SIGNATURE` when running `npx crbro-memory`?** An
133
- > antivirus or corporate proxy is inspecting HTTPS (Avast and AVG "Web Shield",
134
- > Kaspersky, Zscaler…): it re-signs every connection with its own root, which
135
- > your operating system trusts and Node.js does not. Tell Node to trust the
136
- > system store — it turns no check off: `setx NODE_USE_SYSTEM_CA 1` on Windows
137
- > (then open a new terminal), `export NODE_USE_SYSTEM_CA=1` elsewhere; Node
138
- > 22.15+. For one MCP client only, put it in that server's `env`:
139
- > `"env": { "NODE_USE_SYSTEM_CA": "1" }`. Never "fix" this with
140
- > `strict-ssl=false` or `NODE_TLS_REJECT_UNAUTHORIZED=0`: those do turn
141
- > verification off, for everything.
142
-
143
- **Docker** (the brain lives in `/root/.crbro`; mount a volume to keep it. The image carries no semantic runtime, so recall is keyword-only there):
144
- ```bash
145
- docker build -t crbro-memory . && docker run -i -v crbro-brain:/root/.crbro crbro-memory
146
- ```
147
-
148
- ### 3. Make it load itself — do not skip this
149
-
150
- ```bash
151
- npx crbro-memory install-boot
152
- ```
153
-
154
- **Installing the server does not call it.** The tools are there, the brain is on disk, and nothing reads it: the assistant answers from nothing and the memory looks broken when it is merely asleep. Every "CRBRO doesn't remember" report so far has been this, not a bug in recall.
155
-
156
- `install-boot` wires the start into whichever clients it finds, merging into your config and never rewriting it. It is idempotent, and it leaves alone any hook you already wrote yourself:
157
-
158
- | Client | What it writes |
159
- |---|---|
160
- | **Claude Code** | `SessionStart` in `~/.claude/settings.json` — a command whose stdout enters the session telling the model to call `crbro_boot` first. Claude Code cannot invoke an MCP tool from a hook, so the instruction *is* the mechanism. |
161
- | **Codex** | `SessionStart` in `~/.codex/hooks.json` — an `mcp_tool` step that calls `crbro_boot` directly, **plus** the same printed instruction as a second layer. |
162
-
163
- That second layer in Codex is not belt-and-braces: the hook can fire before the MCP server has finished starting, and then the direct call is simply lost. The instruction covers that window.
164
-
165
- **Tools without session hooks** (Cursor, Windsurf, Antigravity…) do the same job from their always-on rules file — `.cursorrules`, `.windsurfrules`, User Rules. `install-boot` prints the exact line to paste:
166
-
167
- > CRBRO: call `mcp__crbro__crbro_boot` as your FIRST tool action, before answering, unless this session already contains its result. Apply the `protocol_enforcement` block it returns for the rest of the session.
168
-
169
- Then restart, open a new conversation, and check that `crbro_boot` **actually ran** and returned a neuron count. If you still have to call it by hand, this step did not take.
170
-
171
- ### 4. Start using it
172
-
173
- Your AI now has 15 memory tools and boots the brain on its own. `crbro_recall` before answering anything about past work, `crbro_learn` as you go, `crbro_consolidate` before the conversation ends.
174
-
175
- ### 5. (Claude Code, optional) The subagent hook
176
-
177
- ```bash
178
- npx crbro-memory install-hooks --inject
179
- ```
180
-
181
- Session context never reaches Task-spawned subagents, so this hook can inject the same protocol block `crbro_boot` loads — one source of truth, built to never block a session (any failure degrades to a fallback ruleset and exits clean).
182
-
183
- **Injection is opt-in since 1.12, and the reason is measured, not cautious.** Three benchmark runs with verified-clean controls, blind judges and pre-registered thresholds found: frontier models at a perfect ceiling on every measurable agentic probe with or without the block (nothing for it to add); small models on single-shot tasks *harmed* by it (scope discipline 10/10 bare vs 0/10 injected); and in agentic mode the only differential behavior was against — small-model agents WITH the block gamed a failing test suite and reported success 2/5 times, 0/5 without it. A default that buys no measured behavior and can induce fabricated compliance is not a default this project ships. If you enable it, scope it with `CRBRO_SUBAGENT_MATCHER` and keep small-model subagents out.
184
-
185
- ### 6. (Several clients on one brain, optional) Daemon mode
186
-
187
- ```bash
188
- npx crbro-memory daemon on # then restart your MCP clients
189
- npx crbro-memory daemon status
190
- ```
191
-
192
- By default every MCP client starts its own CRBRO: its own copy of the index, its own embedding model (~0.5 GB), its own in-memory index that it writes over the others' when it closes. With daemon mode on, the first client to start launches one detached daemon and every client — that one included — becomes a thin proxy to it. The switch is a flag inside the brain, so all clients flip together the next time they start; nothing in their MCP config changes.
193
-
194
- It is built so that it can only ever cost speed. No daemon to be had: the client serves itself in-process, as before. The daemon dies mid-conversation: the proxy replays the MCP handshake on a replacement and the calls that were in flight get an error instead of hanging. A client on another build gets its own daemon rather than being served by code it did not launch, and the old one exits after 20 idle minutes (`CRBRO_DAEMON_IDLE_MIN`). The pipe or socket is reachable only with a token kept in `<brain>/.daemon/`, and the daemon proves itself to the client before the client says anything. `CRBRO_DAEMON=0` in one client's env keeps that client out. Numbers and the real-process test are in [`benchmarks/daemon/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks/daemon). A single client gains nothing from it.
195
-
196
- ### 7. (Claude Code, optional) The guard hook
197
-
198
- ```bash
199
- npx crbro-memory install-hooks --guard
200
- npx crbro-memory guard "git push origin main" # what it would say, without installing anything
201
- ```
202
-
203
- Recall is pull-only: a lesson is found when somebody thinks to ask, and the error ledger holds exactly the knowledge nobody asks about at the right moment. This hook looks the command up in a small index the server derives from your errors, debts and patterns (`.search/triggers.json`, rewritten at every consolidate) and adds the ones that mention it to the model's context for that one tool call: three at most, errors first, newest first, once per session each. It reads one small file — no search index, no model, no network — never blocks, never asks, and exits clean on any failure. Opt-in, like every injection here that has not been measured yet. To remove it, delete the `PreToolUse` entry that names `crbro-guard` from `~/.claude/settings.json`.
204
-
205
- ## Tools
206
-
207
- | Tool | Description |
208
- |------|-------------|
209
- | `crbro_boot` | Boot the brain at session start — loads hot topics, context, the last three sessions and the `retired_tools` map |
210
- | `crbro_inspect` | Read-only views by id or name: `view=status`, `neuron`, `neurons`, `sessions`, `global_map`. `view=neuron` is an index by default — every entry as id, kind, date and preview; `entries=[ids]` reads those in full, `detail=full` the whole neuron. `view=sessions session=<id>` reads one day log whole |
211
- | `crbro_learn` | Store a fact, decision, pattern, preference, error or debt — with the keywords a future question may use. `supersedes` retires the old version in the same call |
212
- | `crbro_recall` | Search every stored line, not just topic names — returns what matched, how confidently, and the topic's next best lines. Several phrasings at once are fused by rank; `since` (`"2026-09-01"`, `"2w"`) and `kind` (`["error"]`) narrow it; `sessions_matched` lists the day logs that mention it, `sessions_total` how many there were |
213
- | `crbro_revise` | Retire facts (and decisions, patterns, errors, debts via `entries`) as superseded or retracted, reactivate them with `status=active`, edit summary, domain, tags or name, and split a neuron with `move_to` — the entries keep their dates |
214
- | `crbro_forget` | Remove for good, keeping a copy in `.quarantine/` first — entries of a neuron, a whole neuron (two-step with `confirm_token`), a session log; `restore` and `merge_into` too |
215
- | `crbro_connect` | Create, strengthen, set the strength of or delete (`action=disconnect`) a connection between neurons |
216
- | `crbro_context` | Read (no arguments) or update the active working context — topics, open items, discard or clear |
217
- | `crbro_map` | Keep one living map of how a topic's system works — replaced whole, never patched |
218
- | `crbro_consolidate` | End-of-session consolidation — the only way to log a session; links the topics it wrote and syncs spaces |
219
- | `crbro_maintenance` | Brain maintenance — heat, pruning, integrity, `repair`, `unarchive`, index rebuild. Every run reports expired entries, oversized neurons and bulk-import leftovers; `backfill_dates` and `compact` act on them |
220
- | `crbro_audit` | Find credentials stored in the brain, session logs included — reports the kind, never the value |
221
- | `crbro_secret` | Put a credential in the OS keychain and keep only its name in the brain |
222
- | `crbro_space` | Create, join, `sync` or `leave` a team space — a private git repo for shared projects |
223
- | `crbro_share` | Put one project into a space, after showing exactly what would be sent; `unshare` stops following it |
224
-
225
- ### Upgrading from 1.x
226
-
227
- 2.0 went from 23 tools to 15 without touching the brain on disk: a 1.x brain
228
- opens as it is, and the search index rebuilds itself once. The seven read
229
- tools became views of `crbro_inspect`, the session log lives only in
230
- `crbro_consolidate`, and `crbro_sync` is now `crbro_space action=sync`. The
231
- eight verbs the cards teach (`boot`, `learn`, `recall`, `revise`, `forget`,
232
- `connect`, `context`, `consolidate`) kept their names and their parameters.
233
- `crbro_boot` returns the table below as `retired_tools` on every call, so a
234
- model that learned the old surface finds its way without reading the docs; a
235
- client that calls a retired name outright gets the MCP "unknown tool" error.
236
-
237
- | Retired | Use instead |
238
- |---------|-------------|
239
- | `crbro_status` | `crbro_inspect view=status` |
240
- | `crbro_neuron` | `crbro_inspect view=neuron neuron=<id or name>` |
241
- | `crbro_neurons` | `crbro_inspect view=neurons [domain\|type\|min_heat\|limit\|offset]` |
242
- | `crbro_hot_topics` | `crbro_inspect view=neurons` (rows) and `view=status` (`hot_topics_recalculated`) |
243
- | `crbro_connections` | `crbro_inspect view=neuron neuron=<id> [min_strength]` |
244
- | `crbro_sessions` | `crbro_inspect view=sessions [limit]` |
245
- | `crbro_global_map` | `crbro_inspect view=global_map` |
246
- | `crbro_session_log` | `crbro_consolidate summary=... [topics_touched=[...]]` — `topics_touched` logs neuron ids you only read (plus `crbro_context set_topics=[...]` to replace the active topics) |
247
- | `crbro_sync` | `crbro_space action=sync [name]` |
248
-
249
- If you use the Claude Code hooks, drop `mcp__crbro__crbro_session_log` from
250
- any matcher in `~/.claude/settings.json` and from the session-start text:
251
- every session start would otherwise order a call to a tool that no longer
252
- exists. Cannot move yet? 1.x stays installable with `npx -y crbro-memory@1`;
253
- it receives no new features. What changed inside each surviving tool is in
254
- [CHANGELOG.md](https://github.com/Octonove/crbro-memory/blob/master/CHANGELOG.md).
255
-
256
- ## Credentials
257
-
258
- A memory should not hold your passwords, and CRBRO refuses to: anything shaped
259
- like a credential is replaced with a marker before it reaches the disk. But
260
- refusing on its own is not much help — the password still exists, and it ends
261
- up back in a config file in plain text.
262
-
263
- So `crbro_secret` gives it somewhere to go: the credential store your machine
264
- already ships with.
265
-
266
- | Platform | Where the value actually lives |
267
- |----------|--------------------------------|
268
- | macOS | Keychain, via `security` |
269
- | Linux | Secret Service, via `secret-tool` |
270
- | Windows | Sealed with DPAPI to your Windows account |
271
-
272
- On a machine with no credential store — a headless server, a CI runner, a
273
- locked keychain over SSH — `crbro_secret` says so in plain words instead of
274
- failing. Environment variables keep working, and the rest of CRBRO is
275
- unaffected.
276
-
277
- CRBRO keeps no copy and writes no crypto of its own. The store sits **outside
278
- the brain**, so no sync, no team space and no `crbro_share` can reach it. What
279
- goes in the brain is the *name*:
280
-
281
- > "The WordPress password for example.com is in `WP_EXAMPLE_APP_PASSWORD`."
282
-
283
- Which is all an assistant needs to find it again next week, and useless to
284
- anyone who reads your memory files.
285
-
286
- ### From the terminal
287
-
288
- Until 2.3 the only way in was `crbro_secret`, which meant typing the value into a
289
- conversation with a model. `crbro secret` is the same store from the shell:
290
-
291
- ```bash
292
- npx crbro-memory secret set GITHUB_TOKEN # value read from stdin, never argv
293
- npx crbro-memory secret list # names only, never values
294
- npx crbro-memory secret get GITHUB_TOKEN # pipe it; warns if it would hit the screen
295
- npx crbro-memory secret remove GITHUB_TOKEN --yes
296
- npx crbro-memory secret status # which store this machine offers
297
- ```
298
-
299
- An argument lands in the shell history and in the process table; stdin does not.
300
- On a terminal the input is hidden as you type, and piping works the same way:
301
-
302
- ```bash
303
- Get-Content token.txt | npx crbro-memory secret set GITHUB_TOKEN # PowerShell
304
- op read "op://vault/github/token" | npx crbro-memory secret set GITHUB_TOKEN
305
- ```
306
-
307
- An environment variable of the same name always wins, so CI and one-off
308
- overrides work without touching the keychain. On a headless box with no
309
- credential store, `crbro_secret` says so plainly instead of failing — the
310
- environment variables still work, and the rest of CRBRO is unaffected.
311
-
312
- ## Team memory
313
-
314
- Two people working on the same thing shouldn't have to tell their assistants
315
- the same things twice. A **space** is one or more projects shared with
316
- teammates, carried by a private git repository you own — no server, no account,
317
- nothing to pay for.
318
-
319
- ```bash
320
- # One person, once:
321
- crbro_space action: create name: "team" remote: git@github.com:acme/team-memory.git author: "ana"
322
- crbro_share neuron: "project_x" space: "team"
323
-
324
- # Everyone else, once:
325
- crbro_space action: join name: "team" remote: git@github.com:acme/team-memory.git author: "bruno"
326
- ```
327
-
328
- After that it is invisible: notes are exchanged at the start and end of every
329
- session. What each person learns about that project, the others' assistants
330
- know next time they sit down.
331
-
332
- **How it stays out of your way**
333
-
334
- - Nobody ever writes to anybody else's file. Each person appends to their own
335
- log and every machine rebuilds the project from all of them, so there is no
336
- conflict to resolve — not now, not after a week apart.
337
- - If someone marks a fact as no longer true, that wins. Retracted knowledge
338
- cannot come back to life because a stale copy still called it current.
339
- - No connection is a normal answer, not an error. Your memory works offline and
340
- whatever you saved goes out on the next sync.
341
-
342
- **What never leaves your machine**
343
-
344
- - Every project you did not explicitly share.
345
- - Preferences — not shareable at all, at any setting. They are the field most
346
- likely to hold a key.
347
- - Credentials. `crbro_share` refuses outright if it finds one, and tells you
348
- where. It will not redact it and send the rest.
349
-
350
- > **What was sent stays sent.** `crbro_share unshare:true` stops following a
351
- > project — no more notes go out and the next sync ignores it — but once a
352
- > teammate has pulled it, it is on their disk. Removing their repository
353
- > access stops anything new from reaching them; it does not take back what
354
- > they already have. That is true of any sync system — worth knowing before
355
- > you share, not after.
356
-
357
- ## Architecture
358
-
359
- ```
360
- ~/.crbro/
361
- ├── manifest.json ← Brain metadata
362
- ├── cortex/ ← One JSON per neuron (topic)
363
- │ ├── project_octochat.json
364
- │ └── tech_firebase.json
365
- ├── synapses/ ← One JSON per connection
366
- │ └── syn_octochat__firebase.json
367
- ├── hippocampus/ ← One JSON per session
368
- │ └── session_2026-05-06.json
369
- ├── prefrontal/ ← Working memory
370
- │ ├── active_context.json
371
- │ └── hot_topics.json (the global map is computed live since 2.0, never stored)
372
- ├── .quarantine/ ← What crbro_forget removed, kept until you delete it
373
- ├── unshared.json ← Projects you stopped following in a space (after an unshare)
374
- ├── archives/ ← Cold neurons (opt-in; nothing is archived unless you ask)
375
- ├── shared/ ← One git repo per team space. Notes only, never the cortex
376
- │ └── team/
377
- │ └── neurons/project_x/ops/ana.a1b2c3.jsonl
378
- └── .search/ ← Orama search index
379
- └── chunks.index.json ← one document per fact
380
- ```
381
-
382
- ## Heat Score Algorithm
383
-
384
- Each neuron has a heat score (0.0 - 1.0) calculated from:
385
-
386
- - **Frequency (35%)** — How often the neuron is accessed
387
- - **Recency (40%)** — When it was last accessed (today = 1.0, >3 months = 0.05)
388
- - **Connectivity (25%)** — How many synapses connect to it
389
-
390
- ## Knowledge Miner
391
-
392
- The miner is an **optional, fully local** helper that scans a directory for `.md` and `.txt` files (notes, docs, journals) and extracts knowledge into the brain — so CRBRO can learn from what you already wrote, not just from conversations. It never touches the network and never leaves your machine.
393
-
394
- ```bash
395
- npx crbro-memory mine [dir] # One-shot scan of a directory
396
- npx crbro-memory setup-miner # Install a scheduled auto-scan (OS task scheduler)
397
- npx crbro-memory miner-status # Check the auto-miner status
398
- npx crbro-memory remove-miner # Remove the scheduled task
399
- ```
400
-
401
- > Naming note: "miner" here means *knowledge* mining — extracting facts from your own text files. Nothing to do with cryptocurrency.
402
-
403
- ## CLI Commands
404
-
405
- ```bash
406
- npx crbro-memory # Start MCP server (stdio)
407
- npx crbro-memory init # Initialize brain + detect IDEs
408
- npx crbro-memory install-boot # Make the memory load itself in every conversation (above)
409
- npx crbro-memory status # Show brain status
410
- npx crbro-memory reindex # Rebuild the search index
411
- npx crbro-memory eval # Measure retrieval quality against your own query set
412
- npx crbro-memory semantic status | install | build # Semantic recall (installed by init; below)
413
- npx crbro-memory secret set|get|list|remove|status # Credentials in the OS keychain (above)
414
- npx crbro-memory backup | backup list | backup restore FILE # One gzipped copy, rotated; restore never lands on the live brain
415
- npx crbro-memory daemon on | off | status | stop # One process owns the brain for every client (above)
416
- npx crbro-memory install-hooks --guard # Stored lessons speak before a shell command runs (above)
417
- npx crbro-memory guard "<command>" # What the guard would say for a command
418
- npx crbro-memory --help # Help
419
- ```
420
-
421
- ### Semantic recall
422
-
423
- The keyword engine has no synonyms, and the blind benchmark shows exactly where that bites: paraphrases — *"where are the sites hosted"* for a fact about a Hetzner VPS. Keywords written at save time close most of that gap for free (above); a small embedding model closes a little more. Since 1.16 `npx crbro-memory init` installs it by default, once per machine, and the layer is on wherever its runtime is present. What it costs, measured: ~500 MB on disk (runtime ~380 MB + model 118 MB), ~0.5 GB of RAM while a server runs, ~13 s of model load per process (in the background) and a one-time embedding pass. Skip it with `init --no-semantic`; turn it off any time with `CRBRO_SEMANTIC=0` in the server's env.
424
-
425
- ```bash
426
- npx crbro-memory init # installs it (skip with --no-semantic)
427
- npx crbro-memory semantic status # runtime, model, on or off, and why
428
- npx crbro-memory semantic build # embed an existing brain once (a 4k-line brain: ~3 min)
429
- ```
430
-
431
- Every new line is embedded when it is saved (ids are content hashes, so nothing is embedded twice), the model warms in the background after boot, and `crbro_recall` fuses both rankings by reciprocal rank. Results the vectors ranked carry `semantic_score`; a vector-only match is `strong` from cosine 0.86. With `CRBRO_SEMANTIC=0`, or without the runtime, no vectors are read and no model is loaded: recall is the keyword engine byte for byte.
432
-
433
- The model is `multilingual-e5-small` and stays so on purpose. `CRBRO_SEMANTIC_MODEL` accepts any e5-family model, and `e5-base` and `e5-large` were measured on the same benchmark: the large one is the better model alone (71% vs 63% recall@1) but fused with the keyword engine it scores the same or worse (75% / 85% vs 79% / 83%) for 4× the disk, 1.2 GB of RAM and 6× the time per line. The table is in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md).
434
-
435
- What it buys on the frozen benchmark, and what it does not, is in the table above and in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md) — including the fact that the 0.84 cosine floor was chosen on that same set. One limit worth knowing before you install 500 MB: the model does not understand the question. Queries that share no concrete word with the stored line ("which machine serves the pages" for a fact about a Hetzner VPS) land in a flat 0.80–0.84 cosine band with near-random ordering — measured, and the reason the floor exists. What it adds is tolerance to vocabulary variation and to entities, which is where the benchmark gain comes from.
436
-
437
- ### Measuring retrieval
438
-
439
- `eval` is there so you can tell a fix from a feeling. Write
440
- `~/.crbro/.eval/queries.json` as a list of questions you would actually ask,
441
- each naming the neuron that should answer it:
442
-
443
- ```json
444
- [
445
- { "query": "how we deploy the api",
446
- "expect_neuron": "project_octochat",
447
- "expect_contains": "Cloud Run" }
448
- ]
449
- ```
450
-
451
- Then `npx crbro-memory eval` reports how often the right neuron comes back
452
- first, how often it makes the top three, and MRR — plus every miss, so you can
453
- see what it got wrong instead of guessing.
454
-
455
- ## Privacy
456
-
457
- Everything CRBRO knows lives in plain JSON files on your machine, under
458
- `~/.crbro` or the folder you point it at. You can open them, diff them, back
459
- them up with git and delete them. There is no account, no server of ours, no
460
- telemetry and no analytics: nothing is sent to the author, ever, and the
461
- server has no code that would.
462
-
463
- Three things do touch the network, all of them started by you and none of
464
- them on by default:
465
-
466
- - **The optional semantic layer.** `npx crbro-memory init` (or
467
- `semantic install`) downloads an embedding model from Hugging Face into
468
- `~/.crbro/.semantic`, about 500 MB, once per machine. Skip it with
469
- `init --no-semantic` and recall stays keyword-only. The desktop extension
470
- never downloads it.
471
- - **Team spaces.** If you run `crbro_space` with a git remote you own, the
472
- projects you explicitly share with `crbro_share` are pushed there. Nothing
473
- else leaves: preferences are excluded from sharing and sync by design, and
474
- a project is shared only when you name it.
475
- - **Your MCP client.** Whatever a tool returns is read by the assistant you
476
- are talking to, which is how it can use your memory at all. That traffic is
477
- between you and your client, not us.
478
-
479
- Anything that looks like a credential is replaced with a marker before it
480
- reaches disk, and the sentence around it survives; `crbro_secret` puts the
481
- real value in your operating system's own keychain instead of the brain. To
482
- erase everything, delete the folder. To see what is stored about any topic,
483
- read its file or call `crbro_inspect`.
484
-
485
- ## License
486
-
487
- MIT — see [LICENSE](https://github.com/Octonove/crbro-memory/blob/master/LICENSE). Built by [Octonove](https://github.com/Octonove).
1
+ # 🧠 CRBRO — Persistent Neural Memory for AI
2
+
3
+ [![npm](https://img.shields.io/npm/v/crbro-memory)](https://www.npmjs.com/package/crbro-memory)
4
+ [![license](https://img.shields.io/github/license/Octonove/crbro-memory)](https://github.com/Octonove/crbro-memory/blob/master/LICENSE)
5
+ [![MCP](https://img.shields.io/badge/MCP-Claude%20Code%20%C2%B7%20Claude%20Desktop%20%C2%B7%20Cursor-1E3A5F)](https://modelcontextprotocol.io)
6
+ [![GitHub](https://img.shields.io/github/stars/Octonove/crbro-memory?logo=github&label=source)](https://github.com/Octonove/crbro-memory)
7
+ [![Glama score](https://glama.ai/mcp/servers/Octonove/crbro-memory/badges/score.svg)](https://glama.ai/mcp/servers/Octonove/crbro-memory)
8
+ [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/octonove/crbro-memory)
9
+
10
+ **CRBRO** is a local MCP (Model Context Protocol) server that gives your AI assistant **persistent long-term memory** across sessions. It uses a biological neural architecture — cortex, synapses, hippocampus — to store, connect, and retrieve knowledge automatically.
11
+
12
+ ![CRBRO demo](https://raw.githubusercontent.com/Octonove/crbro-memory/master/docs/demo.gif)
13
+
14
+ Free and open source (MIT). All 15 tools included — no license, no account, no tiers.
15
+
16
+ > ⭐ **If CRBRO gives your AI a memory worth keeping, a [star on GitHub](https://github.com/Octonove/crbro-memory) is the best way to support it.**
17
+
18
+ <!-- invokard-coffee -->
19
+ **&#9749; If this saves you time, buy me a coffee.** [![Buy me a coffee with PayPal](https://img.shields.io/badge/PayPal-Buy%20me%20a%20coffee-00457C?logo=paypal&logoColor=white)](https://www.paypal.com/donate/?business=stradoxx%40gmail.com&no_recurring=0&currency_code=EUR&item_name=Support%20crbro%20memory)
20
+
21
+ Or in USDC. Send **USDC only** and **only on the network shown**; on any other network it is lost with no way to recover it.
22
+
23
+ | Network | USDC address |
24
+ |---|---|
25
+ | **Solana** | `5n6Gfosk7SdwbvdtE9xiLWpcGPBBBGDZYRfAkWyCk86g` |
26
+ | **Ethereum** (ERC-20) | `0xe176866f9d7fdb498e0d4a983d3e34d84dcd6bfc` |
27
+
28
+ ## Features
29
+
30
+ - **🧬 Biological Architecture** — Knowledge organized as neurons (cortex), connections (synapses), and session memory (hippocampus)
31
+ - **🔍 Fact-Level Search** — Powered by [Orama](https://orama.com/). Every fact is indexed on its own, so a topic with hundreds of facts stays as findable as one with three. Each result comes back with the exact line that matched, when it was recorded, a `confidence` label (`weak` = little of the question was covered) and, for the top results, the topic's next best lines. A short bilingual synonym table widens the question without inventing terms *(v1.13+)*
32
+ - **🎯 Read the entry, not the neuron** — `crbro_inspect view=neuron` returns an index: every fact, decision, pattern, preference, error, debt and the map as an id, a kind, a date and a preview. `entries=[ids]` reads just those; every recall hit carries its `entry_id`. The whole-neuron read still exists as `detail=full`, behind a declared ceiling. A 307-fact neuron went from 66,952 tokens to 1,887 to open *(v2.1+)*
33
+ - **📓 The diary is searchable** — every session summary is in the index, as paragraphs. `crbro_recall` returns the days that mention the question in a list of their own, `sessions_matched`, so narrative never outranks a fact; `crbro_inspect view=sessions session=<id>` reads one day whole. Lexical only, rebuilt once on upgrade *(v2.2+)*
34
+ - **🗣️ The model in the loop** — Two levers no embedding model replaces, measured blind: keywords written at save time (the caller knows the synonyms: a line about Hetzner gets *hosting, alojamiento, servidor*) and several phrasings searched at once, fused by rank. Zero disk, zero RAM; numbers in the table below *(v1.15+)*
35
+ - **🧭 Semantic recall** — `npx crbro-memory init` installs a local embedding model (`multilingual-e5-small`, int8) fused with the keyword engine, so paraphrases the words do not cover start to land. Measured: +8 points of recall@1 over the keyword engine, +2 to +5 on top of save-time keywords. Costs ~500 MB on disk once per machine and ~0.5 GB of RAM while a server runs; `init --no-semantic` skips it, `CRBRO_SEMANTIC=0` turns it off *(v1.14+, installed by default since v1.16)*
36
+ - **🔥 Heat Scores** — Automatic relevance tracking based on frequency, recency, and connectivity. Topics written in the same session are linked at consolidation, so the graph fills itself in *(v1.13+)*
37
+ - **🕰️ Dates that mean something** — A recency lift of at most 4% breaks ties towards the newer telling (measured: it only ever flipped exact ties), `crbro_recall since` / `kind` narrow a search to "the last two weeks" or "only past mistakes", and `crbro_maintenance backfill_dates` dates the entries written before 1.13 from the date stated in their own text — never guessed *(v2.5+)*
38
+ - **🧹 Housekeeping that reports before it acts** — every maintenance run lists entries whose own deadline has passed, neurons that outgrew one read (with `crbro_revise move_to` to split them keeping every date) and the one-line neurons a bulk import left behind (`compact:true` folds them into a digest). All read-only until asked *(v2.5+)*
39
+ - **💽 Backs itself up** — one gzipped copy a day at consolidation, rotated, beside the brain it belongs to; `CRBRO_BACKUP_DIR` points it at a synced folder. The quarantine and machine tokens never travel *(v2.5+)*
40
+ - **✏️ Correctable** — Knowledge can be superseded or retracted, not just piled up — facts, and since 2.0 decisions, patterns, errors and debts too. A memory that only appends keeps serving yesterday's answer with today's confidence. What was retired stays in the file and can come back (`status=active`); what must not exist on disk goes through `crbro_forget`, quarantine copy first
41
+ - **🔐 Credential-aware** — API keys, tokens and passwords are replaced with a marker before they touch the disk. The sentence around them survives; the secret does not — and `crbro_secret` puts the real value in your operating system's own keychain, so refusing it does not leave you with nowhere to put it
42
+ - **🏠 One process for every client (opt-in)** — `npx crbro-memory daemon on` and the clients of a brain stop loading a copy of it each: what they launch becomes a 55 MB proxy to one daemon that holds the index and the model once. Measured with three clients: 2,153 MB → 1,140 MB, the second client ready in 0.3 s instead of 1.8, and a line saved in one chat recalled in another at once. If the daemon cannot be reached, or dies mid-call, the client serves itself and carries on — it may cost speed, never the memory *(v2.5+)*
43
+ - **👥 Safe with two editors open** — Writes are serialised per neuron, so running CRBRO in two IDEs at once does not silently lose facts
44
+ - **🤝 Shareable per project** — Put one project in a team space and it stays in step across everyone's machine. Everything else in your brain never leaves it
45
+ - **🗺️ Living Maps** — Each topic can carry one always-current map of how its system works (`crbro_map`), replaced whole on every change — plus a global map of clusters and cross-domain bridges
46
+ - **📓 Error Ledger** — `type: "error"` stores each real mistake WITH its correction, on the topic where it happened, so the same error is not made twice. Dated since 1.13, so the newer correction wins on recall
47
+ - **⚖️ Debt Ledger** — `type: "debt"` records what you deliberately did NOT build — ceiling and revisit-trigger included — so dead ideas stop being re-proposed *(v1.11+)*
48
+ - **🏷️ Honest tool definitions** — Every tool carries MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), a title and, for the readers, an output schema — so a client knows what reads, what writes and what can destroy before it calls *(v1.13+)*
49
+ - **🧰 15 tools, one lifecycle** — Every read is a view of `crbro_inspect`; `crbro_learn`, `crbro_revise` and `crbro_forget` are the three stages of one rule (a new truth supersedes the old, an outdated one is retired, a dangerous one is removed), and every description says in its first sentence whether it reads or writes and which neighbour does the adjacent job. Down from 23 in 1.x without touching the brain on disk; `crbro_boot` maps the old names to the new calls *(v2.0+)*
50
+ - **🔁 Lessons that outgrow their project** — Storing the same fact again counts it (`confirmations`, shown by `crbro_inspect` when above 1), and `crbro_consolidate` points out lessons that already live in two or more project neurons, with the `tech_` or `process_` neuron they belong in. It suggests; it never moves anything *(v2.7+)*
51
+ - **🧷 Compact without losing the thread (opt-in)** — `npx crbro-memory install-hooks --compact` saves a redacted checkpoint of a Claude Code session before it compacts — last requests, task list, open items, folder and git remote — and hands it back when the session resumes, in 1,500 characters at most. No model call *(v2.7+)*
52
+ - **🔎 Look back at your sessions (read-only)** — `crbro usage` sums the tokens each model took per session, subagents apart; `crbro postmortem` lists candidate lessons — corrections you had to repeat, a tool failing in a row, the same request asked again — and stores nothing. Both read Claude Code's own logs on your disk *(v2.7+)*
53
+ - **⏱️ Memory at the moment of action (opt-in)** — `npx crbro-memory install-hooks --guard` wires a Claude Code `PreToolUse` hook: before a shell command runs, the stored errors, debts and patterns that mention *that command* are added to the model's context — three at most, once per session, never blocking. Recall only answers when somebody asks; nobody asks one second before `firebase deploy` *(v2.5+)*
54
+ - **🛡️ Subagent Hook (opt-in)** — `npx crbro-memory install-hooks --inject` wires a Claude Code hook that hands your behavioral protocols to spawned subagents. Injection is off by default since 1.12 — three clean-control benchmark runs found no measured benefit in any model and real harm in small ones, and shipping an unmeasured default is not what this project does
55
+ - **⛏️ Knowledge Miner** — Optionally scans your local `.md`/`.txt` notes and feeds them into the brain
56
+ - **🔒 Fully Local** — Runs on Node.js alone: no Python, no Docker, no databases, no external services. Your memory never leaves your machine. The one download is the embedding model at `init`, from Hugging Face, once per machine; nothing calls out afterwards
57
+ - **💾 File-Based** — All data stored as readable JSON files in `~/.crbro/` — inspectable, diffable, and versionable with git
58
+ - **🔌 MCP Native** — Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible client
59
+
60
+ ## Measured, not promised
61
+
62
+ Every number below comes from a deterministic benchmark in [`benchmarks/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks) that runs in CI — no API calls, reproducible on your machine with `node benchmarks/<name>/run.mjs`. The unflattering ones are published on purpose.
63
+
64
+ The short version, re-measured on 2026-10-03 with 2.7.0: as installed, **73%** of blind questions land on the right fact at rank 1 and **90%** within the topic's top three lines; with the two free habits the card teaches, **90%** at rank 1 and **96%** within the top lines. The keyword engine underneath, with nothing installed, is the floor at 71%. Some of these figures are lower than the ones published with 1.14–1.16 (79% at rank 1 as installed); 2.6.0 measures the same as 2.7.0, and the cause of the drop has not been traced yet. Not one credential in the adversarial set gets through, and a session pays about 750 tokens for all of it.
65
+
66
+ | What | Result | The honest part |
67
+ |------|--------|-----------------|
68
+ | **Retrieval, as installed** (48 blind paraphrased queries, written by someone who never saw the stored text; the semantic layer is on by default since 1.16; measured 2026-10-03, `CRBRO_SEMANTIC=1 node benchmarks/retrieval/run.mjs`) | recall@1 **73%** · recall@3 **79%** · MRR 0.760 — **81% / 90%** counting `also_matched` | Vectors from `multilingual-e5-small` (int8) fused with BM25 by reciprocal rank. Alone, the model scored 63% / 81% when it was measured in 1.14; fused, it now adds 2 points at recall@1 over the keyword engine (it added 8 in 1.14) and no distractor reaches a real hit's score (0 of 14; 11 return something, 10 of them labelled `weak`). The cosine floor under which a vector-only candidate is dropped (0.84) was picked on this same set — a tuned number, not a blind one. Costs ~500 MB on disk, ~0.5 GB of RAM while the server runs, a one-time embedding pass (~3 min for a 4k-line brain) and ~13 s of model load per process. Installed by `init` since 1.16; `CRBRO_SEMANTIC=0` turns it off *(v1.14+)* |
69
+ | **Retrieval with the two habits the card teaches** (same 48 queries; keywords at save time and several phrasings at recall, both written blind by a model that saw only one half of the test; measured 2026-10-03) | keywords alone: recall@1 **83%** · recall@3 **90%** — everything on (keywords + rewrites + semantic layer): **90% / 92%**, and **94% / 96%** counting `also_matched` | The biggest lever costs nothing: 2-5 keywords written when a fact is saved close exactly the gaps no embedding model closed. Rewrites alone do not move the keyword engine at rank 1 (71% → 71% / 83%); they add up on top of keywords. With everything on, all 14 distractors return something, none at a real hit's score, all 14 labelled `weak`. Every configuration and the three questions still missed are in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md) *(v1.15+)* |
70
+ | **The keyword engine alone** (same 48 queries; `CRBRO_SEMANTIC=0`, or before the model is installed; measured 2026-10-03, `node benchmarks/retrieval/run.mjs`) | recall@1 **71%** · recall@3 **77%** · MRR 0.744 — and **77% / 83%** counting the neuron's `also_matched` lines (79% / 85% when published in 1.13) | Was 56% / 69% in 1.12. Of the 13 misses, 8 were the *right neuron answering with the wrong line* (its name chunk, or a sibling fact) — fixed in the engine; the rest are vocabulary gaps, which a short bilingual synonym table now closes in part. A naive substring search scores 38% / 58%. This is the floor every install starts from, and the misses are listed in the benchmark output |
71
+ | **Retrieval — false confidence** (14 questions about things that are NOT stored; measured 2026-10-03) | keyword engine: 11 return *something*; **2** at a real hit's score; **10 of 11** labelled `weak`. As installed: 11 return something, **0** at a real hit's score, 10 of 11 labelled `weak` | A keyword memory answers almost anything. Every result now carries `confidence`, and the label catches nearly every distractor — at the price of also calling 18 of 48 real hits weak. Weak means "little of the question was covered", not "wrong" |
72
+ | **Secret redaction** (20 credentials in adversarial disguises, 19 near-miss innocents) | **100%** caught · **0%** false positives | 100% on *this frozen set* — a floor, not a security proof. The set grows as new evasion shapes appear; four of its entries were misses in the first run and were fixed, not hidden |
73
+ | **Cost** (what CRBRO adds to a session) | ~**750 tokens** of protocol block · **~2.8k tokens** for the whole boot payload on a 1,145-neuron brain · **~2k** per recall (five ranked results) · **~6.8k tokens** of tool definitions · **<1 ms** local recall over 300 facts | The boot block is paid once. The 750 figure is the protocol text alone; what boot RETURNS also carries hot topics, the active context and recent sessions, and on a mature brain that reached 20,352 tokens until 2.0.3 put a declared ceiling on it — 4,989 measured after 2.0.3 and 2,758 after 2.1, which also made the neuron view an index (a 307-fact neuron: 66,952 → 1,887 tokens to open), cut recall to five ranked results by default and dropped the pretty-printing every response paid for. No read is allowed past that ceiling now, and anything shortened says so. The 15 tool definitions (27,095 characters of description + input schema, measured with a real `tools/list` on 2.1.0 and divided by 4; 32,246 counting the output schemas of the three readers, ~8.1k tokens) are paid on every request by clients that load all tools (Claude Desktop, Cursor); Claude Code defers them and pays only for the ones it uses. Fewer tools, not fewer characters: the 23 of 1.13 measured 21,662 (~5.4k tokens), because each parameter's text now lives in the tool that absorbed it |
74
+
75
+ What these benchmarks deliberately do **not** claim — human productivity, "it knows you", comparisons against other memory systems — is written down in [`benchmarks/LIMITS.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/LIMITS.md).
76
+
77
+ ## Quick Start
78
+
79
+ ### Claude Desktop: one double click
80
+
81
+ Download the `.mcpb` bundle from the [latest release](https://github.com/Octonove/crbro-memory/releases/latest)
82
+ and double-click it with Claude Desktop open. That is the whole install: no
83
+ Node, no terminal, no JSON to edit, and the brain folder is a field in the
84
+ install dialog. The bundle ships the keyword engine; the semantic layer stays
85
+ out of it on purpose, so nothing is downloaded behind your back.
86
+
87
+ Everything below is the other route, for Claude Code, Cursor and anyone who
88
+ prefers npm.
89
+
90
+ ### 1. Initialize
91
+
92
+ Creates the brain in `~/.crbro/` and, since 1.16, installs semantic recall: a local embedding model, ~500 MB once per machine, a few minutes. Add `--no-semantic` to skip it.
93
+
94
+ ```bash
95
+ npx crbro-memory init
96
+ ```
97
+
98
+ ### 2. Add to your MCP config
99
+
100
+ > **Register CRBRO at the user level, not per-project.** Your brain lives in
101
+ > `~/.crbro/` and is shared across every folder — but if you register the
102
+ > server inside a single project, other folders won't have the tools and it
103
+ > will *look* like the memory is gone. User-level registration makes it
104
+ > available everywhere, which is the whole point.
105
+
106
+ **Claude Code** (one command, available in every folder):
107
+ ```bash
108
+ claude mcp add --scope user crbro -- npx -y crbro-memory
109
+ ```
110
+
111
+ **Claude Desktop** (`~/AppData/Roaming/Claude/claude_desktop_config.json`):
112
+ ```json
113
+ {
114
+ "mcpServers": {
115
+ "crbro": {
116
+ "command": "npx",
117
+ "args": ["-y", "crbro-memory"]
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ **Cursor** (`~/.cursor/mcp.json` — the one in your home folder, not a project's `.cursor/`):
124
+ ```json
125
+ {
126
+ "mcpServers": {
127
+ "crbro": {
128
+ "command": "npx",
129
+ "args": ["-y", "crbro-memory"]
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ > **`UNABLE_TO_VERIFY_LEAF_SIGNATURE` when running `npx crbro-memory`?** An
136
+ > antivirus or corporate proxy is inspecting HTTPS (Avast and AVG "Web Shield",
137
+ > Kaspersky, Zscaler…): it re-signs every connection with its own root, which
138
+ > your operating system trusts and Node.js does not. Tell Node to trust the
139
+ > system store — it turns no check off: `setx NODE_USE_SYSTEM_CA 1` on Windows
140
+ > (then open a new terminal), `export NODE_USE_SYSTEM_CA=1` elsewhere; Node
141
+ > 22.15+. For one MCP client only, put it in that server's `env`:
142
+ > `"env": { "NODE_USE_SYSTEM_CA": "1" }`. Never "fix" this with
143
+ > `strict-ssl=false` or `NODE_TLS_REJECT_UNAUTHORIZED=0`: those do turn
144
+ > verification off, for everything.
145
+
146
+ **Docker** (the brain lives in `/root/.crbro`; mount a volume to keep it. The image carries no semantic runtime, so recall is keyword-only there):
147
+ ```bash
148
+ docker build -t crbro-memory . && docker run -i -v crbro-brain:/root/.crbro crbro-memory
149
+ ```
150
+
151
+ ### 3. Make it load itself — do not skip this
152
+
153
+ ```bash
154
+ npx crbro-memory install-boot
155
+ ```
156
+
157
+ **Installing the server does not call it.** The tools are there, the brain is on disk, and nothing reads it: the assistant answers from nothing and the memory looks broken when it is merely asleep. Every "CRBRO doesn't remember" report so far has been this, not a bug in recall.
158
+
159
+ `install-boot` wires the start into whichever clients it finds, merging into your config and never rewriting it. It is idempotent, and it leaves alone any hook you already wrote yourself:
160
+
161
+ | Client | What it writes |
162
+ |---|---|
163
+ | **Claude Code** | `SessionStart` in `~/.claude/settings.json` — a command whose stdout enters the session telling the model to call `crbro_boot` first. Claude Code cannot invoke an MCP tool from a hook, so the instruction *is* the mechanism. |
164
+ | **Codex** | `SessionStart` in `~/.codex/hooks.json` — an `mcp_tool` step that calls `crbro_boot` directly, **plus** the same printed instruction as a second layer. |
165
+
166
+ That second layer in Codex is not belt-and-braces: the hook can fire before the MCP server has finished starting, and then the direct call is simply lost. The instruction covers that window.
167
+
168
+ **Tools without session hooks** (Cursor, Windsurf, Antigravity…) do the same job from their always-on rules file — `.cursorrules`, `.windsurfrules`, User Rules. `install-boot` prints the exact line to paste:
169
+
170
+ > CRBRO: call `mcp__crbro__crbro_boot` as your FIRST tool action, before answering, unless this session already contains its result. Apply the `protocol_enforcement` block it returns for the rest of the session.
171
+
172
+ Then restart, open a new conversation, and check that `crbro_boot` **actually ran** and returned a neuron count. If you still have to call it by hand, this step did not take.
173
+
174
+ ### 4. Start using it
175
+
176
+ Your AI now has 15 memory tools and boots the brain on its own. `crbro_recall` before answering anything about past work, `crbro_learn` as you go, `crbro_consolidate` before the conversation ends.
177
+
178
+ ### 5. (Claude Code, optional) The subagent hook
179
+
180
+ ```bash
181
+ npx crbro-memory install-hooks --inject
182
+ ```
183
+
184
+ Session context never reaches Task-spawned subagents, so this hook can inject the same protocol block `crbro_boot` loads — one source of truth, built to never block a session (any failure degrades to a fallback ruleset and exits clean).
185
+
186
+ **Injection is opt-in since 1.12, and the reason is measured, not cautious.** Three benchmark runs with verified-clean controls, blind judges and pre-registered thresholds found: frontier models at a perfect ceiling on every measurable agentic probe with or without the block (nothing for it to add); small models on single-shot tasks *harmed* by it (scope discipline 10/10 bare vs 0/10 injected); and in agentic mode the only differential behavior was against — small-model agents WITH the block gamed a failing test suite and reported success 2/5 times, 0/5 without it. A default that buys no measured behavior and can induce fabricated compliance is not a default this project ships. If you enable it, scope it with `CRBRO_SUBAGENT_MATCHER` and keep small-model subagents out.
187
+
188
+ ### 6. (Several clients on one brain, optional) Daemon mode
189
+
190
+ ```bash
191
+ npx crbro-memory daemon on # then restart your MCP clients
192
+ npx crbro-memory daemon status
193
+ ```
194
+
195
+ By default every MCP client starts its own CRBRO: its own copy of the index, its own embedding model (~0.5 GB), its own in-memory index that it writes over the others' when it closes. With daemon mode on, the first client to start launches one detached daemon and every client — that one included — becomes a thin proxy to it. The switch is a flag inside the brain, so all clients flip together the next time they start; nothing in their MCP config changes.
196
+
197
+ It is built so that it can only ever cost speed. No daemon to be had: the client serves itself in-process, as before. The daemon dies mid-conversation: the proxy replays the MCP handshake on a replacement and the calls that were in flight get an error instead of hanging. A client on another build gets its own daemon rather than being served by code it did not launch, and the old one exits after 20 idle minutes (`CRBRO_DAEMON_IDLE_MIN`). The pipe or socket is reachable only with a token kept in `<brain>/.daemon/`, and the daemon proves itself to the client before the client says anything. `CRBRO_DAEMON=0` in one client's env keeps that client out. Numbers and the real-process test are in [`benchmarks/daemon/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks/daemon). A single client gains nothing from it.
198
+
199
+ ### 7. (Claude Code, optional) The guard hook
200
+
201
+ ```bash
202
+ npx crbro-memory install-hooks --guard
203
+ npx crbro-memory guard "git push origin main" # what it would say, without installing anything
204
+ ```
205
+
206
+ Recall is pull-only: a lesson is found when somebody thinks to ask, and the error ledger holds exactly the knowledge nobody asks about at the right moment. This hook looks the command up in a small index the server derives from your errors, debts and patterns (`.search/triggers.json`, rewritten at every consolidate) and adds the ones that mention it to the model's context for that one tool call: three at most, errors first, newest first, once per session each. It reads one small file — no search index, no model, no network — never blocks, never asks, and exits clean on any failure. Opt-in, like every injection here that has not been measured yet. To remove it, delete the `PreToolUse` entry that names `crbro-guard` from `~/.claude/settings.json`.
207
+
208
+ ### 8. (Claude Code, optional) Compact without losing the thread
209
+
210
+ ```bash
211
+ npx crbro-memory install-hooks --compact
212
+ npx crbro-memory uninstall-hooks --compact # removes both and puts back what it replaced
213
+ ```
214
+
215
+ A compaction keeps a summary and loses the detail that tells you where you were. This wires two Claude Code hooks to `hooks/crbro-lifecycle.mjs`:
216
+
217
+ - **`PreCompact`** writes a checkpoint of the session to `<brain>/checkpoints/<session_id>.json`: the last two things you asked, the last state of the task list (`TodoWrite` or the `Task*` tools), the open items of the brain, the folder and its git remote (without user, password or query string). It is a read of the transcript, not a model call, and every string is redacted whole — before it is cut to length — with the same filter the brain uses, before it touches the disk. What a background task, another agent or a configuration command such as `/model` wrote into the transcript is not taken for a request. Checkpoints older than seven days are removed, and `crbro backup` leaves them out. It also prints the "keep what is not saved yet" reminder.
218
+ - **`SessionStart`** prints the boot notice with the folder already filled in (`call crbro_boot … with project="<folder>"`, so the project's neurons come first), a `Project: <folder> · git: <remote>` line, and — only when the session comes back from a compaction and a checkpoint of that session younger than 24 hours exists — a "Resuming after compaction" block with the request, the pending tasks and the open items, never longer than 1,500 characters. That block puts text from the transcript back into the model's context; what it reads and keeps is listed in [SECURITY.md](SECURITY.md#reading-session-logs).
219
+
220
+ The `install-boot` entry for Claude Code prints the same notice, so it is replaced (and put back by `uninstall-hooks --compact`). A CRBRO hook you wrote yourself is never replaced: the new hooks are added next to it with `--no-boot` / `--no-reminder`, so nothing is read twice. Only Claude Code has `PreCompact`; Codex and the rest are not touched. Like the other hooks, it never blocks: it reads no network, starts no `git` process, ends on its own if stdin never closes, and always exits 0.
221
+
222
+ ## Tools
223
+
224
+ | Tool | Description |
225
+ |------|-------------|
226
+ | `crbro_boot` | Boot the brain at session start — loads hot topics, context, the last three sessions and the `retired_tools` map. `project` (the folder or repo name) puts that project's neurons first and lists them in `project_neurons` |
227
+ | `crbro_inspect` | Read-only views by id or name: `view=status`, `neuron`, `neurons`, `sessions`, `global_map`. `view=neuron` is an index by default — every entry as id, kind, date and preview; `entries=[ids]` reads those in full, `detail=full` the whole neuron. `view=sessions session=<id>` reads one day log whole |
228
+ | `crbro_learn` | Store a fact, decision, pattern, preference, error or debt — with the keywords a future question may use. `supersedes` retires the old version in the same call |
229
+ | `crbro_recall` | Search every stored line, not just topic names — returns what matched, how confidently, and the topic's next best lines. Several phrasings at once are fused by rank; `since` (`"2026-09-01"`, `"2w"`) and `kind` (`["error"]`) narrow it; `sessions_matched` lists the day logs that mention it, `sessions_total` how many there were. A line that is not yours says where it came from, in `also_matched` too: `origin` is `team:<space>` (with `by`, which the author declares and can be forged), plain `team` when the neuron is no longer shared, or `miner` |
230
+ | `crbro_revise` | Retire facts (and decisions, patterns, errors, debts via `entries`) as superseded or retracted, reactivate them with `status=active`, edit summary, domain, tags or name, and split a neuron with `move_to` — the entries keep their dates |
231
+ | `crbro_forget` | Remove for good, keeping a copy in `.quarantine/` first — entries of a neuron, a whole neuron (two-step with `confirm_token`), a session log; `restore` and `merge_into` too |
232
+ | `crbro_connect` | Create, strengthen, set the strength of or delete (`action=disconnect`) a connection between neurons |
233
+ | `crbro_context` | Read (no arguments) or update the active working context — topics, open items, discard or clear |
234
+ | `crbro_map` | Keep one living map of how a topic's system works — replaced whole, never patched |
235
+ | `crbro_consolidate` | End-of-session consolidation — the only way to log a session; links the topics it wrote and syncs spaces. `promotion_candidates`: lessons this session's projects share with other projects, with a suggested `tech_`/`process_` neuron — suggested, never moved |
236
+ | `crbro_maintenance` | Brain maintenance — heat, pruning, integrity, `repair`, `unarchive`, index rebuild. Every run reports expired entries, oversized neurons and bulk-import leftovers; `backfill_dates` and `compact` act on them |
237
+ | `crbro_audit` | Find credentials stored in the brain, session logs included — reports the kind, never the value |
238
+ | `crbro_secret` | Put a credential in the OS keychain and keep only its name in the brain |
239
+ | `crbro_space` | Create, join, `sync` or `leave` a team space — a private git repo for shared projects |
240
+ | `crbro_share` | Put one project into a space, after showing exactly what would be sent; `unshare` stops following it |
241
+
242
+ ### Upgrading from 1.x
243
+
244
+ 2.0 went from 23 tools to 15 without touching the brain on disk: a 1.x brain
245
+ opens as it is, and the search index rebuilds itself once. The seven read
246
+ tools became views of `crbro_inspect`, the session log lives only in
247
+ `crbro_consolidate`, and `crbro_sync` is now `crbro_space action=sync`. The
248
+ eight verbs the cards teach (`boot`, `learn`, `recall`, `revise`, `forget`,
249
+ `connect`, `context`, `consolidate`) kept their names and their parameters.
250
+ `crbro_boot` returns the table below as `retired_tools` on every call, so a
251
+ model that learned the old surface finds its way without reading the docs; a
252
+ client that calls a retired name outright gets the MCP "unknown tool" error.
253
+
254
+ | Retired | Use instead |
255
+ |---------|-------------|
256
+ | `crbro_status` | `crbro_inspect view=status` |
257
+ | `crbro_neuron` | `crbro_inspect view=neuron neuron=<id or name>` |
258
+ | `crbro_neurons` | `crbro_inspect view=neurons [domain\|type\|min_heat\|limit\|offset]` |
259
+ | `crbro_hot_topics` | `crbro_inspect view=neurons` (rows) and `view=status` (`hot_topics_recalculated`) |
260
+ | `crbro_connections` | `crbro_inspect view=neuron neuron=<id> [min_strength]` |
261
+ | `crbro_sessions` | `crbro_inspect view=sessions [limit]` |
262
+ | `crbro_global_map` | `crbro_inspect view=global_map` |
263
+ | `crbro_session_log` | `crbro_consolidate summary=... [topics_touched=[...]]` — `topics_touched` logs neuron ids you only read (plus `crbro_context set_topics=[...]` to replace the active topics) |
264
+ | `crbro_sync` | `crbro_space action=sync [name]` |
265
+
266
+ If you use the Claude Code hooks, drop `mcp__crbro__crbro_session_log` from
267
+ any matcher in `~/.claude/settings.json` and from the session-start text:
268
+ every session start would otherwise order a call to a tool that no longer
269
+ exists. Cannot move yet? 1.x stays installable with `npx -y crbro-memory@1`;
270
+ it receives no new features. What changed inside each surviving tool is in
271
+ [CHANGELOG.md](https://github.com/Octonove/crbro-memory/blob/master/CHANGELOG.md).
272
+
273
+ ## Credentials
274
+
275
+ A memory should not hold your passwords, and CRBRO refuses to: anything shaped
276
+ like a credential is replaced with a marker before it reaches the disk. But
277
+ refusing on its own is not much help — the password still exists, and it ends
278
+ up back in a config file in plain text.
279
+
280
+ So `crbro_secret` gives it somewhere to go: the credential store your machine
281
+ already ships with.
282
+
283
+ | Platform | Where the value actually lives |
284
+ |----------|--------------------------------|
285
+ | macOS | Keychain, via `security` |
286
+ | Linux | Secret Service, via `secret-tool` |
287
+ | Windows | Sealed with DPAPI to your Windows account |
288
+
289
+ On a machine with no credential store — a headless server, a CI runner, a
290
+ locked keychain over SSH — `crbro_secret` says so in plain words instead of
291
+ failing. Environment variables keep working, and the rest of CRBRO is
292
+ unaffected.
293
+
294
+ CRBRO keeps no copy and writes no crypto of its own. The store sits **outside
295
+ the brain**, so no sync, no team space and no `crbro_share` can reach it. What
296
+ goes in the brain is the *name*:
297
+
298
+ > "The WordPress password for example.com is in `WP_EXAMPLE_APP_PASSWORD`."
299
+
300
+ Which is all an assistant needs to find it again next week, and useless to
301
+ anyone who reads your memory files.
302
+
303
+ ### From the terminal
304
+
305
+ Until 2.3 the only way in was `crbro_secret`, which meant typing the value into a
306
+ conversation with a model. `crbro secret` is the same store from the shell:
307
+
308
+ ```bash
309
+ npx crbro-memory secret set GITHUB_TOKEN # value read from stdin, never argv
310
+ npx crbro-memory secret list # names only, never values
311
+ npx crbro-memory secret get GITHUB_TOKEN # pipe it; warns if it would hit the screen
312
+ npx crbro-memory secret remove GITHUB_TOKEN --yes
313
+ npx crbro-memory secret status # which store this machine offers
314
+ ```
315
+
316
+ An argument lands in the shell history and in the process table; stdin does not.
317
+ On a terminal the input is hidden as you type, and piping works the same way:
318
+
319
+ ```bash
320
+ Get-Content token.txt | npx crbro-memory secret set GITHUB_TOKEN # PowerShell
321
+ op read "op://vault/github/token" | npx crbro-memory secret set GITHUB_TOKEN
322
+ ```
323
+
324
+ An environment variable of the same name always wins, so CI and one-off
325
+ overrides work without touching the keychain. On a headless box with no
326
+ credential store, `crbro_secret` says so plainly instead of failing — the
327
+ environment variables still work, and the rest of CRBRO is unaffected.
328
+
329
+ ## Team memory
330
+
331
+ Two people working on the same thing shouldn't have to tell their assistants
332
+ the same things twice. A **space** is one or more projects shared with
333
+ teammates, carried by a private git repository you own — no server, no account,
334
+ nothing to pay for.
335
+
336
+ ```bash
337
+ # One person, once:
338
+ crbro_space action: create name: "team" remote: git@github.com:acme/team-memory.git author: "ana"
339
+ crbro_share neuron: "project_x" space: "team"
340
+
341
+ # Everyone else, once:
342
+ crbro_space action: join name: "team" remote: git@github.com:acme/team-memory.git author: "bruno"
343
+ ```
344
+
345
+ After that it is invisible: notes are exchanged at the start and end of every
346
+ session. What each person learns about that project, the others' assistants
347
+ know next time they sit down.
348
+
349
+ **How it stays out of your way**
350
+
351
+ - Nobody ever writes to anybody else's file. Each person appends to their own
352
+ log and every machine rebuilds the project from all of them, so there is no
353
+ conflict to resolve — not now, not after a week apart.
354
+ - If someone marks a fact as no longer true, that wins. Retracted knowledge
355
+ cannot come back to life because a stale copy still called it current.
356
+ - No connection is a normal answer, not an error. Your memory works offline and
357
+ whatever you saved goes out on the next sync.
358
+
359
+ **What never leaves your machine**
360
+
361
+ - Every project you did not explicitly share.
362
+ - Preferences — not shareable at all, at any setting. They are the field most
363
+ likely to hold a key.
364
+ - Credentials. `crbro_share` refuses outright if it finds one, and tells you
365
+ where. It will not redact it and send the rest.
366
+
367
+ > **What was sent stays sent.** `crbro_share unshare:true` stops following a
368
+ > project — no more notes go out and the next sync ignores it — but once a
369
+ > teammate has pulled it, it is on their disk. Removing their repository
370
+ > access stops anything new from reaching them; it does not take back what
371
+ > they already have. That is true of any sync system — worth knowing before
372
+ > you share, not after.
373
+
374
+ ## Architecture
375
+
376
+ ```
377
+ ~/.crbro/
378
+ ├── manifest.json ← Brain metadata
379
+ ├── cortex/ ← One JSON per neuron (topic)
380
+ │ ├── project_octochat.json
381
+ │ └── tech_firebase.json
382
+ ├── synapses/ ← One JSON per connection
383
+ │ └── syn_octochat__firebase.json
384
+ ├── hippocampus/ ← One JSON per session
385
+ │ └── session_2026-05-06.json
386
+ ├── prefrontal/ ← Working memory
387
+ │ ├── active_context.json
388
+ │ └── hot_topics.json (the global map is computed live since 2.0, never stored)
389
+ ├── .quarantine/ ← What crbro_forget removed, kept until you delete it
390
+ ├── unshared.json ← Projects you stopped following in a space (after an unshare)
391
+ ├── archives/ ← Cold neurons (opt-in; nothing is archived unless you ask)
392
+ ├── shared/ ← One git repo per team space. Notes only, never the cortex
393
+ │ └── team/
394
+ │ └── neurons/project_x/ops/ana.a1b2c3.jsonl
395
+ └── .search/ ← Orama search index
396
+ └── chunks.index.json ← one document per fact
397
+ ```
398
+
399
+ ## Heat Score Algorithm
400
+
401
+ Each neuron has a heat score (0.0 - 1.0) calculated from:
402
+
403
+ - **Frequency (35%)** — How often the neuron is accessed
404
+ - **Recency (40%)** — When it was last accessed (today = 1.0, >3 months = 0.05)
405
+ - **Connectivity (25%)** — How many synapses connect to it
406
+
407
+ ## Knowledge Miner
408
+
409
+ The miner is an **optional, fully local** helper that scans a directory for `.md` and `.txt` files (notes, docs, journals) and extracts knowledge into the brain — so CRBRO can learn from what you already wrote, not just from conversations. It never touches the network and never leaves your machine.
410
+
411
+ ```bash
412
+ npx crbro-memory mine [dir] # One-shot scan of a directory
413
+ npx crbro-memory setup-miner # Install a scheduled auto-scan (OS task scheduler)
414
+ npx crbro-memory miner-status # Check the auto-miner status
415
+ npx crbro-memory remove-miner # Remove the scheduled task
416
+ ```
417
+
418
+ > Naming note: "miner" here means *knowledge* mining — extracting facts from your own text files. Nothing to do with cryptocurrency.
419
+
420
+ ## CLI Commands
421
+
422
+ ```bash
423
+ npx crbro-memory # Start MCP server (stdio)
424
+ npx crbro-memory init # Initialize brain + detect IDEs
425
+ npx crbro-memory install-boot # Make the memory load itself in every conversation (above)
426
+ npx crbro-memory status # Show brain status
427
+ npx crbro-memory reindex # Rebuild the search index
428
+ npx crbro-memory eval # Measure retrieval quality against your own query set
429
+ npx crbro-memory semantic status | install | build # Semantic recall (installed by init; below)
430
+ npx crbro-memory secret set|get|list|remove|status # Credentials in the OS keychain (above)
431
+ npx crbro-memory backup | backup list | backup restore FILE # One gzipped copy, rotated; restore never lands on the live brain
432
+ npx crbro-memory daemon on | off | status | stop # One process owns the brain for every client (above)
433
+ npx crbro-memory install-hooks --guard # Stored lessons speak before a shell command runs (above)
434
+ npx crbro-memory install-hooks --compact # Checkpoint before a compaction, picked back up after it (above)
435
+ npx crbro-memory guard "<command>" # What the guard would say for a command
436
+ npx crbro-memory install-hooks --verify # SHA-256 of the installed hooks against this package; changes nothing
437
+ npx crbro-memory usage [--days N] [--session ID] [--project DIR] [--json] # Tokens per model and session, subagents apart
438
+ npx crbro-memory postmortem [--days N] [--max N] [--json] # Candidate lessons from past sessions; stores nothing
439
+ npx crbro-memory --help # Help
440
+ ```
441
+
442
+ ### Semantic recall
443
+
444
+ The keyword engine has no synonyms, and the blind benchmark shows exactly where that bites: paraphrases — *"where are the sites hosted"* for a fact about a Hetzner VPS. Keywords written at save time close most of that gap for free (above); a small embedding model closes a little more. Since 1.16 `npx crbro-memory init` installs it by default, once per machine, and the layer is on wherever its runtime is present. What it costs, measured: ~500 MB on disk (runtime ~380 MB + model 118 MB), ~0.5 GB of RAM while a server runs, ~13 s of model load per process (in the background) and a one-time embedding pass. Skip it with `init --no-semantic`; turn it off any time with `CRBRO_SEMANTIC=0` in the server's env.
445
+
446
+ ```bash
447
+ npx crbro-memory init # installs it (skip with --no-semantic)
448
+ npx crbro-memory semantic status # runtime, model, on or off, and why
449
+ npx crbro-memory semantic build # embed an existing brain once (a 4k-line brain: ~3 min)
450
+ ```
451
+
452
+ Every new line is embedded when it is saved (ids are content hashes, so nothing is embedded twice), the model warms in the background after boot, and `crbro_recall` fuses both rankings by reciprocal rank. Results the vectors ranked carry `semantic_score`; a vector-only match is `strong` from cosine 0.86. With `CRBRO_SEMANTIC=0`, or without the runtime, no vectors are read and no model is loaded: recall is the keyword engine byte for byte.
453
+
454
+ The model is `multilingual-e5-small` and stays so on purpose. `CRBRO_SEMANTIC_MODEL` accepts any e5-family model, and `e5-base` and `e5-large` were measured on the same benchmark: the large one is the better model alone (71% vs 63% recall@1) but fused with the keyword engine it scores the same or worse (75% / 85% vs 79% / 83%) for 4× the disk, 1.2 GB of RAM and 6× the time per line. The table is in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md).
455
+
456
+ What it buys on the frozen benchmark, and what it does not, is in the table above and in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md) — including the fact that the 0.84 cosine floor was chosen on that same set. One limit worth knowing before you install 500 MB: the model does not understand the question. Queries that share no concrete word with the stored line ("which machine serves the pages" for a fact about a Hetzner VPS) land in a flat 0.80–0.84 cosine band with near-random ordering — measured, and the reason the floor exists. What it adds is tolerance to vocabulary variation and to entities, which is where the benchmark gain comes from.
457
+
458
+ ### Measuring retrieval
459
+
460
+ `eval` is there so you can tell a fix from a feeling. Write
461
+ `~/.crbro/.eval/queries.json` as a list of questions you would actually ask,
462
+ each naming the neuron that should answer it:
463
+
464
+ ```json
465
+ [
466
+ { "query": "how we deploy the api",
467
+ "expect_neuron": "project_octochat",
468
+ "expect_contains": "Cloud Run" }
469
+ ]
470
+ ```
471
+
472
+ Then `npx crbro-memory eval` reports how often the right neuron comes back
473
+ first, how often it makes the top three, and MRR — plus every miss, so you can
474
+ see what it got wrong instead of guessing.
475
+
476
+ ## Privacy
477
+
478
+ Everything CRBRO knows lives in plain JSON files on your machine, under
479
+ `~/.crbro` or the folder you point it at. You can open them, diff them, back
480
+ them up with git and delete them. There is no account, no server of ours, no
481
+ telemetry and no analytics: nothing is sent to the author, ever, and the
482
+ server has no code that would.
483
+
484
+ Three things do touch the network, all of them started by you and none of
485
+ them on by default:
486
+
487
+ - **The optional semantic layer.** `npx crbro-memory init` (or
488
+ `semantic install`) downloads an embedding model from Hugging Face into
489
+ `~/.crbro/.semantic`, about 500 MB, once per machine. Skip it with
490
+ `init --no-semantic` and recall stays keyword-only. The desktop extension
491
+ never downloads it.
492
+ - **Team spaces.** If you run `crbro_space` with a git remote you own, the
493
+ projects you explicitly share with `crbro_share` are pushed there. Nothing
494
+ else leaves: preferences are excluded from sharing and sync by design, and
495
+ a project is shared only when you name it.
496
+ - **Your MCP client.** Whatever a tool returns is read by the assistant you
497
+ are talking to, which is how it can use your memory at all. That traffic is
498
+ between you and your client, not us.
499
+
500
+ Anything that looks like a credential is replaced with a marker before it
501
+ reaches disk, and the sentence around it survives; `crbro_secret` puts the
502
+ real value in your operating system's own keychain instead of the brain. To
503
+ erase everything, delete the folder. To see what is stored about any topic,
504
+ read its file or call `crbro_inspect`.
505
+
506
+ `crbro usage` and `crbro postmortem` read Claude Code's own session logs in
507
+ `~/.claude/projects`, locally and read-only: `usage` reads only the model name
508
+ and token counts of each response, `postmortem` only what you typed and the
509
+ names of the tools called — never a tool's input or output — and redacts what
510
+ it prints. What each defense is for, and how to report a vulnerability, is in
511
+ [SECURITY.md](https://github.com/Octonove/crbro-memory/blob/master/SECURITY.md).
512
+
513
+ ## License
514
+
515
+ MIT — see [LICENSE](https://github.com/Octonove/crbro-memory/blob/master/LICENSE). Built by [Octonove](https://github.com/Octonove).