crbro-memory 2.9.1 → 2.11.0

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 (197) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +256 -456
  3. package/SECURITY.md +135 -8
  4. package/bin/crbro.mjs +555 -299
  5. package/dist/build-id.json +10 -0
  6. package/dist/cli/common.js +211 -0
  7. package/dist/cli/export.js +522 -0
  8. package/dist/cli/import.js +683 -0
  9. package/dist/cli/markdown.js +313 -0
  10. package/dist/cli/mcpclient.js +107 -0
  11. package/dist/cli/serve.js +453 -0
  12. package/dist/cli/view.js +358 -0
  13. package/dist/cli/viewer-page.js +378 -0
  14. package/dist/daemon/daemon.js +119 -11
  15. package/dist/daemon/endpoint.js +222 -21
  16. package/dist/daemon/lines.js +102 -13
  17. package/dist/daemon/proxy.js +480 -125
  18. package/dist/daemon/surface.js +116 -0
  19. package/dist/daemon/trace.js +73 -0
  20. package/dist/engine/atrest.js +132 -0
  21. package/dist/engine/backup.js +143 -19
  22. package/dist/engine/brain.js +22 -6
  23. package/dist/engine/codexconfig.js +476 -0
  24. package/dist/engine/cortex.js +762 -311
  25. package/dist/engine/doctor.js +676 -0
  26. package/dist/engine/evidence.js +171 -0
  27. package/dist/engine/heat.js +81 -37
  28. package/dist/engine/hippocampus.js +50 -36
  29. package/dist/engine/hookrefresh.js +296 -0
  30. package/dist/engine/hookverify.js +15 -3
  31. package/dist/engine/installer.js +1022 -0
  32. package/dist/engine/installio.js +279 -0
  33. package/dist/engine/keychain.js +735 -144
  34. package/dist/engine/maintenance.js +355 -87
  35. package/dist/engine/modinstall.js +98 -45
  36. package/dist/engine/prefrontal.js +126 -69
  37. package/dist/engine/projects.js +80 -0
  38. package/dist/engine/quarantine.js +204 -0
  39. package/dist/engine/secrets.js +41 -5
  40. package/dist/engine/shelf.js +34 -11
  41. package/dist/engine/synapses.js +183 -80
  42. package/dist/engine/triggers.js +141 -11
  43. package/dist/index.js +37 -3
  44. package/dist/mcp-surface.json +1 -0
  45. package/dist/miner/extractor.js +64 -17
  46. package/dist/miner/scheduler.js +144 -68
  47. package/dist/search/index.js +810 -176
  48. package/dist/search/quality.js +31 -0
  49. package/dist/search/semantic.js +208 -18
  50. package/dist/search/tokenize.js +44 -0
  51. package/dist/server.js +649 -343
  52. package/dist/sync/git.js +203 -72
  53. package/dist/sync/materialize.js +33 -8
  54. package/dist/sync/space.js +286 -101
  55. package/dist/sync/validate.js +204 -0
  56. package/dist/utils/budget.js +15 -2
  57. package/dist/utils/fs.js +40 -6
  58. package/dist/utils/ids.js +128 -14
  59. package/dist/utils/lock.js +219 -52
  60. package/hooks/crbro-codex.mjs +284 -0
  61. package/hooks/crbro-guard.mjs +281 -173
  62. package/hooks/crbro-hooks.shipped.json +20 -0
  63. package/hooks/crbro-lifecycle.mjs +16 -4
  64. package/hooks/crbro-subagent.mjs +180 -180
  65. package/package.json +12 -8
  66. package/dist/daemon/daemon.d.ts +0 -25
  67. package/dist/daemon/daemon.d.ts.map +0 -1
  68. package/dist/daemon/daemon.js.map +0 -1
  69. package/dist/daemon/endpoint.d.ts +0 -66
  70. package/dist/daemon/endpoint.d.ts.map +0 -1
  71. package/dist/daemon/endpoint.js.map +0 -1
  72. package/dist/daemon/lines.d.ts +0 -55
  73. package/dist/daemon/lines.d.ts.map +0 -1
  74. package/dist/daemon/lines.js.map +0 -1
  75. package/dist/daemon/proxy.d.ts +0 -55
  76. package/dist/daemon/proxy.d.ts.map +0 -1
  77. package/dist/daemon/proxy.js.map +0 -1
  78. package/dist/engine/backup.d.ts +0 -68
  79. package/dist/engine/backup.d.ts.map +0 -1
  80. package/dist/engine/backup.js.map +0 -1
  81. package/dist/engine/brain.d.ts +0 -79
  82. package/dist/engine/brain.d.ts.map +0 -1
  83. package/dist/engine/brain.js.map +0 -1
  84. package/dist/engine/cortex.d.ts +0 -670
  85. package/dist/engine/cortex.d.ts.map +0 -1
  86. package/dist/engine/cortex.js.map +0 -1
  87. package/dist/engine/dates.d.ts +0 -28
  88. package/dist/engine/dates.d.ts.map +0 -1
  89. package/dist/engine/dates.js.map +0 -1
  90. package/dist/engine/heat.d.ts +0 -28
  91. package/dist/engine/heat.d.ts.map +0 -1
  92. package/dist/engine/heat.js.map +0 -1
  93. package/dist/engine/hippocampus.d.ts +0 -60
  94. package/dist/engine/hippocampus.d.ts.map +0 -1
  95. package/dist/engine/hippocampus.js.map +0 -1
  96. package/dist/engine/hookverify.d.ts +0 -42
  97. package/dist/engine/hookverify.d.ts.map +0 -1
  98. package/dist/engine/hookverify.js.map +0 -1
  99. package/dist/engine/keychain.d.ts +0 -32
  100. package/dist/engine/keychain.d.ts.map +0 -1
  101. package/dist/engine/keychain.js.map +0 -1
  102. package/dist/engine/maintenance.d.ts +0 -218
  103. package/dist/engine/maintenance.d.ts.map +0 -1
  104. package/dist/engine/maintenance.js.map +0 -1
  105. package/dist/engine/modinstall.d.ts +0 -215
  106. package/dist/engine/modinstall.d.ts.map +0 -1
  107. package/dist/engine/modinstall.js.map +0 -1
  108. package/dist/engine/postmortem.d.ts +0 -81
  109. package/dist/engine/postmortem.d.ts.map +0 -1
  110. package/dist/engine/postmortem.js.map +0 -1
  111. package/dist/engine/prefrontal.d.ts +0 -61
  112. package/dist/engine/prefrontal.d.ts.map +0 -1
  113. package/dist/engine/prefrontal.js.map +0 -1
  114. package/dist/engine/secrets.d.ts +0 -30
  115. package/dist/engine/secrets.d.ts.map +0 -1
  116. package/dist/engine/secrets.js.map +0 -1
  117. package/dist/engine/shelf.d.ts +0 -156
  118. package/dist/engine/shelf.d.ts.map +0 -1
  119. package/dist/engine/shelf.js.map +0 -1
  120. package/dist/engine/source.d.ts +0 -6
  121. package/dist/engine/source.d.ts.map +0 -1
  122. package/dist/engine/source.js.map +0 -1
  123. package/dist/engine/synapses.d.ts +0 -82
  124. package/dist/engine/synapses.d.ts.map +0 -1
  125. package/dist/engine/synapses.js.map +0 -1
  126. package/dist/engine/triggers.d.ts +0 -53
  127. package/dist/engine/triggers.d.ts.map +0 -1
  128. package/dist/engine/triggers.js.map +0 -1
  129. package/dist/engine/usage.d.ts +0 -61
  130. package/dist/engine/usage.d.ts.map +0 -1
  131. package/dist/engine/usage.js.map +0 -1
  132. package/dist/index.d.ts +0 -2
  133. package/dist/index.d.ts.map +0 -1
  134. package/dist/index.js.map +0 -1
  135. package/dist/miner/extractor.d.ts +0 -12
  136. package/dist/miner/extractor.d.ts.map +0 -1
  137. package/dist/miner/extractor.js.map +0 -1
  138. package/dist/miner/index.d.ts +0 -61
  139. package/dist/miner/index.d.ts.map +0 -1
  140. package/dist/miner/index.js.map +0 -1
  141. package/dist/miner/scheduler.d.ts +0 -30
  142. package/dist/miner/scheduler.d.ts.map +0 -1
  143. package/dist/miner/scheduler.js.map +0 -1
  144. package/dist/miner/types.d.ts +0 -11
  145. package/dist/miner/types.d.ts.map +0 -1
  146. package/dist/miner/types.js.map +0 -1
  147. package/dist/search/index.d.ts +0 -323
  148. package/dist/search/index.d.ts.map +0 -1
  149. package/dist/search/index.js.map +0 -1
  150. package/dist/search/semantic.d.ts +0 -80
  151. package/dist/search/semantic.d.ts.map +0 -1
  152. package/dist/search/semantic.js.map +0 -1
  153. package/dist/search/synonyms.d.ts +0 -2
  154. package/dist/search/synonyms.d.ts.map +0 -1
  155. package/dist/search/synonyms.js.map +0 -1
  156. package/dist/search/tokenize.d.ts +0 -39
  157. package/dist/search/tokenize.d.ts.map +0 -1
  158. package/dist/search/tokenize.js.map +0 -1
  159. package/dist/server.d.ts +0 -41
  160. package/dist/server.d.ts.map +0 -1
  161. package/dist/server.js.map +0 -1
  162. package/dist/sync/git.d.ts +0 -36
  163. package/dist/sync/git.d.ts.map +0 -1
  164. package/dist/sync/git.js.map +0 -1
  165. package/dist/sync/materialize.d.ts +0 -35
  166. package/dist/sync/materialize.d.ts.map +0 -1
  167. package/dist/sync/materialize.js.map +0 -1
  168. package/dist/sync/ops.d.ts +0 -142
  169. package/dist/sync/ops.d.ts.map +0 -1
  170. package/dist/sync/ops.js.map +0 -1
  171. package/dist/sync/space.d.ts +0 -116
  172. package/dist/sync/space.d.ts.map +0 -1
  173. package/dist/sync/space.js.map +0 -1
  174. package/dist/types/index.d.ts +0 -346
  175. package/dist/types/index.d.ts.map +0 -1
  176. package/dist/types/index.js.map +0 -1
  177. package/dist/utils/budget.d.ts +0 -44
  178. package/dist/utils/budget.d.ts.map +0 -1
  179. package/dist/utils/budget.js.map +0 -1
  180. package/dist/utils/fs.d.ts +0 -59
  181. package/dist/utils/fs.d.ts.map +0 -1
  182. package/dist/utils/fs.js.map +0 -1
  183. package/dist/utils/hash.d.ts +0 -20
  184. package/dist/utils/hash.d.ts.map +0 -1
  185. package/dist/utils/hash.js.map +0 -1
  186. package/dist/utils/ids.d.ts +0 -47
  187. package/dist/utils/ids.d.ts.map +0 -1
  188. package/dist/utils/ids.js.map +0 -1
  189. package/dist/utils/lock.d.ts +0 -11
  190. package/dist/utils/lock.d.ts.map +0 -1
  191. package/dist/utils/lock.js.map +0 -1
  192. package/dist/utils/transcripts.d.ts +0 -63
  193. package/dist/utils/transcripts.d.ts.map +0 -1
  194. package/dist/utils/transcripts.js.map +0 -1
  195. package/dist/version.d.ts +0 -26
  196. package/dist/version.d.ts.map +0 -1
  197. package/dist/version.js.map +0 -1
