crbro-memory 1.14.0 โ†’ 1.16.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.
package/README.md CHANGED
@@ -16,7 +16,8 @@ Free and open source (MIT). All 23 tools included โ€” no license, no account, no
16
16
 
17
17
  - **๐Ÿงฌ Biological Architecture** โ€” Knowledge organized as neurons (cortex), connections (synapses), and session memory (hippocampus)
18
18
  - **๐Ÿ” 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+)*
19
- - **๐Ÿงญ Semantic layer, opt-in** โ€” Two commands and one env var add a local embedding model (`multilingual-e5-small`, int8) fused with the keyword engine: paraphrases the words do not cover start to land. Measured +8 points of recall@1 on the blind benchmark; ~500 MB on disk, never installed or loaded unless you ask *(v1.14+)*
19
+ - **๐Ÿ—ฃ๏ธ 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+)*
20
+ - **๐Ÿงญ Semantic recall** โ€” `npx crbro-memory init` installs a local embedding model (`multilingual-e5-small`, int8) fused with the keyword engine, so paraphrases the words do not cover start to land. Measured: +8 points of recall@1 over the keyword engine, +2 to +5 on top of save-time keywords. Costs ~500 MB on disk once per machine and ~0.5 GB of RAM while a server runs; `init --no-semantic` skips it, `CRBRO_SEMANTIC=0` turns it off *(v1.14+, installed by default since v1.16)*
20
21
  - **๐Ÿ”ฅ 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+)*
21
22
  - **โœ๏ธ Correctable** โ€” Knowledge can be superseded or retracted, not just piled up. A memory that only appends keeps serving yesterday's answer with today's confidence
22
23
  - **๐Ÿ” 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
@@ -28,7 +29,7 @@ Free and open source (MIT). All 23 tools included โ€” no license, no account, no
28
29
  - **๐Ÿท๏ธ 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+)*
29
30
  - **๐Ÿ›ก๏ธ 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
30
31
  - **โ›๏ธ Knowledge Miner** โ€” Optionally scans your local `.md`/`.txt` notes and feeds them into the brain
31
- - **๐Ÿ”’ Fully Local** โ€” Runs on Node.js alone: no Python, no Docker, no databases, no external services. Your memory never leaves your machine
32
+ - **๐Ÿ”’ 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
32
33
  - **๐Ÿ’พ File-Based** โ€” All data stored as readable JSON files in `~/.crbro/` โ€” inspectable, diffable, and versionable with git
33
34
  - **๐Ÿ”Œ MCP Native** โ€” Works with Claude Desktop, Claude Code, Cursor, Windsurf, and any MCP-compatible client
34
35
 
@@ -39,7 +40,8 @@ Every number below comes from a deterministic benchmark in [`benchmarks/`](bench
39
40
  | What | Result | The honest part |
40
41
  |------|--------|-----------------|
41
42
  | **Retrieval** (48 blind paraphrased queries, written by someone who never saw the stored text) | recall@1 **71%** ยท recall@3 **77%** ยท MRR 0.74 โ€” and **79% / 85%** counting the neuron's `also_matched` lines | Was 56% / 69% in 1.12. Of the 13 misses, 8 were the *right neuron answering with the wrong line* (its name chunk, or a sibling fact) โ€” fixed in the engine; the rest are vocabulary gaps, which a short bilingual synonym table now closes in part. A naive substring search scores 38% / 58%. Still no semantic model: the remaining misses are listed in the benchmark output |
42
- | **Retrieval with the opt-in semantic layer** (same 48 queries, `CRBRO_SEMANTIC=1`) | recall@1 **79%** ยท recall@3 **83%** ยท MRR 0.81 โ€” **88% / 92%** counting `also_matched` | Vectors from `multilingual-e5-small` (int8) fused with BM25 by reciprocal rank. Alone, the model scores 60% / 83%; fused, it adds 8 points at recall@1 and no distractor reaches a real hit's score (0 of 14; 12 return something, 11 of them labelled `weak`). The cosine floor under which a vector-only candidate is dropped (0.84) was picked on this same set โ€” a tuned number, not a blind one. Costs ~500 MB on disk, a one-time embedding pass (~18 ms per line) and ~13 s of model load per process. Off by default *(v1.14+)* |
43
+ | **Retrieval with the semantic layer** (same 48 queries) | recall@1 **79%** ยท recall@3 **83%** ยท MRR 0.81 โ€” **88% / 92%** counting `also_matched` | Vectors from `multilingual-e5-small` (int8) fused with BM25 by reciprocal rank. Alone, the model scores 60% / 83%; fused, it adds 8 points at recall@1 and no distractor reaches a real hit's score (0 of 14; 12 return something, 11 of them labelled `weak`). The cosine floor under which a vector-only candidate is dropped (0.84) was picked on this same set โ€” a tuned number, not a blind one. Costs ~500 MB on disk, ~0.5 GB of RAM while the server runs, a one-time embedding pass (~3 min for a 4k-line brain) and ~13 s of model load per process. Installed by `init` since 1.16; `CRBRO_SEMANTIC=0` turns it off *(v1.14+)* |
44
+ | **Retrieval with the model in the loop** (same 48 queries; keywords and rewrites written blind by a model that saw only one half of the test) | keywords alone: recall@1 **83%** ยท recall@3 **90%** โ€” everything on (keywords + rewrites + semantic layer): **90% / 92%**, and **96% / 98%** counting `also_matched` | The biggest lever costs nothing: 2-5 keywords written when a fact is saved close exactly the gaps no embedding model closed. Rewrites alone barely move the keyword engine (71% โ†’ 71% / 79%); they add up on top of keywords. Every configuration and the three questions still missed are in [`benchmarks/README.md`](benchmarks/README.md) *(v1.15+)* |
43
45
  | **Retrieval โ€” false confidence** (14 questions about things that are NOT stored) | 11 return *something*; **2** at a real hit's score; **10 of 11** labelled `weak` | A keyword memory answers almost anything. Every result now carries `confidence`, and the label catches nearly every distractor โ€” at the price of also calling 18 of 48 real hits weak. Weak means "little of the question was covered", not "wrong" |
44
46
  | **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 |
45
47
  | **Cost** (what CRBRO adds to a session) | ~**750 tokens** at boot ยท **~5.4k tokens** of tool definitions ยท **<1 ms** local recall over 300 facts | The boot block is paid once. The 23 tool definitions 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. 1.12 measured 6.3k and did not say so |
@@ -50,6 +52,8 @@ What these benchmarks deliberately do **not** claim โ€” human productivity, "it
50
52
 
51
53
  ### 1. Initialize
52
54
 
55
+ 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.
56
+
53
57
  ```bash
54
58
  npx crbro-memory init
55
59
  ```
@@ -91,7 +95,7 @@ claude mcp add --scope user crbro -- npx -y crbro-memory
91
95
  }
