CerebroCortex-RS
Health Warn
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 9 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Pure-Rust port of CerebroCortex — brain-analogous AI memory system with ACT-R/FSRS activation, associative networks, 8-phase dream engine, and MCP-over-stdio. Drop-in replacement for the Python version, Pi-native, zero Python runtime.
CerebroCortex-RS
A brain-analogous memory system for AI agents — pure Rust, one binary, one SQLite file.
Memories that decay, dreams that consolidate, skills that compete to survive.
Your agent calls remember and recall over MCP. Underneath, nine engines named after the brain regions they imitate run the content through a salience gate, tag it with emotion, link it into an association graph, and embed it for semantic search. Memories strengthen when retrieved and fade when ignored — real ACT-R and FSRS math, not a vector-store metaphor. At night, a dream cycle replays, abstracts, prunes, and recombines. Procedures that keep failing lose their standing to rivals that win.
All of it compiles to a single binary that idles at 23 MB:
Bare binary (no model): 23 MB RSS, 6 threads, 26 ms recall (FTS5 + spreading activation)
With BGE-small-en-v1.5: 275 MB RSS, 9 threads, 26 ms recall (cosine ANN, 384-dim)
Binary size: 29 MB stripped arm64 ELF
Cold start: ~4.4 s (graph rebuild + model load from cache)
Hot-swapped into a live ApexOS Pi 5 by changing one line in plugins.toml. agentd counted 67 tools and moved on.
✨ What's inside
🧠 A cognitive memory modelSix memory types across four consolidation layers. Recall blends vector similarity + ACT-R activation + FSRS retrievability + salience — recency, frequency, and importance all matter, and every retrieval sharpens what it touches. |
🌙 An 8-phase dream cycleNightly consolidation: episodic replay, LLM pattern extraction with semantic re-discovery detection, schema formation, emotional reprocessing, pruning, REM recombination — plus two evolutionary phases below. |
🧬 Darwinian skill selectionProcedures carry a win/loss ledger. A dream phase ranks same-niche rivals by Wilson lower bound, crowns a |
👁 A vision loop
|
📥 File ingestion
|
🤝 Multi-agent, scoped, auditedPrivate/shared/thread visibility enforced inside the SQL, a shared-only federation scope for mesh peers, message inboxes, and a self-history audit log that answers "what did I actually do, in order?" |
🚀 Quick start
git clone https://github.com/buckster123/CerebroCortex-RS
cd CerebroCortex-RS
cargo build --release -p cerebro-mcp # ~2 min on a Pi 5
Wire it into any MCP client (Claude Code shown):
{
"mcpServers": {
"cerebro-cortex": {
"command": "/path/to/target/release/cerebro-mcp",
"env": { "CEREBRO_DATA_DIR": "/path/to/brain" }
}
}
}
First remember downloads the ~128 MB embedding model to the cache; set CEREBRO_EMBED_MODEL="" to skip it and run keyword-only in 23 MB. Then:
remember("The deploy hot-swap needs systemctl stop before cp — text file busy otherwise")
recall("how do I deploy?") → ranked, activation-weighted, and now slightly stronger
[!TIP]
Migrating from the Python original? PointCEREBRO_DATA_DIRat your existingcerebro.dband start the binary. The Python schema is detected and migrated in one transaction — 504 memories and 9.4k links took under 50 ms in production. The old tables are kept as a fallback through the migration boot, then reaped on the next start.
🗺 Architecture
Four crates, one brain:
crates/
cerebro/ # the library — engines, activation math, storage, vision, ingestion
cerebro-mcp/ # MCP-over-stdio binary — the agent-facing drop-in (67 tools)
cerebro-api/ # axum REST API + the Lucida observatory (127.0.0.1:8765, token auth)
cerebro-cli/ # clap CLI (cerebro remember / recall / stats / dream ...)
ui-slint/ # cerebro-ui — Lucida's native mirror (Slint; dashboard + Atlas + Thought)
graph TB
subgraph Frontends
MCP[cerebro-mcp<br/>67 MCP tools]
API[cerebro-api<br/>REST + Lucida observatory]
CLI[cerebro<br/>CLI]
end
subgraph Library["cerebro (lib)"]
Cortex[Cortex<br/>coordinator]
subgraph Engines["9 engines"]
TH[Thalamus<br/>gating]
AM[Amygdala<br/>emotion]
TE[Temporal<br/>concepts]
HI[Hippocampus<br/>episodic]
AS[Association<br/>links]
CB[Cerebellum<br/>procedural]
PF[Prefrontal<br/>ranking]
NC[Neocortex<br/>schemas]
DR[Dream<br/>8 phases]
end
VI[Vision<br/>VLM + CLIP]
IN[Ingest<br/>7 formats]
subgraph Storage
SQ[(SQLite<br/>source of truth)]
VE[sqlite-vec ANN<br/>+ FTS5 fallback]
GR[petgraph<br/>in-memory graph]
end
end
MCP --> Cortex
API --> Cortex
CLI --> Cortex
Cortex --> Engines
Cortex --> VI
Cortex --> IN
Cortex --> Storage
VE --> SQ
GR --> SQ
SQLite is the single source of truth — the graph and vector index are derived caches, rebuilt on startup and kept fresh across processes via PRAGMA data_version (the MCP daemon and the REST API can share one DB without seeing stale graphs).
🔬 How memory works
Storing
flowchart LR
Input([content]) --> TH[Thalamus<br/>salience gate<br/>10 B – 64 KiB]
TH --> AM[Amygdala<br/>valence + arousal]
AM --> TE[Temporal<br/>concepts + bigrams]
TE --> SQ[(SQLite)]
SQ --> GR[graph node]
SQ --> VE[384-dim embed<br/>vec0 index]
Recalling
flowchart LR
Query([query]) --> VEC[sqlite-vec<br/>cosine ANN]
Query -. fallback .-> FTS[FTS5 · BM25]
VEC --> ACT[Spreading activation<br/>2 hops · 0.6 decay<br/>scope-bounded frontier]
FTS --> ACT
ACT --> PF[Prefrontal ranking]
PF --> R([ranked memories])
R --> REINF[ACT-R access +<br/>FSRS review recorded]
score = 0.35·vector_sim + 0.30·ACT-R activation + 0.20·FSRS retrievability + 0.15·salience
Every recall is also a rehearsal: the ACT-R access history grows and the FSRS stability rises, so frequently-used memories genuinely resist forgetting while untouched ones drift toward the activation_at_risk list.
ACT-R base-level activation — recency + frequency:
$$B(t) = \ln\left(\sum_k t_k^{-d}\right) + \varepsilon \qquad d = 0.5,\ \varepsilon \sim U(\pm 0.4)$$
Access timestamps are capped at the 50 most recent per memory.
FSRS retrievability — the spaced-repetition forgetting curve:
$$R(t, S) = \left(1 + \frac{t}{9S}\right)^{-1}$$
t = days since last review, S = stability in days. A successful recall grows S and eases difficulty; a lapse halves it.
Spreading activation — Collins & Loftus over the link graph: BFS from the vector-search seeds, max 2 hops, 0.6 decay per hop, 50-node cap. Edge conductance is link_type_weight × effective_weight(now) with a 30-day link half-life. The visibility map is computed only over the reachable frontier (never the whole store), and a node missing from the map is treated as not visible — fail-closed by construction.
All three are verified against the Python reference implementation to within 1e-4 by fixture tests.
Memory types & layers
MemoryType: Episodic · Semantic · Procedural · Affective · Prospective · Schematic
MemoryLayer: Sensory (minutes) → Working (days) → LongTerm (months) → Cortex (permanent)
Visibility: Private (agent-only) · Shared (all agents) · Thread (cross-agent dialogue)
🌙 The dream cycle
dream_run executes eight phases; three use an LLM (ANTHROPIC_API_KEY) and skip gracefully without one — the algorithmic phases always run. Pre-phases close stale episodes and sweep retention caps on the lifecycle tables.
flowchart LR
P1[1 · SWS replay] --> P2[2 · Pattern extraction 🤖]
P2 --> P3[3 · Schema formation 🤖]
P3 --> P4[4 · Emotional reprocessing]
P4 --> P5[5 · Pruning]
P5 --> P6[6 · REM recombination 🤖]
P6 --> P7[7 · Variation 🤖]
P7 --> P8[8 · Skill competition]
| Phase | Kind | What it does |
|---|---|---|
| 1 · SWS replay | algorithmic | Replays recent episodes, strengthens temporal links |
| 2 · Pattern extraction | LLM | Clusters memories into candidate procedures — with a semantic re-discovery gate: a candidate ≥ 0.86 cosine to an existing procedure reinforces it instead of re-minting a fragment |
| 3 · Schema formation | LLM | Abstracts episodes into schematic knowledge; distills skills from winning procedure clusters |
| 4 · Emotional reprocessing | algorithmic | Adjusts salience from emotional markers |
| 5 · Pruning | algorithmic | Retires stale, low-salience, orphaned memories (scope-safe) |
| 6 · REM recombination | LLM | Surfaces non-obvious cross-graph connections |
| 7 · Variation | LLM | Refines underperforming procedures into fresh variants; merges two strong same-niche procedures into a hybrid |
| 8 · Skill competition | algorithmic | The selection step ↓ |
🧬 The evolutionary layer
The part where the memory system stops being a filing cabinet. Procedures aren't just stored — they compete:
flowchart LR
USE[record_procedure_outcome<br/>wins & losses] --> LED[fitness ledger<br/>Wilson lower bound]
LED --> COMP[skill_competition<br/>same-niche rivals ranked]
COMP -->|fittest| CH[👑 skill_champion]
COMP -->|dominated| DK[salience decay<br/>→ prune floor]
DK --> VAR[variation phase<br/>refine / merge]
VAR -->|dream_mutated · dream_merged| LED
CH --> RET[champion-aware retrieval<br/>find_relevant_procedures · cognitive_bootstrap]
- Grading a procedure's outcome is asymmetric: one failure bites harder than one success rewards, so bad habits can't coast on age.
- The competition uses the Wilson lower bound on the win rate — a 2/2 newcomer doesn't dethrone a 40/45 veteran, and novel procedures are exempt until they've been graded.
- Dominated rivals decay toward a prune floor instead of being deleted — they can fight their way back.
- Mutated and merged variants inherit their niche tags but start un-graded: trust is re-earned, never copied.
👁 The vision loop
flowchart LR
IMG([image]) --> DI[describe_image<br/>Ollama local/LAN → Anthropic fallback]
DI -->|caption| M[(memory · tagged vision)]
DI -->|CLIP 512-dim| VX[(vision_embeddings)]
TQ([text query]) --> SV[search_vision]
IQ([example image]) --> SV
SV --> VX --> M
The backend is tiered so a node with no local compute still gets eyes: point CEREBRO_VISION_URL at any Ollama (a Pi running moondream, or a beefy box across the LAN), or let it fall back to the Anthropic API. CLIP's image and text towers share one embedding space, so "a red bicycle by a door" finds the photo, and the photo finds its siblings. Nodes with embeddings disabled fall back to caption keyword search — degraded, never broken.
📥 File ingestion
ingest_file routes by extension, chunks to memory-sized pieces, and stamps everything with a source:<filename> tag:
| Format | Strategy |
|---|---|
| text / code (30+ extensions) | paragraph chunks, ≤ 500 words, sentence-split, through the full pipeline |
| Markdown | ## sections → Title: content memories with slug tags; frontmatter sets type/tags |
| JSON | list of strings or {content, type, tags, salience} records |
| CSV | one memory per row, or a schema summary past 200 rows |
| HTML | script/style-stripped text chunks |
| pure-Rust text extraction (image-only scans get an honest error) | |
| images | VLM caption + CLIP index — lands in search_vision |
The provenance tag makes every import a first-class, reversible operation: find_by_tags(["source:notes.md"]) lists it, bulk_delete removes it.
🤝 Multi-agent memory
Multiple agents share one brain without reading each other's diaries. Every query carries a VisibilityScope compiled into the SQL:
-- FORGE's view:
WHERE (visibility='shared' OR (visibility='private' AND agent_id='FORGE'))
AND deleted_at IS NULL
- Scope-enforced writes — deletes, purges, restores, and tag rewrites are scope-checked at the storage layer, atomically, not in the handler above it.
- Federation scope —
recall(visibility: "shared")restricts to shared memories only, and private nodes don't even influence the spreading activation. This is the scope a mesh peer's query runs under: private never crosses the wire. - Ownership rules —
share_memoryis the deliberate publish act; privatizing an owner-less memory is refused (it would be visible to no one). - Self-history — every successful mutating call writes one attributed row to the audit log.
query_auditreads back the agent's own verbs, newest first, filterable by action and time.
🧰 The tool surface (67)
All 67 advertised tools are implemented — no stubs. Wire format: newline-delimited JSON-RPC 2.0 over stdio, protocol 2024-11-05; stdout is exclusively the MCP stream, logs go to stderr. Malformed and oversized frames are answered per-frame (the daemon never dies on bad input), handler panics are isolated, and content is bounded at both gates (64 KiB per memory, 32 MiB per frame).
| Category | Tools |
|---|---|
| Core | remember recall get_memory memory_store memory_search update_memory delete_memory |
| Association | associate memory_neighbors common_neighbors find_path check_near_duplicates |
| Session / thread | session_save session_recall get_thread_memories list_threads prune_thread |
| Episodes | episode_start episode_add_step episode_end get_episode get_episode_memories list_episodes |
| Dream | dream_run dream_status |
| Intentions | store_intention list_intentions resolve_intention |
| Procedures | store_procedure list_procedures find_relevant_procedures record_procedure_outcome |
| Schemas | create_schema list_schemas find_matching_schemas get_schema_sources |
| Analytics | emotional_summary activation_curve activation_heatmap activation_at_risk memory_health cortex_stats memory_graph_stats audit_summary query_audit |
| Tags | list_tags find_by_tags delete_tag rename_tag merge_tags |
| Multi-agent | register_agent list_agents share_memory send_message check_inbox |
| Lifecycle | list_deleted restore_memory purge_memory bulk_delete purge_all_deleted get_memory_versions restore_version |
| Vision | describe_image search_vision |
| Ingestion | ingest_file |
| Bootstrap | cognitive_bootstrap |
| Export | export_memories |
cognitive_bootstrap deserves a mention: one call assembles a token-budgeted priming block — open intentions, relevant session notes, distilled skills, champion procedures, relevant memories — replacing a four-tool orient at session start.
memories — the nodes; access_times JSON for ACT-R, embedding BLOB for vec0
links — typed, weighted edges with traversal stats and decay
memories_fts — FTS5 mirror, trigger-synced, soft-delete aware
memory_vectors — vec0 virtual table (sqlite-vec), rowid-joined
vision_embeddings — CLIP 512-dim image vectors + source paths
memory_versions — content snapshots for undo/audit (retention-capped)
episodes / steps — episodic sequences
dream_reports — persisted dream cycle output (retention-capped)
audit_log — the agent's own action timeline (retention-capped)
agents — registry with display metadata
schema_version — migration marker (100 = migrated from Python)
A retention sweep rides the dream cycle and bounds the three forever-growing tables (CEREBRO_RETAIN_* env knobs; 0 = keep forever). When it prunes, it writes one audit row saying exactly what it did — the timeline may shorten, but never silently.
🚢 Deployment
The tier ladder
Same binary everywhere — tiers are just environment variables.
| Tier | Hardware | Embeddings | RSS | Search |
|---|---|---|---|---|
| Nano | Pi Zero 2W, 512 MB boards | disabled | ~23 MB | FTS5 + spreading activation |
| Micro | Pi 4 | bge-small | ~275 MB | cosine ANN |
| Standard | Pi 5, mini-PC | bge-small | ~275 MB | cosine ANN + CLIP vision |
| Pro | x86 + GPU | bge-small† | ~500 MB | cosine ANN + CLIP vision |
† GPU ONNX execution providers are planned; CPU works everywhere today. An unrecognized model name falls back to bge-small with a loud warning — embeddings never silently disable.
The real target is the hardware sitting in drawers — last-gen mini-PCs, retired Mac Minis, Pi 4s from the before-times. A complete cognitive memory system in 23 MB leaves the rest of the board for the agent itself.
ApexOS drop-in
# /etc/agentd/plugins.toml
[[plugin]]
id = "cerebro"
cmd = "/usr/local/bin/cerebro-mcp"
restart = "always"
[plugin.env]
CEREBRO_DATA_DIR = "/var/lib/agentd/cerebro"
FASTEMBED_CACHE_DIR = "/var/lib/agentd/cerebro/models"
RUST_LOG = "warn"
Build natively on the target (arm64 ≠ x86 — never cross-compile), stop the service before copying the binary (text file busy), and pre-warm the model cache on first deploy.
sudo mkdir -p /var/lib/agentd/cerebro/models
sudo chown agentd:agentd /var/lib/agentd/cerebro/models
# Run once as the service user — downloads ~128 MB to the cache
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"prewarm","version":"0.1"}}}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"remember","arguments":{"content":"prewarm memory for model download"}}}\n' | \
sudo -u agentd env \
CEREBRO_DATA_DIR=/var/lib/agentd/cerebro \
FASTEMBED_CACHE_DIR=/var/lib/agentd/cerebro/models \
/usr/local/bin/cerebro-mcp
Environment variables
| Variable | Default | Purpose |
|---|---|---|
CEREBRO_DATA_DIR |
~/.cerebro-cortex/ |
SQLite DB root |
CEREBRO_EMBED_MODEL |
BAAI/bge-small-en-v1.5 |
fastembed model (empty = FTS5-only Nano tier) |
FASTEMBED_CACHE_DIR |
.fastembed_cache |
embedding model cache |
ANTHROPIC_API_KEY |
— | dream LLM phases + vision fallback (all skip gracefully unset) |
CEREBRO_VISION_BACKEND |
auto |
auto | ollama | anthropic | off |
CEREBRO_VISION_URL / _MODEL |
localhost:11434 / moondream |
Ollama endpoint — point at any LAN node |
CEREBRO_VISION_EMBED |
follows embed model | CLIP visual recall on/off |
CEREBRO_RETAIN_VERSIONS / _DREAM_REPORTS / _AUDIT_ROWS |
10 / 90 / 20000 | retention caps (0 = keep forever) |
CEREBRO_API_TOKEN |
— | REST API bearer token (required for non-loopback binds) |
CEREBRO_API_ADDR |
127.0.0.1:8765 |
REST API bind — refuses LAN exposure without a token |
RUST_LOG |
info |
tracing filter (stderr only) |
🔨 Building from source
cargo build --release # all four crates
cargo test # 250 tests, no network, no model download
| Suite | Tests | What it gates |
|---|---|---|
| cerebro (unit) | 137 | engines, activation vs Python fixtures (±1e-4), dream phases, vision, ingestion, transport-free logic |
| cerebro (integration) | 76 | storage CRUD, scope enforcement, migration + reap, retention, cortex end-to-end |
| cerebro-mcp | 46 | dispatch routing, tool contracts, audit trail, panic isolation, frame caps |
| cerebro-api | 7 | priority casing, PCA projection, route-syntax pin, time-lapse clamp + decay |
| ui-slint | 10 | field placement (web-parity FNV-1a), star/edge ranking, trace prep honesty |
| total | 276 |
🔗 Related
- CerebroCortex — the Python original: reference implementation and the source of the activation-math fixtures
- ApexOS — the Pi-native agent runtime this plugs into, where the multi-node colony features (mesh recall, procedure replication) live
📄 License
MIT
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found