package/README.md CHANGED
@@ -7,114 +7,46 @@
7
7
  [![Glama score](https://glama.ai/mcp/servers/Octonove/crbro-memory/badges/score.svg)](https://glama.ai/mcp/servers/Octonove/crbro-memory)
8
8
  [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/octonove/crbro-memory)
9
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.
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. Everything lives in plain JSON files on your machine.
11
11
 
12
12
  ![CRBRO tour: memory across sessions, corrections that replace old facts, secrets kept out, the guard before a shell command, the compaction checkpoint and the open-items band](https://raw.githubusercontent.com/Octonove/crbro-memory/master/docs/crbro-tour.gif)
13
13
 
14
14
  Free and open source (MIT). All 15 tools included — no license, no account, no tiers.
15
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.**
16
+ **This page has three layers.** [1. Quick start](#1-quick-start) gets you running in a minute. [2. Reference](#2-reference) lists the tools, the commands and the environment variables. [3. Measurements](#3-measurements) says what it costs and how well it works, with dates. [Troubleshooting](#troubleshooting-and-faq) covers the problems people actually hit.
17
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)
18
+ ---
20
19
 
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.
20
+ ## 1. Quick start
22
21
 
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. It matters most in a big brain: with 1,482 unrelated facts around the test set it lifts recall@1 from 54% to 67% on the original exam and from 31% to 48% on a new 96-question one; on a small brain it measures within 2 points of the keyword engine (75% vs 77% on 2.7.2). 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
- - **⏳ Shelf life: what may have changed comes apart** — A port, a price, a version or who holds a role changes in the world without anyone telling the memory, and recall used to serve the old value with `confidence: strong`. Now every fact has a shelf life — `volatile` (versions, prices, ports, hosts, paths, config, people in roles: 90 days), `normal` (365), `durable` (decisions and patterns: 730) or `permanent` (preferences, errors, debts, history: never) — set with `shelf_life` on `crbro_learn` or, when omitted, inferred from the text and returned. Since 2.9.1 two kinds of unmarked fact are inferred `permanent`: a line the miner imported (`shelf_reason: "miner"`), and a dated record of something done — a date and a finished action in the line's first sentence, "FASE 2 completada (ago 2026)", "Deployed v2.3.1 on 2026-06-18" (`shelf_reason: "history"`) — unless that sentence states what holds from a date on ("desde el 18-sep el puerto es 9443", "as of 2026-10-01 the plan is $49"), looks ahead ("caduca", "will be released"), speaks of the present ("actualmente", "last deployed") or says the value it carries still holds ("Comprobado el 4-oct-2026: cuesta 35 €", "Migrado el panel al puerto 9443 (18-sep-2026)"); those keep warning. The clock runs from the last verification: `crbro_revise status=verified` when the agent checked a line against its source, or the same fact learned again with nothing else in the call. A recall row whose best line is past its window moves, whole, to a separate `possibly_stale` block with `age_days` and `last_verified`, and the hint says how to reconfirm or supersede it; the ranking does not change and what is current stays where it was. The windows are a policy choice, not a measurement — `CRBRO_SHELF_DAYS="volatile=90,normal=365,durable=730"` changes them, `CRBRO_STALENESS=0` turns the whole feature off. An existing brain is not flooded on upgrade: unmarked lines written before the first boot of this version start counting near that boot — since 2.9.1 the ones the detector infers volatile too, when the brain itself predates shelf life — staggered so they do not all come due on the same day; a line marked volatile by hand gets no grace, lines with no date are never flagged, and nothing is rewritten on disk. **Measured, and it did not change what the agent answers:** in the pre-registered agentic case below, recall flags all four changed values correctly, but no agent opened the file to check — see the table. A second iteration changes how the warning arrives: the answer opens with `stale_warning`, each stale row leads with `warning` and a `next_step` (open the file the line itself names, or look where the value lives; if that is not possible, say it may be out of date) and carries the old line as `last_known` rather than as ordinary content, and `crbro_learn` asks that a changeable value say where it came from. **Measured on a second pre-registered case, and still not met:** when recall flags the row, the agent stops giving the old value as current (it warns or abstains), but it still does not open the file to check, and only two of that case's six changed values were flagged at all — see the table
39
- - **🧹 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+)*
40
- - **💽 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+)*
41
- - **✏️ 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
42
- - **🔐 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
43
- - **🏠 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+)*
44
- - **👥 Safe with two editors open** — Writes are serialised per neuron, so running CRBRO in two IDEs at once does not silently lose facts
45
- - **🤝 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
46
- - **🗺️ 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
47
- - **📓 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
48
- - **⚖️ 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+)*
49
- - **🏷️ 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+)*
50
- - **🧰 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+)*
51
- - **🔁 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+)*
52
- - **🧷 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+)*
53
- - **📌 Open items in sight (on by default for Claude Code, opt-out)** — where Claude Code is installed, `crbro_boot` adds a Claude Code mod on its own, keeps it up to date, and has the assistant tell you once when it does: the newest open item of the brain above the prompt, whole — its label apart, its numbered steps one per line, its age in color — with ‹ › to go through the rest, and `/pending` (alias `/pendientes`) with every one as a card: filter, *work on this*, *done* and *discard* behind a confirmation, and what was closed lately. It reads through `crbro_context` and closes through it; the brain file is only read when the server is not reachable. English or Spanish (`--lang`). Needs Claude Code 2.1.286 or later: the CLI and the desktop app's Code tab. Remove it with `npx crbro-memory uninstall-mod` — it is never put back on its own, whichever app runs CRBRO — or keep one MCP client from installing it with `CRBRO_MOD=0` in that client's env *(v2.8+)*
54
- - **🔎 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+)*
55
- - **⏱️ 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+)*
56
- - **🛡️ 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
57
- - **⛏️ Knowledge Miner** — Optionally scans your local `.md`/`.txt` notes and feeds them into the brain
58
- - **🔒 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
59
- - **💾 File-Based** — All data stored as readable JSON files in `~/.crbro/` — inspectable, diffable, and versionable with git
60
- - **🔌 MCP Native** — Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible client
61
-
62
- ## Measured, not promised
63
-
64
- Every number below comes from a benchmark in [`benchmarks/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks), reproducible on your machine with `node benchmarks/<name>/run.mjs`. All of them are deterministic and run in CI with no API calls, except the agentic one, which puts a real Claude Code agent to work and spends tokens. The unflattering ones are published on purpose.
65
-
66
- The short version, measured on 2026-10-03 with 2.7.2: **a fresh session did not ask again what memory already held** — with CRBRO a real agent answered 24 of 24 questions whose answer lived only in memory, without it 0 of 24 (haiku and sonnet, Claude Code 2.1.270, n=3). As installed, **75%** 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, **92%** at rank 1 and **98%** within the top lines. A second, harder exam of 96 new questions lands 57% at rank 1, and the semantic layer earns its place as the brain grows: inside 1,482 unrelated facts it holds 48% where the keyword engine alone falls to 31%. The drop of the semantic layer since 2.5 (79% → 73%) is traced to two changes in how ties and vectors are computed, not to a search bug. Not one credential in the adversarial set gets through, and a session pays about 1,000 tokens for all of it.
67
-
68
- | What | Result | The honest part |
69
- |------|--------|-----------------|
70
- | **A fresh session does not ask again** (a new Claude Code session, no history, gets a question whose answer lives only in a memory seeded earlier; the prompt never mentions memory; 12 frozen fictitious tasks, 4 thresholds fixed before running; haiku and sonnet, Claude Code 2.1.270, n=3; measured 2026-10-03, `node benchmarks/agentic/run.mjs`) | with CRBRO **24/24** on answers that live only in memory, **0** retired values given (12/12 where an old value was replaced) — without it **0/24**, and sonnet invented 4 | Both controls behave: when the answer is in the question both arms get it (6/6), and when it is nowhere CRBRO abstains as often as the bare agent (6/6, nothing invented). The server's instructions were fixed twice between runs on these same 12 tasks — the published run is the one where the fix works, not a blind one — and these are short single-question sessions. A result holds for that model and that Claude Code version; another needs its own run. Pre-registration and every run are in [`benchmarks/agentic/`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/agentic/PREREGISTRO.md) *(v2.7.2)* |
71
- | **A value that changed and nobody retired** (`stale-unmarked`: four fictitious values — a version, a price, a port, a person in a role — still live in memory at 200 days while the current one sits in a file in the working directory, readable by both arms; thresholds pre-registered before any run; 2.8.0 `before` vs the shelf-life branch `after`, haiku and sonnet, Claude Code 2.1.270, n=3; measured 2026-10-04) | with CRBRO, **0/12** correct before and **0/12** after in both models; old value given without a warning: haiku 11 → 9 and 10, sonnet 12 → 11 and 12 (two `after` runs each). Without memory the agent reads the file and gets 1-6 of 12 | **Not met — the pre-registered claim is not made.** The shelf-life feature does its part (recall moves all four rows to `possibly_stale`, 200 days old, with a hint to check them), but in 48 `after` cells no agent with CRBRO opened the file: they answered from recall, abstained, or once (sonnet) gave the old value with a warning. Here memory still answers worse than no memory with the file at hand. The 12 original tasks still pass all four thresholds in the complete `after` runs (24/24, 0 retired values, controls 6/6). Cost per CRBRO cell on these tasks: haiku $0.0121 → ~$0.015, sonnet $0.0263 → ~$0.027. Limits: no task has an old value that is still true, so false warnings are not measured, and two of the four texts match the detector's own examples. Full tables in [`benchmarks/agentic/PREREGISTRO.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/agentic/PREREGISTRO.md) |
72
- | **The same, second iteration** (`stale-unmarked-b`: a new fictitious project, six values that changed — an SMS provider, a price, a person in a role, an API host, a time, a cancellation window — still live in memory at 130-300 days, two marked volatile, one marked normal, three unmarked, current values in files both arms can read; tasks and thresholds pre-registered before any run; 2.8.0 `before` vs the branch with the second iteration `after`, one run per model, haiku and sonnet, Claude Code 2.1.270, n=3; measured 2026-10-04) | with CRBRO, **0/18 → 1/18** correct (haiku) and **0/18 → 0/18** (sonnet); old value given without a warning: haiku 14 → 9, sonnet 18 → 12; with a warning: sonnet 0 → 6; abstentions: haiku 4 → 8. Without memory the agent reads the file and gets 6 (haiku) and 9 (sonnet) of 18 | **Not met — the pre-registered claim is not made** (U1, U2, U3 fail in both models; U4 and U5 pass). Recall flagged only two of the six rows: the other four, unmarked or marked normal and under 365 days old, are served as current, and nothing changed there (same answers before and after). On the two flagged rows the old value as current went from 5 to 0 (haiku) and 6 to 0 (sonnet): haiku abstains, sonnet gives it with a warning. An agent with CRBRO opened a file in 1 of 48 cells. False warnings are now measured too: on an old value that is still true, sonnet keeps answering it right but adds "may be out of date"; haiku abstains as it did on 2.8.0. The 12 original tasks still pass all four thresholds in the same runs. Cost per CRBRO cell on these tasks: haiku $0.0114 → $0.0129, sonnet $0.0268 → $0.0272. Six tasks by one author on one project; the author of the product change knew the tasks. Full tables in [`benchmarks/agentic/PREREGISTRO.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/agentic/PREREGISTRO.md) |
73
- | **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 on 2.7.2, `CRBRO_SEMANTIC=1 node benchmarks/retrieval/run.mjs`) | recall@1 **75%** · recall@3 **81%** · MRR 0.781 — **81% / 90%** counting `also_matched` | Vectors from `multilingual-e5-small` (int8) fused with BM25 by reciprocal rank. On this small set the fusion now sits 2 points below the keyword engine at rank 1 (75% vs 77%) — the keyword engine got better in 2.7.2, the fusion barely moved — and no distractor reaches a real hit's score (0 of 14). It added 8 points in 1.14; the −6 since 2.5 is traced in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md). The cosine floor under which a vector-only candidate is dropped (0.84) was picked on this same set and re-checked on a separate tuning 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 when it was measured in batches; one line at a time since 2.7.2 takes 1.6× as long) and ~13 s of model load per process. Installed by `init` since 1.16; `CRBRO_SEMANTIC=0` turns it off *(v1.14+)* |
74
- | **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 on 2.7.2) | keywords alone: recall@1 **83%** · recall@3 **92%** — everything on (keywords + rewrites + semantic layer): **92% / 96%**, and **94% / 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 — which is why `crbro_learn` now asks for them when a fact arrives without. Rewrites alone do not move the keyword engine at rank 1 (77% → 77% / 90%); they add up on top of keywords. With everything on, no distractor reaches a real hit's score. Every configuration and the questions still missed are in [`benchmarks/README.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/README.md) *(v1.15+)* |
75
- | **The keyword engine alone** (same 48 queries; `CRBRO_SEMANTIC=0`, or before the model is installed; measured 2026-10-03 on 2.7.2, `node benchmarks/retrieval/run.mjs`) | recall@1 **77%** · recall@3 **83%** · MRR 0.806 — the same counting `also_matched` (71% / 77% on 2.7.1) | Was 56% / 69% in 1.12. 2.7.2 weighs each query term by its rarity, chosen on a separate tuning set: +6 here, +12 inside the 1,482-fact haystack, and nothing on the new 96-question exam (49%). A naive substring search scores 38% / 58%. This is the floor every install starts from, and the misses are listed in the benchmark output |
76
- | **Retrieval at scale** (a second blind exam of 96 questions + 20 distractors, and a haystack of 1,482 facts in 114 unrelated topics learned before the test brain; both frozen before measuring; measured 2026-10-03 on 2.7.2) | as installed: recall@1 **57%** · recall@3 **60%**; inside the haystack **48% / 52%**. Keyword engine alone: 49% / 53%, inside the haystack **31% / 40%** | The new exam is harder than the original one and gives more false confidence: 8 of its 20 distractors come back at a real hit's score as installed, 11 with the keyword engine. Its numbers did not move between 2.7.1 and 2.7.2. What it shows is what the semantic layer is for: the more unrelated facts a brain holds, the more it carries recall — 17 points here |
77
- | **Retrieval — false confidence** (14 questions about things that are NOT stored; measured 2026-10-03 on 2.7.2) | keyword engine: **2** at a real hit's score. As installed: **0** at a real hit's score | A keyword memory answers almost anything. Every result carries `confidence`, and the label catches nearly every distractor on this set — at the price of also calling some real hits weak. Weak means "little of the question was covered", not "wrong". On the harder 96-question exam it catches far fewer (see the row above) |
78
- | **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 |
79
- | **Cost** (what CRBRO adds to a session) | ~**1,000 tokens** of protocol block · **~2.8k tokens** for the whole boot payload on a 1,145-neuron brain · **~2k** per recall (five ranked results) · **~7.5k tokens** of tool definitions · **~1 ms** local recall over 300 facts with the keyword engine, **~10 ms** with the semantic layer, which embeds the question | The boot block is paid once. The 1,000 figure is the protocol text alone — Card Zero's ten protocols, 4,035 characters, measured on 2026-10-03 (750 before its tenth protocol); 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 (29,897 characters of description + input schema, measured with a real `tools/list` on 2.7.2 on 2026-10-03 and divided by 4; 35,416 counting the output schemas of the three readers, ~8.9k tokens; 29,757 on 2.7.1; 27,095 and 32,246 on 2.1.0) 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 |
80
-
81
- 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).
82
-
83
- ## Quick Start
22
+ You need **Node.js 20 or later** (the Claude Desktop bundle below needs none).
84
23
 
