crbro-memory 2.7.2 → 2.9.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 +66 -7
- package/SECURITY.md +36 -0
- package/bin/crbro.mjs +1437 -1366
- package/dist/daemon/endpoint.d.ts.map +1 -1
- package/dist/daemon/endpoint.js +18 -0
- package/dist/daemon/endpoint.js.map +1 -1
- package/dist/engine/brain.d.ts.map +1 -1
- package/dist/engine/brain.js +30 -0
- package/dist/engine/brain.js.map +1 -1
- package/dist/engine/cortex.d.ts +55 -1
- package/dist/engine/cortex.d.ts.map +1 -1
- package/dist/engine/cortex.js +183 -3
- package/dist/engine/cortex.js.map +1 -1
- package/dist/engine/maintenance.d.ts +22 -0
- package/dist/engine/maintenance.d.ts.map +1 -1
- package/dist/engine/maintenance.js +59 -2
- package/dist/engine/maintenance.js.map +1 -1
- package/dist/engine/modinstall.d.ts +215 -0
- package/dist/engine/modinstall.d.ts.map +1 -0
- package/dist/engine/modinstall.js +1342 -0
- package/dist/engine/modinstall.js.map +1 -0
- package/dist/engine/shelf.d.ts +97 -0
- package/dist/engine/shelf.d.ts.map +1 -0
- package/dist/engine/shelf.js +343 -0
- package/dist/engine/shelf.js.map +1 -0
- package/dist/engine/source.d.ts +6 -0
- package/dist/engine/source.d.ts.map +1 -0
- package/dist/engine/source.js +101 -0
- package/dist/engine/source.js.map +1 -0
- package/dist/search/index.d.ts +6 -0
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +46 -1
- package/dist/search/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +226 -33
- package/dist/server.js.map +1 -1
- package/dist/sync/materialize.d.ts +4 -0
- package/dist/sync/materialize.d.ts.map +1 -1
- package/dist/sync/materialize.js +80 -1
- package/dist/sync/materialize.js.map +1 -1
- package/dist/sync/ops.d.ts +29 -2
- package/dist/sync/ops.d.ts.map +1 -1
- package/dist/sync/ops.js.map +1 -1
- package/dist/sync/space.d.ts.map +1 -1
- package/dist/sync/space.js +15 -2
- package/dist/sync/space.js.map +1 -1
- package/dist/types/index.d.ts +47 -0
- package/dist/types/index.d.ts.map +1 -1
- package/mods/crbro-pending/.claude-plugin/plugin.json +21 -0
- package/mods/crbro-pending/hooks/hooks.json +1 -0
- package/mods/crbro-pending/hooks/register.tsx +576 -0
- package/mods/crbro-pending/hooks/strings.ts +200 -0
- package/mods/crbro-pending/types/index.d.ts +27 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
**CRBRO** is a local MCP (Model Context Protocol) server that gives your AI assistant **persistent long-term memory** across sessions. It uses a biological neural architecture — cortex, synapses, hippocampus — to store, connect, and retrieve knowledge automatically.
|
|
11
11
|
|
|
12
|
-

|
|
13
13
|
|
|
14
14
|
Free and open source (MIT). All 15 tools included — no license, no account, no tiers.
|
|
15
15
|
|
|
@@ -35,6 +35,7 @@ Or in USDC. Send **USDC only** and **only on the network shown**; on any other n
|
|
|
35
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
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
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. 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: non-volatile lines written before the first boot of this version start counting near that boot, staggered so they do not all come due on the same day, 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 *(unreleased)*
|
|
38
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+)*
|
|
39
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+)*
|
|
40
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
|
|
@@ -49,6 +50,7 @@ Or in USDC. Send **USDC only** and **only on the network shown**; on any other n
|
|
|
49
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+)*
|
|
50
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+)*
|
|
51
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+)*
|
|
52
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+)*
|
|
53
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+)*
|
|
54
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
|
|
@@ -66,6 +68,8 @@ The short version, measured on 2026-10-03 with 2.7.2: **a fresh session did not
|
|
|
66
68
|
| What | Result | The honest part |
|
|
67
69
|
|------|--------|-----------------|
|
|
68
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) *(unreleased)* |
|
|
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) *(unreleased)* |
|
|
69
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+)* |
|
|
70
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+)* |
|
|
71
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 |
|
|
@@ -221,21 +225,53 @@ A compaction keeps a summary and loses the detail that tells you where you were.
|
|
|
221
225
|
|
|
222
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.
|
|
223
227
|
|
|
228
|
+
### 9. (Claude Code, on by default) Open items in sight
|
|
229
|
+
|
|
230
|
+

