Octobrain 0.9.0: Knowledge Goes Multiplayer
Your team already wrote the docs. The deploy runbook, the "never touch this without a migration" rules, the hard-won notes about why the payments service retries the way it does. They live in a wiki nobody reads, a pinned Slack message, and three people's heads. Every new agent session — and every new teammate — starts from zero and re-learns it the hard way.
0.7.0 made each agent's memory maintain itself — sleep consolidation, decay, goal-anchored folding. That was about one memory, getting smarter on its own.
0.9.0 is about the other half of the problem: knowledge that shouldn't be re-learned per machine. It makes Octobrain's knowledge layer shareable — versioned in git, scoped by name, synced automatically — and sharpens recall so the right fact wins more often. (We folded 0.8.0's groundwork in here too.)
Git-Backed Knowledge Boxes — Ship Knowledge Like Code
This is the headline. A knowledge box is a git repository full of markdown — rules, docs, playbooks, architecture notes — that Octobrain clones, indexes, and keeps in sync. Curate it once, version it like code, and every agent on every machine that subscribes gets the same searchable knowledge.
There are two flavors, and they cover the two real cases:
Project-local — just commit a .box/ directory. Drop your project's living knowledge into .box/ in the repo root. Anyone who clones the repo and runs Octobrain gets it indexed automatically — no extra command, no remote to configure. It travels with the code because it is in the code.
Remote — subscribe to a shared box. Point Octobrain at a git URL and it shallow-clones the box and indexes it under a scope:
# Subscribe to your org's shared knowledge box
octobrain box import https://github.com/acme/engineering-knowledge
# Index it at the global scope — visible in every project on this machine
octobrain box import https://github.com/acme/conventions --global
# Pull + smart-reindex every subscribed box and the local .box/
octobrain box sync
# See what you're subscribed to, or drop one
octobrain box list
octobrain box remove github.com/acme/engineering-knowledge
Every box-sourced chunk gets a stable box://<host>/<org>/<repo>/... source URI, so it's grouped, attributable, and cleanly removable — pull a box and all its rows go with it. Re-syncs are hash-based and smart: only changed files get re-embedded, so a sync over an unchanged box costs almost nothing.
And under MCP, you don't even call sync — the server discovers each project's .box/, probes for an org box, and refreshes subscribed remotes in the background, once per session, single-flighted so it never blocks a request. Your agent just starts finding the team's knowledge in its searches.
[knowledge]
chunk_size = 1200 # boxes index through the same chunker as everything else
The point: the runbook stops living in someone's head. It lives in a repo, it's searchable by meaning, and it shows up in your agent's context the moment it's relevant — for everyone.
Scopes Replace Project Hashes — Memory With a Name
Until now, Octobrain isolated memory per project by hashing your Git remote URL into an opaque SHA-256 directory. It worked, but you couldn't read it, couldn't target it, and couldn't share it.
0.9.0 replaces that with scopes: human-readable strings, derived automatically from your Git remote (or local path as a fallback), that you can actually see and point at.
# Auto-detected from the git remote — nothing to configure
octobrain memory remember "rate limiting approach"
# Or target a scope explicitly
octobrain memory remember "rate limiting approach" --scope acme/payments
# Store something that should be visible everywhere, not just this project
octobrain memory memorize --title "Team convention: trunk-based, no long-lived branches" \
--content "..." --global
Scopes are what make boxes coherent: a remote box binds to an org-level scope by default, a .box/ binds to its project's scope, and --global puts knowledge or memory in front of every project on the machine. One naming system, used everywhere — storage paths, search filters, stats, and logs all read in plain language now instead of hashes.
This is the one breaking change that touches you: the --project flag and project tool parameters are now --scope. Same behavior, readable name. See Upgrading.
Multi-Query Recall That Actually Pays Off — RRF Fusion
Octobrain has long supported multi-query search — decompose a fuzzy question into several sharper ones and search them together:
octobrain memory remember "authentication" "session security" "jwt expiry"
The problem was the merge. The old logic kept each memory's best single score and tacked on a flat 10% per extra match — mixing per-query scores computed on incomparable scales. A memory that ranked solidly across all three queries could lose to a one-off top hit on a single query. Decomposition didn't actually help; sometimes it hurt.
0.9.0 replaces that with Reciprocal Rank Fusion — the same k=60 rank-based fusion Octobrain already uses to combine BM25 and vector search in-store. RRF is rank-based and scale-free: a memory that places well across many queries beats one that spikes on a single query. Now query decomposition pays off the way it should. It's pure math — no LLM, no extra config — and rrf_fuse is a small, unit-tested function you can trust.
Recall Knows What's Current — Supersedes-Aware Ranking
Facts go stale. You decided to use Postgres, then six weeks later switched to SQLite. Both notes are in memory, both match "what database are we using" — and the old answer has no business winning.
Octobrain has always had a Supersedes relationship type, but it was defined, parsed, and stored — and then never read at retrieval. A built capability, sitting dead.
0.9.0 wires it in. When an active X Supersedes M edge marks a result as outdated, retrieval soft-down-ranks the stale one (×0.1 — never deleted), so the current fact rises to the top while history stays queryable. Two deliberate guardrails:
- Edges are honored, never auto-created. Detecting a genuine contradiction needs semantic judgment, and Octobrain keeps that off the hot path on purpose. You (or your agent) mark the supersede; retrieval respects it. Over MCP, the
knowledgetool now actively guides agents to create supersedes links when they update a fact. - Best-effort. A relationship-lookup failure leaves the result untouched rather than dropping it. Worst case you're back to old behavior, never worse.
The current decision wins; the trail back to the old one survives.
Time-Scoped Recall — Temporal & Relevance Filters
"What did I decide last week?" is a question humans ask constantly, and semantic search alone answers it badly — relevance doesn't know about time.
MemoryQuery already supported created_after / created_before (pushed straight down to the created_at index) and min_relevance — but the remember MCP tool never populated them. Another built-but-dead capability. 0.9.0 exposes both:
created_after/created_before— ISO-8601 date (2026-06-01) or full RFC3339 timestamp. A bare date means midnight UTC; anything unparseable simply skips the filter rather than erroring.min_relevance— a per-call floor on result quality, overriding the global default.
The tool tells the agent to compute the window itself — it already knows today's date — so there's no brittle natural-language date parsing buried in the tool. "What did I decide last week" turns into a clean indexed range scan, which is exactly the kind of time-anchored question LongMemEval measures.
We Put Numbers On It — BEIR Retrieval Benchmarks
0.7.0 added LongMemEval for long-term memory. 0.9.0 adds a BEIR retrieval harness so we can score the ranking layer — embedding + BM25 fusion + reranking — on standard datasets with real qrels, fully local, no LLM judge.
Using the default local embedder (bge-small-en-v1.5, 384-dim, 33M params), measured as nDCG@10:
| Dataset | Octobrain vector | Octobrain hybrid | BM25 | bge-small-en-v1.5 |
|---|---|---|---|---|
| SciFact (5.2K docs, 300 q) | 0.722 | 0.742 | 0.665 | 0.713 |
| NFCorpus (3.6K docs, 323 q) | 0.341 | 0.363 | 0.325 | 0.343 |
The dense-only column reproduces the embedder's published BEIR numbers — that's the harness validating itself. The hybrid column (BM25 + vector fused with RRF, Octobrain's default) adds +2 nDCG@10 over the bare embedding and beats classic BM25 on both datasets. Reproduce it yourself: cd benches && bash scripts/run_retrieval.sh. The recall claims above are claims we can stand behind.
Under the Hood
The quieter changes that keep things fast and predictable as the corpus grows:
Two new search knobs, in config.
search.similarity_threshold(default0.3) is the global relevance floor for semantic queries;search.max_results(default50) is a hard ceiling no caller can exceed. Both are now wired end-to-end instead of advertised-but-ignored.[search] similarity_threshold = 0.3 # min relevance for semantic queries (0.0–1.0) max_results = 50 # hard ceiling on results from any searchTimeouts for embeddings and reranker. A slow or hung provider call no longer stalls a search —
timeout_secs(default30) bounds both, with an example in the reranker config.Background initialization. Heavy startup tasks spawn off the hot path, so the first request after launch doesn't pay for index warm-up.
Automatic scope discovery & config override (from 0.8.0). Octobrain derives your scope from the working directory automatically, and
OCTOBRAIN_CONFIG_PATHlets you point at a custom config file — handy for CI, containers, and multi-tenant setups. Project and role locking were decoupled so unrelated sessions stop contending.Multi-arch Docker. Release now builds and pushes multi-arch images, so
arm64(Apple Silicon, Graviton) andamd64are both first-class.Hardened ranking math. Fixes to the reranker candidate limit, RRF normalization, archived-memory exclusion, and a PRF guard tighten up edge cases in the new retrieval path. Knowledge search also now returns the full parent section, not a truncated fragment.
You won't reach for most of these directly. That's the point.
What 0.9.0 Looks Like in Practice
A new engineer joins the payments team:
- They clone the repo. Its
.box/directory — deploy runbook, "don't bypass the idempotency layer" rules, the why-we-retry notes — gets indexed automatically the first time their agent runs. Zero setup. - Their machine subscribes to the org box (
octobrain box import …), so company-wide conventions show up under a global scope, in every project. - They ask their agent a vague question — "how do we handle webhook failures here?" Multi-query decomposition fans it out, RRF fuses the ranks, and the team's runbook entry lands at the top.
- A decision changed last month — the team moved off a queue they used to recommend. The old note is marked superseded, so the current approach wins and the history is still one query away.
- They ask "what did we change last week?" — temporal filter, clean indexed range, no noise from six months ago.
Nobody re-explained the system. The knowledge was already written down — Octobrain just made it findable, current, and shared.
Upgrading
From 0.7.x or 0.8.x, the migration is small.
Config — --project becomes --scope. This is the one breaking change. Anywhere you passed --project <id> on the CLI, or a project parameter to an MCP tool, use --scope <name> instead. The big upgrade: the value is now a human-readable string (auto-derived from your Git remote), not a hash — so most of the time you can drop the flag entirely and let discovery handle it.
octobrain memory remember "api design" --scope acme/web # was: --project <hash>
Storage — nothing to do. The scope column and its index are added on first run, and existing memories migrate in place. No manual steps, no downtime.
New config is additive. search.similarity_threshold, search.max_results, and the embedding/reranker timeout_secs all ship with working defaults. Add them only if you want to tune them.
Knowledge boxes are opt-in. Nothing changes until you commit a .box/ directory or run octobrain box import. Existing indexed sources are untouched.
MCP clients — refresh your tool list. remember now accepts created_after, created_before, and min_relevance; memorize takes --global. No renames on the core five tools — just new optional fields your agent can use.
Source, binaries, and Docker images at github.com/muvon/octobrain. If something breaks, open an issue — we read them.