92
96
  ```
93
97
 
94
- **Docker** (the brain lives in `/root/.crbro`; mount a volume to keep it):
98
+ **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):
95
99
  ```bash
96
100
  docker build -t crbro-memory . && docker run -i -v crbro-brain:/root/.crbro crbro-memory
97
101
  ```
@@ -116,10 +120,10 @@ Session context never reaches Task-spawned subagents, so this hook can inject th
116
120
  |------|-------------|
117
121
  | `crbro_boot` | Boot the brain at session start โ€” loads hot topics and context |
118
122
  | `crbro_status` | Brain status โ€” neurons, synapses, sessions count |
119
- | `crbro_learn` | Store a fact, decision, pattern, preference, error or debt |
123
+ | `crbro_learn` | Store a fact, decision, pattern, preference, error or debt โ€” with the keywords a future question may use |
120
124
  | `crbro_neuron` | Read a specific neuron (topic) with all its knowledge |
121
125
  | `crbro_neurons` | List neurons with optional filters (domain, type, heat) |
122
- | `crbro_recall` | Search every stored line, not just topic names โ€” returns what matched, how confidently, and the topic's next best lines |
126
+ | `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 |
123
127
  | `crbro_connect` | Create or strengthen a connection between neurons |
124
128
  | `crbro_connections` | Get all connections for a neuron |
125
129
  | `crbro_session_log` | Log a session summary |
@@ -269,21 +273,23 @@ npx crbro-memory init # Initialize brain + detect IDEs
269
273
  npx crbro-memory status # Show brain status
270
274
  npx crbro-memory reindex # Rebuild the search index
271
275
  npx crbro-memory eval # Measure retrieval quality against your own query set
272
- npx crbro-memory semantic install | build | status # The opt-in semantic layer (below)
276
+ npx crbro-memory semantic status | install | build # Semantic recall (installed by init; below)
273
277
  npx crbro-memory --help # Help
274
278
  ```
275
279
 
276
- ### Semantic search (opt-in)
280
+ ### Semantic recall
277
281
 
278
- The keyword engine has no synonyms, and the blind benchmark shows exactly where that bites: after the 1.13 ranking fixes, the misses left are paraphrases โ€” *"where are the sites hosted"* for a fact about a Hetzner VPS. A small embedding model closes part of that gap. It is opt-in and stays so: the runtime (transformers.js + onnxruntime) is ~380 MB, the model 118 MB, and a cold load takes ~13 s per process โ€” none of which most users should pay by default.
282
+ The keyword engine has no synonyms, and the blind benchmark shows exactly where that bites: paraphrases โ€” *"where are the sites hosted"* for a fact about a Hetzner VPS. Keywords written at save time close most of that gap for free (above); a small embedding model closes a little more. Since 1.16 `npx crbro-memory init` installs it by default, once per machine, and the layer is on wherever its runtime is present. What it costs, measured: ~500 MB on disk (runtime ~380 MB + model 118 MB), ~0.5 GB of RAM while a server runs, ~13 s of model load per process (in the background) and a one-time embedding pass. Skip it with `init --no-semantic`; turn it off any time with `CRBRO_SEMANTIC=0` in the server's env.
279
283
 
280
284
  ```bash
281
- npx crbro-memory semantic install # once per machine โ†’ ~/.crbro/.semantic
282
- # then add CRBRO_SEMANTIC=1 to the crbro server's env in your MCP client config
283
- npx crbro-memory semantic build # once: embeds every line of the brain (~18 ms each)
285
+ npx crbro-memory init # installs it (skip with --no-semantic)
286
+ npx crbro-memory semantic status # runtime, model, on or off, and why
287
+ npx crbro-memory semantic build # embed an existing brain once (a 4k-line brain: ~3 min)
284
288
  ```
285
289
 
286
- From then on 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. Set `CRBRO_SEMANTIC=0` (or just unset it) and the layer disappears: no vectors are read, no model is loaded, recall is the 1.13 engine byte for byte.
290
+ 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.
291
+
292
+ The model is `multilingual-e5-small` and stays so on purpose. `CRBRO_SEMANTIC_MODEL` accepts any e5-family model, and `e5-base` and `e5-large` were measured on the same benchmark: the large one is the better model alone (71% vs 63% recall@1) but fused with the keyword engine it scores the same or worse (75% / 85% vs 79% / 83%) for 4ร— the disk, 1.2 GB of RAM and 6ร— the time per line. The table is in [`benchmarks/README.md`](benchmarks/README.md).
287
293
 
288
294
  What it buys on the frozen benchmark, and what it does not, is in the table above and in [`benchmarks/README.md`](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.
289
295