85
24
  ### Claude Desktop: one double click
86
25
 
87
- Download the `.mcpb` bundle from the [latest release](https://github.com/Octonove/crbro-memory/releases/latest)
88
- and double-click it with Claude Desktop open. That is the whole install: no
89
- Node, no terminal, no JSON to edit, and the brain folder is a field in the
90
- install dialog. The bundle ships the keyword engine; the semantic layer stays
91
- out of it on purpose, so nothing is downloaded behind your back.
92
-
93
- Everything below is the other route, for Claude Code, Cursor and anyone who
94
- prefers npm.
26
+ Download the `.mcpb` bundle from the [latest release](https://github.com/Octonove/crbro-memory/releases/latest) and double-click it with Claude Desktop open. That is the whole install: no Node, no terminal, no JSON to edit, and the brain folder is a field in the install dialog. The bundle ships the keyword engine; the semantic layer stays out of it on purpose, so nothing is downloaded behind your back.
95
27
 
96
- ### 1. Initialize
97
-
98
- 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.
28
+ ### Every other client: one command
99
29
 
100
30
  ```bash
101
- npx crbro-memory init
31
+ npx crbro-memory install
102
32
  ```
103
33
 
104
- ### 2. Add to your MCP config
34
+ It finds the MCP clients on this machine (Claude Code, Claude Desktop, Cursor, Codex), copies the engine to one stable folder (`~/.crbro-engine/<version>`, or `--engine-dir DIR`), registers `node <that folder>/crbro.mjs` in each client with the timeouts that client needs, and makes the memory load itself at the start of every conversation. No `npx` at client start, so every client runs the same build and shares one daemon. It merges into your config files and never rewrites them: every file it touches keeps a timestamped backup beside it (`<file>.crbro-bak-<stamp>`). Pick clients with `--clients claude-code,codex` (default `auto`), see what it would do first with `--dry-run`, and get the report as JSON with `--json`. `npx crbro-memory uninstall` takes the same flags and removes only what CRBRO added — never the brain ([complete uninstall](#complete-uninstall)).
35
+
36
+ Then **restart the client, open a new conversation, and check that `crbro_boot` actually ran** and returned a neuron count. `npx crbro-memory doctor` is a read-only check of what is installed where.
37
+
38
+ > **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. The `install` command above wires the start for you; the manual route is below.
105
39
 
106
- > **Register CRBRO at the user level, not per-project.** Your brain lives in
107
- > `~/.crbro/` and is shared across every folder — but if you register the
108
- > server inside a single project, other folders won't have the tools and it
109
- > will *look* like the memory is gone. User-level registration makes it
110
- > available everywhere, which is the whole point.
40
+ ### Registering by hand
41
+
42
+ Prefer to edit config yourself? Register CRBRO at the **user level, not per-project**: the brain lives in `~/.crbro/` and is shared across every folder, but a server registered inside one project is missing everywhere else and it will *look* like the memory is gone.
111
43
 
112
44
  **Claude Code** (one command, available in every folder):
113
45
  ```bash
114
46
  claude mcp add --scope user crbro -- npx -y crbro-memory
115
47
  ```
116
48
 
117
- **Claude Desktop** (`~/AppData/Roaming/Claude/claude_desktop_config.json`):
49
+ **Claude Desktop** — `%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `~/.config/Claude/claude_desktop_config.json` on Linux:
118
50
  ```json
119
51
  {
120
52
  "mcpServers": {
@@ -126,450 +58,318 @@ claude mcp add --scope user crbro -- npx -y crbro-memory
126
58
  }
127
59
  ```
128
60
 
129
- **Cursor** (`~/.cursor/mcp.json` — the one in your home folder, not a project's `.cursor/`):
130
- ```json
131
- {
132
- "mcpServers": {
133
- "crbro": {
134
- "command": "npx",
135
- "args": ["-y", "crbro-memory"]
136
- }
137
- }
138
- }
139
- ```
61
+ **Cursor** — `~/.cursor/mcp.json` (the one in your home folder, not a project's `.cursor/`): same JSON as above.
140
62
 
141
- > **`UNABLE_TO_VERIFY_LEAF_SIGNATURE` when running `npx crbro-memory`?** An
142
- > antivirus or corporate proxy is inspecting HTTPS (Avast and AVG "Web Shield",
143
- > Kaspersky, Zscaler…): it re-signs every connection with its own root, which
144
- > your operating system trusts and Node.js does not. Tell Node to trust the
145
- > system store — it turns no check off: `setx NODE_USE_SYSTEM_CA 1` on Windows
146
- > (then open a new terminal), `export NODE_USE_SYSTEM_CA=1` elsewhere; Node
147
- > 22.15+. For one MCP client only, put it in that server's `env`:
148
- > `"env": { "NODE_USE_SYSTEM_CA": "1" }`. Never "fix" this with
149
- > `strict-ssl=false` or `NODE_TLS_REJECT_UNAUTHORIZED=0`: those do turn
150
- > verification off, for everything.
63
+ **Codex** — `~/.codex/config.toml`. Give it a startup timeout: Codex starts MCP servers when a session opens and gives up after a short default (see [Troubleshooting](#codex-says-the-mcp-server-timed-out-at-startup)).
64
+ ```toml
65
+ [mcp_servers.crbro]
66
+ command = "npx"
67
+ args = ["-y", "crbro-memory"]
68
+ startup_timeout_sec = 60
69
+ tool_timeout_sec = 120
70
+ ```
71
+ `install` and `install-boot` add these two lines only when they are missing; values you set yourself are kept.
151
72
 
152
73
  **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):
153
74
  ```bash
154
75
  docker build -t crbro-memory . && docker run -i -v crbro-brain:/root/.crbro crbro-memory
155
76
  ```
156
77
 
157
- ### 3. Make it load itself — do not skip this
78
+ ### Making it load itself, by hand
158
79
 
159
80
  ```bash
160
81
  npx crbro-memory install-boot
161
82
  ```
162
83
 
163
- **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.
164
-
165
84
  `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:
166
85
 
167
86
  | Client | What it writes |
168
87
  |---|---|
169
88
  | **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. |
170
- | **Codex** | `SessionStart` in `~/.codex/hooks.json` — an `mcp_tool` step that calls `crbro_boot` directly, **plus** the same printed instruction as a second layer. |
171
-
172
- 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.
89
+ | **Codex** | `SessionStart` in `~/.codex/hooks.json` — an `mcp_tool` step that calls `crbro_boot` directly, **plus** the same printed instruction as a second layer. The hook can fire before the MCP server has finished starting, and then the direct call is simply lost; the instruction covers that window. |
173
90
 
174
91
  **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:
175
92
 
176
93
  > 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.
177
94
 
178
- 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.
179
-
180
- ### 4. Start using it
181
-
182
- 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.
183
-
184
- ### 5. (Claude Code, optional) The subagent hook
185
-
186
- ```bash
187
- npx crbro-memory install-hooks --inject
188
- ```
189
-
190
- 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).
191
-
192
- **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.
193
-
194
- ### 6. (Several clients on one brain, optional) Daemon mode
195
-
196
- ```bash
197
- npx crbro-memory daemon on # then restart your MCP clients
198
- npx crbro-memory daemon status
199
- ```
200
-
201
- 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.
202
-
203
- 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.
204
-
205
- ### 7. (Claude Code, optional) The guard hook
206
-
207
- ```bash
208
- npx crbro-memory install-hooks --guard
209
- npx crbro-memory guard "git push origin main" # what it would say, without installing anything
210
- ```
211
-
212
- 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`.
213
-
214
- ### 8. (Claude Code, optional) Compact without losing the thread
215
-
216
- ```bash
217
- npx crbro-memory install-hooks --compact
218
- npx crbro-memory uninstall-hooks --compact # removes both and puts back what it replaced
219
- ```
220
-
221
- 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`:
95
+ ### Semantic recall (optional)
222
96
 
223
- - **`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.
224
- - **`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).
97
+ `npx crbro-memory init` creates the brain and installs a local embedding model that is fused with the keyword engine, so paraphrases the words do not cover start to land. It is a download of several hundred MB once per machine (sizes and timings in [Measurements](#3-measurements)); `init --no-semantic` skips it and `CRBRO_SEMANTIC=0` turns it off any time. Details: [docs/semantic-recall.md](docs/semantic-recall.md).
225
98
 
226
- 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.
99
+ ### Using it
227
100
 
228
- ### 9. (Claude Code, on by default) Open items in sight
229
-
230
- ![The open-items band above the Claude Code prompt and the /pending pane: an item read whole, filtered, sent to the prompt and closed through CRBRO](https://raw.githubusercontent.com/Octonove/crbro-memory/master/docs/pending-band.gif)
231
-
232
- Nothing to run: if Claude Code is on the machine (`~/.claude` exists), the first `crbro_boot` installs this mod exactly as `install-mod` below would, with the language on auto, and the boot answer carries a `mod_notice` the assistant passes on to you — what was installed, that it appears in *new* Claude Code sessions, and how to remove it. The notice goes to the first boot of up to three server processes (one each) within a week, because the first one may be a background run nobody reads. After an update of CRBRO, a boot that finds the installed files different from the package (SHA-256, line endings aside) refreshes them, without touching `settings.json`, and says so too; an older CRBRO on the same machine never takes back the files of a newer one, and two builds of the same version (a checkout beside the npm copy) do not rewrite each other. It runs once per server process (once per daemon) and never fails the boot. The files are copied without blocking and the boot waits for the install 1.5 s at most; the few settings reads and writes left are synchronous and take milliseconds. Two sessions starting at once take turns through a lock file, and `settings.json` is written only if it is still what was read: a change Claude Code saves at the same moment is merged, not lost.
233
-
234
- To opt out:
235
-
236
- ```bash
237
- npx crbro-memory uninstall-mod # removes it and leaves a mark: never put back on its own, from any app
238
- CRBRO_MOD=0 # in one MCP client's env: that client never installs or updates it
239
- ```
240
-
241
- `uninstall-mod` is the machine-wide way out: the mark sits in `~/.claude/crbro-mods/state.json`, which every CRBRO reads. `CRBRO_MOD=0` only covers the client whose MCP configuration sets it — CRBRO in Codex, Cursor or Claude Desktop installs in the same `~/.claude` unless it has the variable too — so set it in each, or run `uninstall-mod` once. Taking `~/.claude/crbro-mods/crbro-pending` out of `CLAUDE_CODE_PLUGIN_DIRS` by hand counts as a no as well, and the next boot says so once, with the way back. `install-mod` lifts the mark. A `settings.json` that does not parse is never touched, and the same failure is not retried until that file or the package changes, or a day goes by (a file held open by another program is retried at the next start). If the list already holds another `crbro-pending` (a checkout of this repository, say), nothing is installed beside it. If `CLAUDE_CODE_PLUGIN_DIRS` is set only in the environment Claude Code starts from and not in `settings.json`, nothing is installed either — `settings.json`'s `env` wins over the environment, so writing the variable there would stop those plugins from loading — and the boot says so once; move the variable into `settings.json` and the next start adds the mod beside them. Claude Code before 2.1.286 has not been tried with the mod.
242
-
243
- ```bash
244
- npx crbro-memory install-mod # --lang en | es | auto (default: leave it as it is; auto on a first install)
245
- npx crbro-memory install-mod --verify # SHA-256 of the installed copy against this package; changes nothing
246
- npx crbro-memory uninstall-mod
247
- ```
248
-
249
- An open item left in `crbro_context` is only seen when `crbro_boot` lists it, which is how finished work gets repeated back for weeks and unfinished work gets forgotten. This installs `mods/crbro-pending`, a Claude Code mod (a plugin of function hooks):
250
-
251
- - **The band**, above the prompt: the newest open item, whole. A short `Label:` is drawn apart and `(1) … (2) …` steps go one per line; the age is green up to 3 days, amber up to two weeks, red after. ‹ › walks the others, *Compact* folds it to one line, *See all* opens the list, *Hide* puts it away until `/pending`.
252
- - **`/pending`** (alias `/pendientes`): every open item as a card, with a filter that ignores accents, *Work on this* (writes the item into the prompt for you to send), *Done* and *Discard*, each behind a yes/no, and the items closed lately.
101
+ 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.
253
102
 
254
- It reads with `crbro_context` and no arguments, which only reads, on whichever MCP server has that tool (`crbro` in a standard install, found with the session's tool list), and refreshes every minute and after every CRBRO tool call. When no CRBRO server is reachable it reads `<CRBRO_PATH or ~/.crbro>/prefrontal/active_context.json` instead, resolved as the server resolves it, and says so. That fallback only sees a `CRBRO_PATH` set where Claude Code itself runs (the system, your shell, or the `env` block of `~/.claude/settings.json`), not one set only in the MCP server's own `env` block; with a brain configured only there, the band reads `~/.crbro` until the server connects, and the pane names the file it read. *Done* and *Discard* always go through the server — `resolve_pending` keeps the item under recently closed, `discard_pending` does not — and the mod never writes the brain.
103
+ More that you can switch on, each in [docs/hooks.md](docs/hooks.md) and [docs/daemon.md](docs/daemon.md): the guard hook (stored lessons speak before a shell command runs), the compaction checkpoint, the subagent hook, the open-items band in Claude Code, and the daemon for several clients on one brain.
255
104
 
256
- `install-mod` copies the mod to `~/.claude/crbro-mods/crbro-pending` and adds that folder to `env.CLAUDE_CODE_PLUGIN_DIRS` in `~/.claude/settings.json` (`;` between folders on Windows, `:` elsewhere), once; nothing else in that file is touched, except the mod's own language when `--lang en` or `--lang es` is given (`pluginConfigs.crbro-pending.options.language`, also a row in `/config`). `auto` follows `CRBRO_LANG`, then `LC_ALL` / `LC_MESSAGES` / `LANG`, then the system locale. A `settings.json` that does not parse is left alone, the write is atomic, and running it again changes nothing. If the list already holds a folder whose plugin is named `crbro-pendientes` — the copy made by hand before this existed — it is replaced in place and named; its folder stays on disk. Any other copy, another `crbro-pending` in the list or one in `~/.claude/mods`, is pointed out and never touched, and `--verify` fails while it is there, because Claude Code would draw two bands. `uninstall-mod` takes the path out of the list (and the variable, if it ends up empty), puts back the `crbro-pendientes` folder it replaced if that folder is still there, and deletes `~/.claude/crbro-mods/crbro-pending`, nothing else. If `CLAUDE_CODE_PLUGIN_DIRS` is also set in your shell with folders `settings.json` does not list, `install-mod` names them: the `env` block of `settings.json` is applied on top of the environment, so add them there if those plugins stop loading. `install-hooks --verify` checks the mod too.
105
+ ---
257
106
 
258
- Mods need Claude Code 2.1.286 or later and are drawn in the CLI and in the desktop app's Code tab; Claude Desktop chat, Codex, Cursor and the VS Code extension do not draw them. Open a new session after installing.
107
+ ## 2. Reference
259
108
 
260
- ## Tools
109
+ ### The 15 tools
261
110
 
262
111
  | Tool | Description |
263
112
  |------|-------------|
264
113
  | `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` |
265
114
  | `crbro_inspect` | Read-only views by id or name: `view=status` (with the version the process runs, and the one installed on disk when npx replaced it under a running process), `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 |
266
- | `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; `shelf_life` says how fast a fact goes stale (inferred from the text when omitted, and returned); the same fact again, with nothing else in the call, counts as re-verified |
267
- | `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`. A row whose best line is past its shelf life since last verified comes back apart, in `possibly_stale`: `warning` and `next_step` first (what to check before answering, naming the file the line cites when it cites one), the line as `last_known`, then `age_days`, `last_verified`, `shelf_life` and `shelf_inferred`; the answer then opens with `stale_warning`. An old `also_matched` preview carries `stale_days` |
268
- | `crbro_revise` | Retire facts (and decisions, patterns, errors, debts via `entries`) as superseded or retracted, reactivate them with `status=active`, reconfirm facts, decisions and patterns checked against their source with `status=verified`, edit summary, domain, tags or name, and split a neuron with `move_to` — the entries keep their dates |
115
+ | `crbro_learn` | Store a fact, decision, pattern, preference, error or debt with search keywords. `supersedes` replaces old facts; `shelf_life`, `reference` and `temporal` describe the claim. Repeating it never verifies it; use an explicit `crbro_revise status=verified` with evidence after a real check |
116
+ | `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. A line that is not yours says where it came from (`origin`). A row past its shelf life comes back apart, in `possibly_stale`, with what to check before answering |
117
+ | `crbro_revise` | Retire facts (and decisions, patterns, errors, debts via `entries`) as superseded or retracted, reactivate them with `status=active`, reconfirm checked ones with `status=verified`, edit summary, domain, tags or name, and split a neuron with `move_to` — the entries keep their dates |
269
118
  | `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 |
270
119
  | `crbro_connect` | Create, strengthen, set the strength of or delete (`action=disconnect`) a connection between neurons |
271
120
  | `crbro_context` | Read (no arguments) or update the active working context — topics, open items, discard or clear |
272
121
  | `crbro_map` | Keep one living map of how a topic's system works — replaced whole, never patched |
273
- | `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 |
274
- | `crbro_maintenance` | Brain maintenance — heat, pruning, integrity, `repair`, `unarchive`, index rebuild. Every run reports expired entries, entries past their shelf life (`stale_entries`, `stale_sample`), oversized neurons and bulk-import leftovers; `backfill_dates` and `compact` act on them |
122
+ | `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 — suggested, never moved |
123
+ | `crbro_maintenance` | Brain maintenance — heat, pruning, integrity, `repair`, `unarchive`, index rebuild. Every run reports expired entries, entries past their shelf life, oversized neurons and bulk-import leftovers; `backfill_dates` and `compact` act on them |
275
124
  | `crbro_audit` | Find credentials stored in the brain, session logs included — reports the kind, never the value |
276
- | `crbro_secret` | Put a credential in the OS keychain and keep only its name in the brain |
277
- | `crbro_space` | Create, join, `sync` or `leave` a team space — a private git repo for shared projects |
125
+ | `crbro_secret` | Put a credential in the OS keychain and keep only its name in the brain. See [docs/credentials.md](docs/credentials.md) |
126
+ | `crbro_space` | Create, join, `sync` or `leave` a team space — a private git repo for shared projects. See [docs/team-memory.md](docs/team-memory.md) |
278
127
  | `crbro_share` | Put one project into a space, after showing exactly what would be sent; `unshare` stops following it |
279
128
 
280
- ### Upgrading from 1.x
281
-
282
- 2.0 went from 23 tools to 15 without touching the brain on disk: a 1.x brain
283
- opens as it is, and the search index rebuilds itself once. The seven read
284
- tools became views of `crbro_inspect`, the session log lives only in
285
- `crbro_consolidate`, and `crbro_sync` is now `crbro_space action=sync`. The
286
- eight verbs the cards teach (`boot`, `learn`, `recall`, `revise`, `forget`,
287
- `connect`, `context`, `consolidate`) kept their names and their parameters.
288
- `crbro_boot` returns the table below as `retired_tools` on every call, so a
289
- model that learned the old surface finds its way without reading the docs; a
290
- client that calls a retired name outright gets the MCP "unknown tool" error.
291
-
292
- | Retired | Use instead |
293
- |---------|-------------|
294
- | `crbro_status` | `crbro_inspect view=status` |
295
- | `crbro_neuron` | `crbro_inspect view=neuron neuron=<id or name>` |
296
- | `crbro_neurons` | `crbro_inspect view=neurons [domain\|type\|min_heat\|limit\|offset]` |
297
- | `crbro_hot_topics` | `crbro_inspect view=neurons` (rows) and `view=status` (`hot_topics_recalculated`) |
298
- | `crbro_connections` | `crbro_inspect view=neuron neuron=<id> [min_strength]` |
299
- | `crbro_sessions` | `crbro_inspect view=sessions [limit]` |
300
- | `crbro_global_map` | `crbro_inspect view=global_map` |
301
- | `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) |
302
- | `crbro_sync` | `crbro_space action=sync [name]` |
303
-
304
- If you use the Claude Code hooks, drop `mcp__crbro__crbro_session_log` from
305
- any matcher in `~/.claude/settings.json` and from the session-start text:
306
- every session start would otherwise order a call to a tool that no longer
307
- exists. Cannot move yet? 1.x stays installable with `npx -y crbro-memory@1`;
308
- it receives no new features. What changed inside each surviving tool is in
309
- [CHANGELOG.md](https://github.com/Octonove/crbro-memory/blob/master/CHANGELOG.md).
310
-
311
- ## Credentials
312
-
313
- A memory should not hold your passwords, and CRBRO refuses to: anything shaped
314
- like a credential is replaced with a marker before it reaches the disk. But
315
- refusing on its own is not much help — the password still exists, and it ends
316
- up back in a config file in plain text.
317
-
318
- So `crbro_secret` gives it somewhere to go: the credential store your machine
319
- already ships with.
320
-
321
- | Platform | Where the value actually lives |
322
- |----------|--------------------------------|
323
- | macOS | Keychain, via `security` |
324
- | Linux | Secret Service, via `secret-tool` |
325
- | Windows | Sealed with DPAPI to your Windows account |
326
-
327
- On a machine with no credential store — a headless server, a CI runner, a
328
- locked keychain over SSH — `crbro_secret` says so in plain words instead of
329
- failing. Environment variables keep working, and the rest of CRBRO is
330
- unaffected.
331
-
332
- CRBRO keeps no copy and writes no crypto of its own. The store sits **outside
333
- the brain**, so no sync, no team space and no `crbro_share` can reach it. What
334
- goes in the brain is the *name*:
335
-
336
- > "The WordPress password for example.com is in `WP_EXAMPLE_APP_PASSWORD`."
337
-
338
- Which is all an assistant needs to find it again next week, and useless to
339
- anyone who reads your memory files.
340
-
341
- ### From the terminal
342
-
343
- Until 2.3 the only way in was `crbro_secret`, which meant typing the value into a
344
- conversation with a model. `crbro secret` is the same store from the shell:
129
+ A 1.x brain opens as it is: see [Upgrading from 1.x](docs/upgrading-from-1x.md) for the retired tool names.
345
130
 
346
- ```bash
347
- npx crbro-memory secret set GITHUB_TOKEN # value read from stdin, never argv
348
- npx crbro-memory secret list # names only, never values
349
- npx crbro-memory secret get GITHUB_TOKEN # pipe it; warns if it would hit the screen
350
- npx crbro-memory secret remove GITHUB_TOKEN --yes
351
- npx crbro-memory secret status # which store this machine offers
352
- ```
131
+ ### Commands
353
132
 
354
- An argument lands in the shell history and in the process table; stdin does not.
355
- On a terminal the input is hidden as you type, and piping works the same way:
133
+ Every command is run as `npx crbro-memory <command>` (there is no separate `crbro` binary). `--version` prints the version and `<command> --help` explains one command.
356
134
 
357
- ```bash
358
- Get-Content token.txt | npx crbro-memory secret set GITHUB_TOKEN # PowerShell
359
- op read "op://vault/github/token" | npx crbro-memory secret set GITHUB_TOKEN
360
- ```
135
+ **Setup and checks**
361
136
 
362
- An environment variable of the same name always wins, so CI and one-off
363
- overrides work without touching the keychain. On a headless box with no
364
- credential store, `crbro_secret` says so plainly instead of failing — the
365
- environment variables still work, and the rest of CRBRO is unaffected.
137
+ | Command | What it does |
138
+ |---|---|
139
+ | `install` / `uninstall` | Register CRBRO in your MCP clients and wire the boot hook; remove what it installed. `--dry-run` lists the changes without making them |
140
+ | `init` | Create the brain and install semantic recall (`--no-semantic` skips it) |
141
+ | `install-boot` | Make the memory load itself in every conversation (above) |
142
+ | `status` | Show the brain's status |
143
+ | `doctor [--json]` | Read-only diagnostics: versions, brain and client paths, hooks, daemon leftovers, quarantine, backups' age, semantic files. Repairs nothing, reads no credential values. See [docs/doctor.md](docs/doctor.md) |
144
+ | `reindex` | Rebuild the search index |
145
+ | `eval` | Measure retrieval quality against your own query set ([docs/semantic-recall.md](docs/semantic-recall.md#measuring-retrieval)) |
366
146
 
367
- ## Team memory
147
+ **Viewing, moving and serving the memory**
368
148
 
369
- Two people working on the same thing shouldn't have to tell their assistants
370
- the same things twice. A **space** is one or more projects shared with
371
- teammates, carried by a private git repository you own — no server, no account,
372
- nothing to pay for.
149
+ | Command | What it does |
150
+ |---|---|
151
+ | `view [--port N] [--no-open]` | A local page in your browser (127.0.0.1 only, one-time token in the link): neurons, every entry with its date, status, verification and freshness, search, open items to resolve or discard, stale entries to verify or retire |
152
+ | `export [--out DIR] [--format md\|json] [--include-retired]` | Write the brain as an Obsidian-compatible Markdown vault or one JSON file. Read-only, safe while a client runs, credentials redacted |
153
+ | `import PATH [--apply] [--topic NAME] [--type fact\|preference\|pattern]` | Bring memory in from `CLAUDE.md` / `AGENTS.md`, a Claude Code memory folder or a CRBRO export. A dry run unless `--apply`; importing twice adds nothing |
154
+ | `serve --http [--port 8787] [--host 127.0.0.1] [--allow-remote] [--new-token] [--allow-secrets]` | MCP over Streamable HTTP at `/mcp` with a bearer token (`CRBRO_HTTP_TOKEN` or the keychain). Loopback unless `--allow-remote`; no TLS, no OAuth; `crbro_secret` is left out unless `--allow-secrets`. Some antivirus web shields (Avast's, for one) rewrite MCP traffic on loopback: exclude the port if requests fail |
373
155
 
374
- ```bash
375
- # One person, once:
376
- crbro_space action: create name: "team" remote: git@github.com:acme/team-memory.git author: "ana"
377
- crbro_share neuron: "project_x" space: "team"
156
+ **Credentials, backups, daemon**
378
157
 
379
- # Everyone else, once:
380
- crbro_space action: join name: "team" remote: git@github.com:acme/team-memory.git author: "bruno"
381
- ```
158
+ | Command | What it does |
159
+ |---|---|
160
+ | `secret set\|get\|list\|remove\|status` | Credentials in the OS keychain; the value is read from stdin, never argv ([docs/credentials.md](docs/credentials.md)) |
161
+ | `backup`, `backup list`, `backup restore FILE` | One gzipped copy of the brain, rotated; restore never lands on the live brain. `backup --keep N` sets how many to keep |
162
+ | `daemon on\|off\|status\|stop` | One process owns the brain for every client ([docs/daemon.md](docs/daemon.md)) |
382
163
 
383
- After that it is invisible: notes are exchanged at the start and end of every
384
- session. What each person learns about that project, the others' assistants
385
- know next time they sit down.
386
-
387
- **How it stays out of your way**
388
-
389
- - Nobody ever writes to anybody else's file. Each person appends to their own
390
- log and every machine rebuilds the project from all of them, so there is no
391
- conflict to resolve — not now, not after a week apart.
392
- - If someone marks a fact as no longer true, that wins. Retracted knowledge
393
- cannot come back to life because a stale copy still called it current.
394
- - A teammate who checks a shared fact against its source restarts everyone's
395
- shelf-life clock on it: the latest check wins. An explicit `shelf_life`
396
- travels too, and the most volatile one wins — a needless warning costs one
397
- check, a missing one a wrong answer — so a shared fact's shelf life can be
398
- shortened but not lengthened: the next sync restores the more volatile
399
- value from the log, and `crbro_learn` says so in `shared_warning`. A check
400
- dated more than a day in the future (a clock that is ahead) counts as no
401
- check. A teammate on an older CRBRO simply does not receive the checks.
402
- - No connection is a normal answer, not an error. Your memory works offline and
403
- whatever you saved goes out on the next sync.
404
-
405
- **What never leaves your machine**
406
-
407
- - Every project you did not explicitly share.
408
- - Preferences — not shareable at all, at any setting. They are the field most
409
- likely to hold a key.
410
- - Credentials. `crbro_share` refuses outright if it finds one, and tells you
411
- where. It will not redact it and send the rest.
412
-
413
- > **What was sent stays sent.** `crbro_share unshare:true` stops following a
414
- > project — no more notes go out and the next sync ignores it — but once a
415
- > teammate has pulled it, it is on their disk. Removing their repository
416
- > access stops anything new from reaching them; it does not take back what
417
- > they already have. That is true of any sync system — worth knowing before
418
- > you share, not after.
419
-
420
- ## Architecture
164
+ **Claude Code hooks and mod**
421
165
 
422
- ```
423
- ~/.crbro/
424
- ├── manifest.json ← Brain metadata
425
- ├── cortex/ ← One JSON per neuron (topic)
426
- │ ├── project_octochat.json
427
- │ └── tech_firebase.json
428
- ├── synapses/ ← One JSON per connection
429
- │ └── syn_octochat__firebase.json
430
- ├── hippocampus/ ← One JSON per session
431
- │ └── session_2026-05-06.json
432
- ├── prefrontal/ ← Working memory
433
- │ ├── active_context.json
434
- │ └── hot_topics.json (the global map is computed live since 2.0, never stored)
435
- ├── .quarantine/ ← What crbro_forget removed, kept until you delete it
436
- ├── unshared.json ← Projects you stopped following in a space (after an unshare)
437
- ├── archives/ ← Cold neurons (opt-in; nothing is archived unless you ask)
438
- ├── shared/ ← One git repo per team space. Notes only, never the cortex
439
- │ └── team/
440
- │ └── neurons/project_x/ops/ana.a1b2c3.jsonl
441
- └── .search/ ← Orama search index
442
- └── chunks.index.json ← one document per fact
166
+ | Command | What it does |
167
+ |---|---|
168
+ | `install-hooks --guard` | Stored lessons speak before a shell command runs. `guard "<command>"` shows what it would say |
169
+ | `install-hooks --compact` / `uninstall-hooks --compact` | Checkpoint before a compaction, picked back up after it |
170
+ | `install-hooks --inject` | Hand your protocols to spawned subagents (opt-in) |
171
+ | `install-hooks --verify` | SHA-256 of the installed hooks and mod against this package; changes nothing |
172
+ | `install-mod [--lang en\|es\|auto]` / `uninstall-mod` | The open-items band and `/pending` in Claude Code |
173
+
174
+ All of these are described in [docs/hooks.md](docs/hooks.md).
175
+
176
+ **Looking back, mining, semantic layer**
177
+
178
+ | Command | What it does |
179
+ |---|---|
180
+ | `usage [--days N] [--session ID] [--project DIR] [--json]` | Tokens per model and session from Claude Code's own logs, subagents apart. Read-only |
181
+ | `postmortem [--days N] [--max N] [--json]` | Candidate lessons from past sessions: corrections you repeated, a tool failing in a row. Stores nothing |
182
+ | `mine [dir]`, `setup-miner`, `miner-status`, `remove-miner` | Optional, fully local scan of your `.md`/`.txt` notes into the brain; "miner" means *knowledge* mining ([docs/architecture.md](docs/architecture.md)) |
183
+ | `semantic status\|install\|build` | The semantic layer's runtime, model and index ([docs/semantic-recall.md](docs/semantic-recall.md)) |
184
+
185
+ Unknown commands are rejected with a non-zero exit code instead of starting the server by accident.
186
+
187
+ ### Environment variables
188
+
189
+ Set them in the `env` block of the MCP client's config to affect that client only, or in your shell. Flags (`0`/`1`) accept the values shown.
190
+
191
+ | Variable | Default | What it does |
192
+ |---|---|---|
193
+ | `CRBRO_PATH` | `~/.crbro` | Where the brain lives. Also read by the hooks and the CLI. `CRBRO_BRAIN_PATH` is an older alias still read by the guard and subagent hooks |
194
+ | `CRBRO_SEMANTIC` | on where the runtime is installed | `0` turns the semantic layer off: recall is the keyword engine alone |
195
+ | `CRBRO_SEMANTIC_HOME` | `~/.crbro/.semantic` | Where the semantic runtime and model are kept |
196
+ | `CRBRO_SEMANTIC_MODEL` | `Xenova/multilingual-e5-small` | Embedding model (any e5-family model) |
197
+ | `CRBRO_SEMANTIC_DTYPE` | `q8` | Model quantization |
198
+ | `CRBRO_SEMANTIC_FLOOR` | built in | Cosine floor under which a vector-only candidate is dropped |
199
+ | `CRBRO_SEMANTIC_BATCH` | built in | Lines embedded per batch |
200
+ | `CRBRO_SEMANTIC_WAIT_MS` | `1500` | How long a recall waits for the semantic model before answering keyword-only (`semantic: "warming"`) |
201
+ | `CRBRO_NO_ANSWER` | on | `0` turns off `no_answer`: recall then returns its usual rows even when nothing clearly matches |
202
+ | `CRBRO_SYNONYMS` | on | `0` turns off the bilingual synonym table |
203
+ | `CRBRO_RECENCY` | on | `0` turns off the small recency lift that breaks ties toward newer entries |
204
+ | `CRBRO_IDF` | on | `0` turns off weighting query terms by rarity |
205
+ | `CRBRO_STALENESS` | on | `0` switches off shelf-life tracking and `possibly_stale` |
206
+ | `CRBRO_SHELF_DAYS` | `volatile=90,normal=365,durable=730` | Override the shelf-life windows, e.g. `volatile=60,normal=300` |
207
+ | `CRBRO_AUTOBACKUP` | on | `0` disables the daily backup made at consolidation |
208
+ | `CRBRO_BACKUP_DIR` | `<brain parent>/<brain name>-backups/brain` (`~/.crbro-backups/brain`) | Where backups go; point it at a synced folder |
209
+ | `CRBRO_KEYS_DIR` | `~/.crbro-keys` | Where the keychain file lives on platforms that use one |
210
+ | `CRBRO_KEYS_COPIES` | `5` | Sealed copies of the Windows keychain file kept in `sealed-copies/` (2–100) |
211
+ | `CRBRO_SECRET_<NAME>` | — | An environment value `crbro_secret get NAME` may return (for CI or machines with no credential store). Plain variables are never read |
212
+ | `CRBRO_SECRET_ENV` | — | Comma-separated names whose plain environment variable `crbro_secret get` may return as well |
213
+ | `CRBRO_ENCRYPT_AT_REST` | off | `1` seals backups and quarantine copies with AES-256-GCM, using a 32-byte key stored in the keychain as `CRBRO_AT_REST_KEY` (create it once, see [docs/credentials.md](docs/credentials.md)). Without the key nothing is written in clear and nothing is deleted |
214
+ | `CRBRO_DAEMON` | the brain's own flag | `1` / `0` forces daemon mode on or off for one client; see [docs/daemon.md](docs/daemon.md) |
215
+ | `CRBRO_DAEMON_IDLE_MIN` | `20` | Minutes without a conversation before a daemon exits; `0` keeps it running |
216
+ | `CRBRO_MOD` | on | `0` keeps this client from installing or updating the Claude Code mod |
217
+ | `CRBRO_LANG` | system locale | Language of the mod (`en` or `es`) when installed with `--lang auto` |
218
+ | `CRBRO_SUBAGENT_INJECT` | off | `full` makes the subagent hook inject the protocol block |
219
+ | `CRBRO_SUBAGENT_MATCHER` | — | Regex that scopes the subagent hook to some subagent types |
220
+ | `CRBRO_STARTUP_TRACE` | off | `1` traces the startup steps, with timings, to stderr and `<brain>/.daemon/startup-trace.log` |
221
+ | `CRBRO_QUARANTINE_DAYS` | `180` | Days `.quarantine/` keeps the copies taken before a forget, merge, compact or repair; `0` keeps them forever |
222
+ | `CRBRO_ENGINE_DIR` | `~/.crbro-engine` | Where `install` keeps the engine the clients run |
223
+ | `CRBRO_HOOK_REFRESH` | on | `0` stops a newer release from refreshing the hook copies it installed earlier |
224
+ | `CRBRO_GUARD_ORIGINS` | own | `all` lets the guard also speak lessons from team spaces and the miner (labelled) |
225
+ | `CRBRO_CODEX_HOOK` | on | `0` silences the packaged Codex boot hook |
226
+ | `CRBRO_HTTP_TOKEN` | — | Bearer token for `serve --http` (else read from the keychain under the same name) |
227
+ | `CLAUDE_CONFIG_DIR` | `~/.claude` | Where the hooks and the mod are installed, if you moved Claude Code's folder |
228
+ | `CODEX_HOME` | `~/.codex` | Same, for Codex |
229
+ | `CLAUDE_CODE_PLUGIN_DIRS` | — | Read and extended (never replaced) by the mod installer |
230
+ | `NODE_USE_SYSTEM_CA` | — | Node's own switch: trust the system certificate store (see [Troubleshooting](#npx-fails-with-unable_to_verify_leaf_signature)) |
231
+
232
+
233
+ ### More documentation
234
+
235
+ | | |
236
+ |---|---|
237
+ | [docs/features.md](docs/features.md) | The full feature list, version by version |
238
+ | [docs/hooks.md](docs/hooks.md) | Guard, compaction checkpoint, subagent hook, open-items mod |
239
+ | [docs/daemon.md](docs/daemon.md) | One process for every client |
240
+ | [docs/semantic-recall.md](docs/semantic-recall.md) | The embedding layer, and measuring retrieval on your own queries |
241
+ | [docs/credentials.md](docs/credentials.md) | The keychain and the `secret` command |
242
+ | [docs/team-memory.md](docs/team-memory.md) | Spaces: sharing projects through a git repo you own |
243
+ | [docs/architecture.md](docs/architecture.md) | What is on disk, the heat score, the miner |
244
+ | [docs/privacy.md](docs/privacy.md) | Exactly which data flows can touch the network |
245
+ | [docs/doctor.md](docs/doctor.md) | What `doctor` reports and what it never does |
246
+ | [docs/upgrading-from-1x.md](docs/upgrading-from-1x.md) | The 23 → 15 tools change |
247
+ | [docs/releasing.md](docs/releasing.md) | How releases are made (for maintainers) |
248
+ | [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md), [CHANGELOG.md](CHANGELOG.md) | |
249
+
250
+ ---
251
+
252
+ ## 3. Measurements
253
+
254
+ Every number about cost and quality comes from a script in [`benchmarks/`](https://github.com/Octonove/crbro-memory/tree/master/benchmarks) that you can run yourself. The unflattering results are published on purpose, and what the benchmarks deliberately do **not** claim — human productivity, "it knows you", comparisons against other memory systems — is in [`benchmarks/LIMITS.md`](https://github.com/Octonove/crbro-memory/blob/master/benchmarks/LIMITS.md).
255
+
256
+ **What runs in CI** on every push: the lexical retrieval benchmark (keyword engine alone, no model, no network) and the credential-redaction benchmark, both as gates that fail the build if they regress (`npm run bench`), plus the unit and integration test suite on Linux, Windows and macOS. Everything else below is run by hand, with the version and date next to it. The agentic benchmark puts a real Claude Code agent to work and spends tokens, so it is never run in CI.
257
+
258
+ Measured for **2.11.0 on 14-11-2026**, on Windows 11 with Node 24. "Real brain" means a copy of one person's brain (563 neurons, 9 MB of neurons, 146 day logs, semantic layer installed); the 2.10.0 figure next to each is the same measurement on the same copy.
259
+
260
+ | What | Result | How to reproduce |
261
+ |---|---|---|
262
+ | **Cost: `tools/list`** (what an MCP client that loads every tool pays on each request) | **29,802 characters** (≈7,500 tokens) for the 15 tools, 2,918 of them output schemas. 2.10.0: 44,434 | `node benchmarks/cost/context.mjs` |
263
+ | **Cost: `crbro_boot`** (paid once per session) | **9,973 characters** on the real brain (2.10.0: 21,704); 9,529 on the 503-neuron synthetic brain of `context.mjs` | `node benchmarks/cost/context.mjs` |
264
+ | **Cost: `crbro_recall`** (per search, default five results) | **~7,700–8,800 characters** for five results, plus the same as `structuredContent` (2.10.0: ~13,000). A question with nothing clearly stored behind it comes back flagged `no_answer` with at most three weak rows: 5,147 characters for one on the real brain, where 2.10.0 returned five rows and 13,205 characters | `node benchmarks/cost/context.mjs` |
265
+ | **Cost: `crbro_context`** | A read: 21,318 characters (unchanged on purpose: it is the door to everything pending). A write (`add_pending` and the like) now answers in ~430 characters instead of ~22,000 | `node benchmarks/cost/context.mjs` |
266
+ | **Retrieval, keyword engine alone** (blind paraphrased queries; the CI gate) | **recall@1 83 %, recall@3 90 %, MRR 0.865** on 48 blind paraphrased queries (2.10.0: 77 %, 83 %, 0.806). The CI gate's floor is 40/48, 42/48 and 0.85 | `node benchmarks/retrieval/run.mjs` |
267
+ | **Retrieval, semantic layer on** | **recall@1 85 %, recall@3 88 %, MRR 0.865** (2.10.0: 75 %, 81 %, 0.781). On the real brain a search takes ~140–220 ms with the layer on, ~60 ms keyword-only | `CRBRO_SEMANTIC=1 node benchmarks/retrieval/run.mjs` |
268
+ | **Retrieval, Spanish** (accents, hyphenated compounds, questions with no answer) | 29 answerable questions: **recall@1 25, recall@3 25** (2.10.0: 18, 21). Accents 17/17, hyphenated compounds 4/4, long entries answered with the part that matched 3/3; 5 of 8 unanswerable questions flagged `no_answer` (2.10.0: 0). On the real brain, `diseño` now finds 105 neurons (2.10.0: 14), `título` 99 (17), `categoría` 77 (16), `España` 72 (6) | `node benchmarks/retrieval/run.mjs` (see its README) |
269
+ | **False confidence** (questions about things that are not stored) | Keyword engine: 1 of 14 distractors reaches a real hit's score (2.10.0: 2). Semantic layer on: 0 of 14 | `node benchmarks/retrieval/run.mjs` |
270
+ | **Secret redaction** (adversarial credentials and near-miss innocents; the CI gate) | **24/24 caught, 0/28 false positives**, counted per value: a case is caught only if every secret value in it is gone | `node benchmarks/security/run.mjs` |
271
+ | **Startup** (client connected until the first tool answers; with and without the daemon) | Real brain. Without the daemon: `initialize` ~0.28 s, `crbro_boot` ~0.9–1.4 s, first recall ~0.2 s. With the daemon warm: `initialize` 69 ms, `crbro_boot` 37 ms. With the daemon to be started: `initialize` 103 ms (2.10.0: 625 ms), first boot ~1.7 s | `node benchmarks/daemon/startup.mjs` |
272
+ | **Memory use** (RAM per client, with and without the daemon) | Without the daemon, one full engine per client: ~1 GB with the semantic model loaded, ~530 MB keyword-only (2.10.0: ~700 MB). With the daemon: ~62 MB per client plus one daemon (~0.8–1 GB) | `node benchmarks/daemon/startup.mjs` |
273
+ | **Disk** (semantic layer: runtime and model) | ~500 MB in `~/.crbro/.semantic` (runtime and model, downloaded once by `semantic install`) | `npx crbro-memory semantic status` |
274
+ | **First boot after upgrading** (the search index rebuilds once) | **9.7 s** on the real brain (563 neurons): the index rebuilds once in the new format. The semantic vectors of long entries, now split into parts, then fill in the background (~5,500 of them, about 4 minutes here); meanwhile recall stays at 0.05–0.4 s and answers keyword-only (`semantic: "warming"`) | — |
275
+ | **Tests** | **105 files, 1,324 passed, 6 skipped** on Windows 11; CI runs the suite on Linux, Windows and macOS with Node 20, 22 and 24 | `npx vitest run` |
276
+ | **A fresh session does not ask again** (agentic; haiku and sonnet) | Not re-run for 2.11: the 2.7.2 result stands, with its caveats, in [docs/measurements-2.7.2.md](docs/measurements-2.7.2.md) | `node benchmarks/agentic/run.mjs` |
277
+
278
+ The figures published for 2.7.2 (retrieval, scale, false confidence, the agentic runs and the two stale-value experiments that did **not** meet their pre-registered claim) are kept, dated and with their caveats, in [docs/measurements-2.7.2.md](docs/measurements-2.7.2.md). They have not been re-measured for 2.11.
279
+
280
+ ---
281
+
282
+ ## Troubleshooting and FAQ
283
+
284
+ ### CRBRO does not remember anything
285
+
286
+ Almost always the memory is asleep, not broken: the boot step is not wired, so the assistant never reads the brain. Run `npx crbro-memory doctor`, then `npx crbro-memory install-boot` (or `install`), restart the client and open a *new* conversation. Check that `crbro_boot` ran and returned a neuron count. If you have to call it by hand, the step did not take. If the server was registered inside one project instead of at the user level, other folders do not have the tools: register it with `--scope user`.
287
+
288
+ ### Codex says the MCP server timed out at startup
289
+
290
+ Codex starts MCP servers when a session opens and waits only a short default time. A first start through `npx` also downloads the package. Give the server more time in `~/.codex/config.toml`:
291
+
292
+ ```toml
293
+ [mcp_servers.crbro]
294
+ command = "npx"
295
+ args = ["-y", "crbro-memory"]
296
+ startup_timeout_sec = 60
297
+ tool_timeout_sec = 120
443
298
  ```
444
299
 
445
- ## Heat Score Algorithm
300
+ `npx crbro-memory install` writes these for you. The server answers `initialize` and `tools/list` at once, before it has loaded the brain, so a Codex that still times out is waiting on `npx` itself: install once with `npm install -g crbro-memory` and use `crbro-memory` as the command, or let `install` keep the engine in a stable folder. `CRBRO_STARTUP_TRACE=1` in the server's env prints where the time goes.
446
301
 
447
- Each neuron has a heat score (0.0 - 1.0) calculated from:
302
+ ### Two daemons are running
448
303
 
449
- - **Frequency (35%)** — How often the neuron is accessed
450
- - **Recency (40%)** — When it was last accessed (today = 1.0, >3 months = 0.05)
451
- - **Connectivity (25%)** — How many synapses connect to it
304
+ Daemon mode is one process per *version* of CRBRO: after an upgrade, a client on the new version starts its own daemon and the old one exits by itself after 20 idle minutes (`CRBRO_DAEMON_IDLE_MIN`). Until then two are alive, and that is expected. `npx crbro-memory daemon status` lists them, `daemon stop` stops a daemon, and `doctor` flags leftovers of dead daemons. Never kill the process by hand while a client is mid-conversation; the client falls back to serving itself and carries on.
452
305
 
453
- ## Knowledge Miner
306
+ ### The first start after upgrading is slow
454
307
 
455
- 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.
308
+ 2.11 reads words with accents (á, í, ú, ñ, ü) and hyphenated compounds differently, so the search index is rebuilt once the first time a brain is opened. How long depends on the size of the brain; it does not happen again. Do not interrupt it. The semantic layer, if installed, is not re-embedded.
456
309
 
457
- ```bash
458
- npx crbro-memory mine [dir] # One-shot scan of a directory
459
- npx crbro-memory setup-miner # Install a scheduled auto-scan (OS task scheduler)
460
- npx crbro-memory miner-status # Check the auto-miner status
461
- npx crbro-memory remove-miner # Remove the scheduled task
462
- ```
310
+ ### The keychain is missing or locked
463
311
 
464
- > Naming note: "miner" here means *knowledge* mining — extracting facts from your own text files. Nothing to do with cryptocurrency.
312
+ `npx crbro-memory secret status` says which store this machine offers: Keychain on macOS (`security`), Secret Service on Linux (`secret-tool`, which needs a running D-Bus session), a DPAPI-sealed file on Windows. On a headless server, a CI runner or an SSH session with a locked keychain, `crbro_secret` says so in plain words instead of failing; use `CRBRO_SECRET_<NAME>` environment variables there. A missing keychain file is reported as missing, never treated as an empty keychain: if you moved or deleted `~/.crbro-keys`, restore it from your own backup before storing anything new. See [docs/credentials.md](docs/credentials.md).
465
313
 
466
- ## CLI Commands
314
+ ### `npx` fails with `UNABLE_TO_VERIFY_LEAF_SIGNATURE`
467
315
 
468
- ```bash
469
- npx crbro-memory # Start MCP server (stdio)
470
- npx crbro-memory init # Initialize brain + detect IDEs
471
- npx crbro-memory install-boot # Make the memory load itself in every conversation (above)
472
- npx crbro-memory status # Show brain status
473
- npx crbro-memory reindex # Rebuild the search index
474
- npx crbro-memory eval # Measure retrieval quality against your own query set
475
- npx crbro-memory semantic status | install | build # Semantic recall (installed by init; below)
476
- npx crbro-memory secret set|get|list|remove|status # Credentials in the OS keychain (above)
477
- npx crbro-memory backup | backup list | backup restore FILE # One gzipped copy, rotated; restore never lands on the live brain
478
- npx crbro-memory daemon on | off | status | stop # One process owns the brain for every client (above)
479
- npx crbro-memory install-hooks --guard # Stored lessons speak before a shell command runs (above)
480
- npx crbro-memory install-hooks --compact # Checkpoint before a compaction, picked back up after it (above)
481
- npx crbro-memory guard "<command>" # What the guard would say for a command
482
- npx crbro-memory install-hooks --verify # SHA-256 of the installed hooks and mod against this package; changes nothing
483
- npx crbro-memory install-mod [--lang en|es|auto] # Open items above the prompt and /pending in Claude Code (above)
484
- npx crbro-memory uninstall-mod # Remove that mod and its CLAUDE_CODE_PLUGIN_DIRS entry
485
- npx crbro-memory usage [--days N] [--session ID] [--project DIR] [--json] # Tokens per model and session, subagents apart
486
- npx crbro-memory postmortem [--days N] [--max N] [--json] # Candidate lessons from past sessions; stores nothing
487
- npx crbro-memory --help # Help
488
- ```
316
+ An antivirus or corporate proxy is inspecting HTTPS (Avast and AVG "Web Shield", Kaspersky, Zscaler…): it re-signs every connection with its own root, which your operating system trusts and Node.js does not. Tell Node to trust the system store — it turns no check off: `setx NODE_USE_SYSTEM_CA 1` on Windows (then open a new terminal), `export NODE_USE_SYSTEM_CA=1` elsewhere; Node 22.15+. For one MCP client only, put it in that server's `env`. Never "fix" this with `strict-ssl=false` or `NODE_TLS_REJECT_UNAUTHORIZED=0`: those turn verification off for everything.
489
317
 
490
- ### Semantic recall
318
+ ### Where does the memory live?
491
319
 
492
- 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 on a small brain and a lot more on a big one. 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.
320
+ | What | Where |
321
+ |---|---|
322
+ | The brain (readable JSON) | `~/.crbro`, or `CRBRO_PATH`. Neurons in `cortex/`, connections in `synapses/`, session logs in `hippocampus/`, the search index in `.search/`. Layout: [docs/architecture.md](docs/architecture.md) |
323
+ | What `crbro_forget` removed | `<brain>/.quarantine/` until its retention runs out |
324
+ | Backups | `~/.crbro-backups/brain`, or `CRBRO_BACKUP_DIR` |
325
+ | The semantic runtime and model | `~/.crbro/.semantic`, or `CRBRO_SEMANTIC_HOME` |
326
+ | Credentials | The OS keychain (Windows: `~/.crbro-keys`, sealed with DPAPI). Never inside the brain, never in backups |
327
+ | Hooks and the mod | `~/.claude/settings.json`, `~/.claude/crbro-mods/`, `~/.codex/hooks.json` (and the `CLAUDE_CONFIG_DIR` / `CODEX_HOME` equivalents) |
328
+ | Team spaces | `<brain>/shared/<space>`, one git repo each |
329
+
330
+ ### Complete uninstall
331
+
332
+ The one-command way, which lists everything first and removes only what CRBRO itself wrote:
493
333
 
494
334
  ```bash
495
- npx crbro-memory init # installs it (skip with --no-semantic)
496
- npx crbro-memory semantic status # runtime, model, on or off, and why
497
- npx crbro-memory semantic build # embed an existing brain once (a 4k-line brain: ~3 min in batches; 2.7.2 embeds one line at a time, 1.6x that)
335
+ npx crbro-memory uninstall --dry-run # what it would remove
336
+ npx crbro-memory uninstall
498
337
  ```
499
338
 
500
- 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.
339
+ It removes the registrations that run CRBRO in every client it finds, its hooks and boot wiring, the Claude Code mod and the engine folder `install` created. It keeps the backup of every file it edits, and it never touches the brain, your backups or the keychain: it prints where they are, and there is no flag that deletes them. That last step is yours (item 7 below).
501
340
 
502
- 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 scored the same or worse when measured in 1.16 (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).
341
+ By hand, or to check that nothing is left, in this order:
503
342
 
504
- 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.
343
+ 1. **Stop the daemon:** `npx crbro-memory daemon off`, then `daemon stop`.
344
+ 2. **Unregister the server** from each client: `claude mcp remove crbro --scope user`; delete the `crbro` entry from Claude Desktop's `claude_desktop_config.json`, from `~/.cursor/mcp.json` and the `[mcp_servers.crbro]` table of `~/.codex/config.toml`. Uninstall the Claude Desktop extension from its settings if you used the `.mcpb`.
345
+ 3. **Remove the hooks:** `npx crbro-memory uninstall-hooks --compact` and delete any remaining entry naming `crbro` from `~/.claude/settings.json` (`SessionStart`, `PreCompact`, `PreToolUse`, `SubagentStart`) and from `~/.codex/hooks.json`. `npx crbro-memory install-hooks --verify` shows what is still installed.
346
+ 4. **Remove the Claude Code mod:** `npx crbro-memory uninstall-mod`.
347
+ 5. **Remove the scheduled miner**, if you set it up: `npx crbro-memory remove-miner`.
348
+ 6. **Remove credentials** you stored: `npx crbro-memory secret list`, then `secret remove NAME --yes` for each. Deleting the brain does *not* delete keychain entries.
349
+ 7. **Delete the data**, only if you want the memory gone for good: `~/.crbro` (brain, quarantine and semantic model), `~/.crbro-backups`, `~/.crbro-keys`, and the engine folder that `install` created, if any (`uninstall --dry-run` names it).
350
+ 8. Copies you shared with a team space stay on your teammates' disks and in the git remote.
505
351
 
506
- ### Measuring retrieval
352
+ ### What does it send over the network?
507
353
 
508
- `eval` is there so you can tell a fix from a feeling. Write
509
- `~/.crbro/.eval/queries.json` as a list of questions you would actually ask,
510
- each naming the neuron that should answer it:
354
+ Nothing to us, ever: there is no account, no telemetry. The optional semantic layer downloads a model once; team sync pushes only the projects you explicitly share, to a git remote you own; and what a tool returns is read by your AI client. [docs/privacy.md](docs/privacy.md) lists each flow.
511
355
 
512
- ```json
513
- [
514
- { "query": "how we deploy the api",
515
- "expect_neuron": "project_octochat",
516
- "expect_contains": "Cloud Run" }
517
- ]
518
- ```
356
+ ---
357
+
358
+ ## Contributing and support
519
359
 
520
- Then `npx crbro-memory eval` reports how often the right neuron comes back
521
- first, how often it makes the top three, and MRR — plus every miss, so you can
522
- see what it got wrong instead of guessing.
523
-
524
- ## Privacy
525
-
526
- Everything CRBRO knows lives in plain JSON files on your machine, under
527
- `~/.crbro` or the folder you point it at. You can open them, diff them, back
528
- them up with git and delete them. There is no account, no server of ours, no
529
- telemetry and no analytics: nothing is sent to the author, ever, and the
530
- server has no code that would.
531
-
532
- Three things do touch the network, all of them started by you and none of
533
- them on by default:
534
-
535
- - **The optional semantic layer.** `npx crbro-memory init` (or
536
- `semantic install`) downloads an embedding model from Hugging Face into
537
- `~/.crbro/.semantic`, about 500 MB, once per machine. Skip it with
538
- `init --no-semantic` and recall stays keyword-only. The desktop extension
539
- never downloads it.
540
- - **Team spaces.** If you run `crbro_space` with a git remote you own, the
541
- projects you explicitly share with `crbro_share` are pushed there. Nothing
542
- else leaves: preferences are excluded from sharing and sync by design, and
543
- a project is shared only when you name it.
544
- - **Your MCP client.** Whatever a tool returns is read by the assistant you
545
- are talking to, which is how it can use your memory at all. That traffic is
546
- between you and your client, not us.
547
-
548
- Anything that looks like a credential is replaced with a marker before it
549
- reaches disk, and the sentence around it survives; `crbro_secret` puts the
550
- real value in your operating system's own keychain instead of the brain. To
551
- erase everything, delete the folder. To see what is stored about any topic,
552
- read its file or call `crbro_inspect`.
553
-
554
- `crbro usage` and `crbro postmortem` read Claude Code's own session logs in
555
- `~/.claude/projects`, locally and read-only: `usage` reads only the model name
556
- and token counts of each response, `postmortem` only what you typed and the
557
- names of the tools called — never a tool's input or output — and redacts what
558
- it prints.
559
-
560
- The one thing CRBRO writes in Claude Code's folder without being asked is the
561
- open-items mod: `~/.claude/crbro-mods/` (the mod itself, a `state.json` with
562
- the opt-out mark and the installed version, a lock held for the seconds an
563
- install takes, and a notice kept until the boots that hand it over have had
564
- it) and its one entry in `env.CLAUDE_CODE_PLUGIN_DIRS` of
565
- `~/.claude/settings.json`. No other key in that file is changed; it is
566
- rewritten as JSON with its indentation and line endings (on Windows the new
567
- file takes the folder's permissions). Nothing is downloaded or sent, and none
568
- of it happens without `~/.claude`, in a client with `CRBRO_MOD=0`, or after
569
- `uninstall-mod`.
570
-
571
- What each defense is for, and how to report a vulnerability, is in
572
- [SECURITY.md](https://github.com/Octonove/crbro-memory/blob/master/SECURITY.md).
360
+ Bug reports and pull requests are welcome: see [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities as described in [SECURITY.md](https://github.com/Octonove/crbro-memory/blob/master/SECURITY.md).
361
+
362
+ > ⭐ **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.**
363
+
364
+ <!-- invokard-coffee -->
365
+ **&#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)
366
+
367
+ 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.
368
+
369
+ | Network | USDC address |
370
+ |---|---|
371
+ | **Solana** | `5n6Gfosk7SdwbvdtE9xiLWpcGPBBBGDZYRfAkWyCk86g` |
372
+ | **Ethereum** (ERC-20) | `0xe176866f9d7fdb498e0d4a983d3e34d84dcd6bfc` |
573
373
 
574
374
  ## License
575
375