|
|
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.
|
|
253
|
+
|
|
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.
|
|
255
|
+
|
|
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.
|
|
257
|
+
|
|
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.
|
|
259
|
+
|
|
224
260
|
## Tools
|
|
225
261
|
|
|
226
262
|
| Tool | Description |
|
|
227
263
|
|------|-------------|
|
|
228
264
|
| `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` |
|
|
229
265
|
| `crbro_inspect` | Read-only views by id or name: `view=status`, `neuron`, `neurons`, `sessions`, `global_map`. `view=neuron` is an index by default — every entry as id, kind, date and preview; `entries=[ids]` reads those in full, `detail=full` the whole neuron. `view=sessions session=<id>` reads one day log whole |
|
|
230
|
-
| `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 |
|
|
231
|
-
| `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` |
|
|
232
|
-
| `crbro_revise` | Retire facts (and decisions, patterns, errors, debts via `entries`) as superseded or retracted, reactivate them with `status=active`, edit summary, domain, tags or name, and split a neuron with `move_to` — the entries keep their dates |
|
|
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 |
|
|
233
269
|
| `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 |
|
|
234
270
|
| `crbro_connect` | Create, strengthen, set the strength of or delete (`action=disconnect`) a connection between neurons |
|
|
235
271
|
| `crbro_context` | Read (no arguments) or update the active working context — topics, open items, discard or clear |
|
|
236
272
|
| `crbro_map` | Keep one living map of how a topic's system works — replaced whole, never patched |
|
|
237
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 |
|
|
238
|
-
| `crbro_maintenance` | Brain maintenance — heat, pruning, integrity, `repair`, `unarchive`, index rebuild. Every run reports expired entries, oversized neurons and bulk-import leftovers; `backfill_dates` and `compact` act on them |
|
|
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 |
|
|
239
275
|
| `crbro_audit` | Find credentials stored in the brain, session logs included — reports the kind, never the value |
|
|
240
276
|
| `crbro_secret` | Put a credential in the OS keychain and keep only its name in the brain |
|
|
241
277
|
| `crbro_space` | Create, join, `sync` or `leave` a team space — a private git repo for shared projects |
|
|
@@ -355,6 +391,14 @@ know next time they sit down.
|
|
|
355
391
|
conflict to resolve — not now, not after a week apart.
|
|
356
392
|
- If someone marks a fact as no longer true, that wins. Retracted knowledge
|
|
357
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.
|
|
358
402
|
- No connection is a normal answer, not an error. Your memory works offline and
|
|
359
403
|
whatever you saved goes out on the next sync.
|
|
360
404
|
|
|
@@ -435,7 +479,9 @@ npx crbro-memory daemon on | off | status | stop # One process owns the brain
|
|
|
435
479
|
npx crbro-memory install-hooks --guard # Stored lessons speak before a shell command runs (above)
|
|
436
480
|
npx crbro-memory install-hooks --compact # Checkpoint before a compaction, picked back up after it (above)
|
|
437
481
|
npx crbro-memory guard "<command>" # What the guard would say for a command
|
|
438
|
-
npx crbro-memory install-hooks --verify # SHA-256 of the installed hooks against this package; changes nothing
|
|
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
|
|
439
485
|
npx crbro-memory usage [--days N] [--session ID] [--project DIR] [--json] # Tokens per model and session, subagents apart
|
|
440
486
|
npx crbro-memory postmortem [--days N] [--max N] [--json] # Candidate lessons from past sessions; stores nothing
|
|
441
487
|
npx crbro-memory --help # Help
|
|
@@ -509,7 +555,20 @@ read its file or call `crbro_inspect`.
|
|
|
509
555
|
`~/.claude/projects`, locally and read-only: `usage` reads only the model name
|
|
510
556
|
and token counts of each response, `postmortem` only what you typed and the
|
|
511
557
|
names of the tools called — never a tool's input or output — and redacts what
|
|
512
|
-
it prints.
|
|
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
|
|
513
572
|
[SECURITY.md](https://github.com/Octonove/crbro-memory/blob/master/SECURITY.md).
|
|
514
573
|
|
|
515
574
|
## License
|
package/SECURITY.md
CHANGED
|
@@ -15,6 +15,7 @@ like friction, and nobody trusts one for more than it does.
|
|
|
15
15
|
| | What the miner extracted from files on disk | Neurons, marked `source: miner` |
|
|
16
16
|
| | Claude Code session logs, read by `crbro usage`, `crbro postmortem` and the lifecycle hook | `~/.claude/projects/` |
|
|
17
17
|
| | Compaction checkpoints written by the lifecycle hook (requests, task list, folder, remote) | `<brain>/checkpoints/`, seven days |
|
|
18
|
+
| **Code CRBRO runs in Claude Code without a command** | The open-items mod, installed and updated by `crbro_boot` | `~/.claude/crbro-mods/`, one entry in `env.CLAUDE_CODE_PLUGIN_DIRS` of `~/.claude/settings.json` |
|
|
18
19
|
| **Communication out** | Team-space sync | A git remote you configure |
|
|
19
20
|
| | The optional semantic model | Downloaded once from Hugging Face by `semantic install` |
|
|
20
21
|
|
|
@@ -158,6 +159,41 @@ cannot explain is worth looking at before the next session.
|
|
|
158
159
|
It compares against the package on disk, so it cannot catch a change made to
|
|
159
160
|
both. It runs when you run it, not on its own.
|
|
160
161
|
|
|
162
|
+
### The mod CRBRO installs on its own — `crbro_boot`, `install-mod --verify`
|
|
163
|
+
|
|
164
|
+
Since 2.8, `crbro_boot` copies the open-items mod (`mods/crbro-pending`, TSX
|
|
165
|
+
that Claude Code runs in every new session) into
|
|
166
|
+
`~/.claude/crbro-mods/crbro-pending` and adds that folder to
|
|
167
|
+
`env.CLAUDE_CODE_PLUGIN_DIRS` of `~/.claude/settings.json`, wherever
|
|
168
|
+
`~/.claude` exists, without being asked. The author chose that so the band
|
|
169
|
+
reaches everyone who has CRBRO; this section is what it costs and how to
|
|
170
|
+
check it.
|
|
171
|
+
|
|
172
|
+
- **What runs is what the package ships.** On every new server process, the
|
|
173
|
+
installed copy is compared file by file (SHA-256) with the package that
|
|
174
|
+
process runs, and a different build of a newer or equal version replaces it.
|
|
175
|
+
Updating CRBRO therefore updates code Claude Code executes, with no step in
|
|
176
|
+
between. A file edited by hand in the installed copy is overwritten at the
|
|
177
|
+
next start; to work on the mod, list your own checkout in the variable and
|
|
178
|
+
the automatic install stays out.
|
|
179
|
+
- **Check it.** `npx crbro-memory install-mod --verify` hashes the installed
|
|
180
|
+
copy against the package you run, names any other copy Claude Code would
|
|
181
|
+
load, writes nothing and exits 1 on a difference. The same limits as hook
|
|
182
|
+
verification apply: it compares with the package on disk.
|
|
183
|
+
- **It says what it did.** The boot that installs or updates it carries
|
|
184
|
+
`mod_notice` for the assistant to pass on, with the paths and the way out.
|
|
185
|
+
- **The way out is final.** `npx crbro-memory uninstall-mod` removes the
|
|
186
|
+
entry and the folder and writes `optedOut` in
|
|
187
|
+
`~/.claude/crbro-mods/state.json`; no CRBRO, from any client, installs it
|
|
188
|
+
again until `install-mod` is run. Taking the folder out of the list by hand
|
|
189
|
+
counts the same. `CRBRO_MOD=0` in an MCP client's env keeps that client
|
|
190
|
+
out (a daemon started without it does not serve it), but not the others.
|
|
191
|
+
- **What it will not do.** It does not write a `settings.json` that does not
|
|
192
|
+
parse, does not overwrite a change saved to that file while it was working
|
|
193
|
+
(the file is hashed again right before the rename), and does not write the
|
|
194
|
+
variable there when only the environment sets it. It downloads nothing:
|
|
195
|
+
the files come from the installed npm package.
|
|
196
|
+
|
|
161
197
|
### Reading session logs — `crbro usage`, `crbro postmortem`, the lifecycle hook
|
|
162
198
|
|
|
163
199
|
Claude Code's logs hold everything said in a session, tool output included.
|