Introduction
The Problem
You have side projects. Maybe 3, maybe 10. You work on them in bursts — a flurry of commits, then months of silence.
When you return, the question is always the same:
“Wait, what was I working on? Where did I leave off?”
You scroll through git history. You grep for “TODO”. You search your notes. By the time you remember, you’ve already lost 20 minutes.
The Solution
Cerebro watches your development activity and builds a personal mission control dashboard. It aggregates:
- OpenCode sessions — Your AI pair-programming history
- Git activity — Commits, branches, file changes
- TODOs — TODO, FIXME, HACK, XXX comments in your code
- Manual notes — Your status, next actions, goals
When you return to a dormant project, your dashboard answers the question in seconds.
How It Works
Cerebro uses a two-repo architecture:
flowchart LR
subgraph "Sources"
G[Git repos]
O[OpenCode sessions.db]
end
subgraph "cerebro (CLI)"
C[cerebro build]
end
subgraph "cortex (your data directory)"
CT[content/ generated md]
NB[content/notes/ manual]
BK[book/ rendered HTML]
end
subgraph "cerebro-mcp"
MS[MCP server]
end
subgraph "Consumers"
MDB[mdbook]
OC[OpenCode]
end
G -->|scrape| C
O -->|scrape| C
C -->|writes| CT
NB -. manual .-> CT
CT -->|mdbook| BK
NB -->|mdbook| BK
MS -->|reads| CT
MS -->|reads| NB
OC <-->|JSON-RPC| MS
The Two Repos
| Repo | Purpose |
|---|---|
~/Projects/cerebro | Source code — CLI, MCP, TUI, shared types |
~/Projects/<name> | Your cortex — config, generated content, manual notes, rendered HTML |
The Three Binaries
| Binary | Purpose | Used by |
|---|---|---|
cerebro | CLI: scrape repos, generate markdown | You, cron |
cerebro-mcp | MCP server: answer questions about projects | OpenCode |
cerebro-tui | Terminal UI: browse projects interactively | You (feature branch) |
Content Boundaries
Your cortex’s content/ has a clear split:
| Path | Generated by | Edit? |
|---|---|---|
content/index.md | cerebro | No |
content/projects/*.md | cerebro | No |
content/journal/ | cerebro | No |
content/today.md | cerebro | No |
content/this-week.md | cerebro | No |
content/intent/ | Human | Yes |
content/notes/ | Human | Yes |
content/SUMMARY.md | Human | Yes |
The boundary is enforced by an AGENTS.md file in your cortex — AI agents are instructed not to edit manual content.
Why It Works
Cerebro succeeds when it reduces context-switching friction. You’ll notice it when:
- You return to a project you haven’t touched in weeks
- You have too many projects to track mentally
- You use AI assistants and want to remember what you worked on
Key Concepts
| Term | Meaning |
|---|---|
| Collector | A source of data (git, opencode, todos, notes) |
| Generator | Creates output files from collected data |
| Project | A repo + notes + activity you’re tracking |
| Dashboard | The generated markdown output |
Architecture
Cerebro is a Rust workspace with three crates (four on the TUI branch):
- cerebro — CLI tool and collectors
- cerebro-core — Shared types and storage traits
- cerebro-mcp — MCP server for OpenCode integration
- cerebro-tui — Terminal UI for browsing projects (feature branch)
Next Steps
- Quick Start — Get running in 5 minutes
- Dashboard Guide — Understand the output
- Configuration — Customize for your projects
Quick Start
Get your dashboard running in 5 minutes.
1. Install
cargo install --path crates/cerebro
2. Create Config
Place config.toml in your cortex:
[settings]
cache_ttl_hours = 24
opencode_db_path = "~/.local/share/opencode/opencode.db"
output_dir = "./content"
[[projects]]
name = "my-project"
repo_path = "~/Projects/my-project"
active = true
3. Build
cd ~/Projects/my-cortex && cerebro build
This generates your dashboard in ~/Projects/my-cortex/content/.
4. Serve
cd ~/Projects/my-cortex && mdbook serve --port 3456
Open http://localhost:3456 to see your dashboard.
Your First Win
After a few days of use, come back to a dormant project. Instead of:
“Wait, what was I working on? Where did I leave off?”
Your dashboard shows:
- Last activity: 3 days ago — “feat: add user authentication”
- OpenCode session: “Debugging JWT token refresh”
- TODOs left:
src/auth.rs:42— “TODO: handle expired tokens” - Next action: From your notes — “Test the login flow”
That’s the moment cerebro earns its place in your workflow.
Next Steps
- Configuration — Customize settings
- Dashboard Guide — Understand the output
- Commands — All available commands
Dashboard Guide
Understanding the output cerebro generates.
Output Structure
{cerebro-dashboard}/
├── index.md # Your mission control
├── today.md # Today's activity
├── this-week.md # This week's activity
├── projects/
│ └── {name}.md # Per-project pages
└── journal/
└── {year}/
└── {mm}/
└── {dd}.md # Daily journal pages
index.md — Your Mission Control
The main dashboard shows:
Activity Overview
- Projects at a glance — Which have recent activity
- Git commit counts — How much you’ve shiped
- OpenCode session counts — How much AI help you’ve received
- TODO totals — Work waiting to be done
Project Cards
Each project shows:
- Last activity — When you last worked on it
- Recent commits — What you shipped
- OpenCode sessions — AI-assisted work
- TODOs — Outstanding items
- Status — From your notes (e.g., “paused”, “actively developing”)
- Next action — Your stated next step
projects/{name}.md — Deep Dive
Click any project card to see full context:
Header
- Repository path
- Last activity timestamp
- Status badge
Your Notes
Whatever you’ve written in notes/projects/{name}.md:
## Status
building: integrating Stripe API
## Next
- Test webhook endpoints locally
- Deploy to staging
Git Activity
Recent commits with messages, dates, and files changed.
OpenCode Sessions
AI-assisted work sessions with titles and timestamps.
TODOs
List of TODO/FIXME/HACK/XXX items found in code:
- TODO: handle expired JWT tokens (src/auth.rs:42)
- FIXME: race condition in cache (src/cache.rs:18)
- HACK: temporary rate limiting (src/api.rs:103)
today.md — Daily Pulse
Today’s activity, scoped to the last 24 hours.
this-week.md — Weekly Review
This week’s activity, scoped to 7 days.
journal/{date}.md — Historical Record
Daily pages with all activity for that date. Useful for:
- Reviewing what you accomplished
- Identifying patterns in your work
- Journaling your development journey
Using the Dashboard
For Context Switching
When returning to a project:
- Open the dashboard
- Find your project (search or click)
- Read: status → next → TODOs → recent activity
For Daily Standup
- Check
today.mdfor today’s work - Review
this-week.mdfor the week’s progress
For Planning
- Read your notes in each project
- Review TODOs to see what’s left
Customization
The dashboard is just markdown. You can:
- Add it to git for version control
- Deploy it to a static host
- Customize the templates in
generators/ - Add your own data sources
TUI Guide
Launch the terminal UI with:
cerebro tui
Or run the standalone binary directly:
cerebro-tui
The TUI provides a rich, interactive terminal interface for browsing all your project activity data — sessions, commits, TODOs, journal entries, and manual notes — without leaving your terminal.
Layout
┌─────────────────────────────────────────────────────┐
│ Cerebro TUI │
├──────────┬──────────────────────────────────────────┤
│ Dashboard│ [Content area — changes per view] │
│ Projects │ │
│ Journal │ │
│ TODOs │ │
│ Config │ │
├──────────┴──────────────────────────────────────────┤
│ r refresh b build Space leader q quit ? help │
└─────────────────────────────────────────────────────┘
Navigation
Main Views
| Key | Action |
|---|---|
j / ↓ | Next item in sidebar |
k / ↑ | Previous item in sidebar |
Tab | Cycle focus (sidebar ↔ content) |
Shift+Tab | Cycle focus backward |
Enter | Switch to selected view (sidebar) |
1 / g | Dashboard |
2 | Projects |
3 | Journal |
4 | TODOs |
5 / G | Config |
Leader Key
Press Space then a letter to jump directly:
| Sequence | Action |
|---|---|
Space d | Dashboard |
Space p | Projects |
Space j | Journal |
Space t | TODOs |
Space c | Config |
The leader key is active everywhere except during text input (journal editing, note editing, or form input). Press Esc to cancel a pending leader sequence.
Focus Management
| Key | Action |
|---|---|
Right / l | Move focus from sidebar to content |
Left / h | Move focus from content to sidebar |
Views
Dashboard
Summary of all projects with session counts, commit counts, and TODO counts. Press Enter on a project to drill into its detail view.
Projects
When no project is selected, shows a list of all projects with activity counts. Navigate with j/k, press Enter to select.
Once a project is selected, three tabs are available:
| Key | Tab |
|---|---|
1 | Sessions |
2 | Commits |
3 | TODOs |
Tab | Next tab |
Shift+Tab | Previous tab |
Within each tab, navigate items with j/k. Press Enter on a TODO to preview its full context. Press e to edit the project’s status/next notes. Press Esc to deselect and return to the project list.
Journal
Shows journal entries from all projects. Entries are grouped by date headers (### 2026-04-25) or shown as a single entry per project if no date headers exist.
| Key | Action |
|---|---|
j / ↓ | Next entry |
k / ↑ | Previous entry |
g | First entry |
G | Last entry |
Enter | View full entry |
i | Edit journal for the selected project |
Esc | Close preview / cancel edit |
Journal entries come from ## Journal sections in your project notes files (content/notes/projects/{name}.md). If no journal sections exist, the view will be empty.
TODOs
Aggregates TODOs from all projects. Navigate with j/k, press Enter to preview the full TODO with file context. Press Esc to close preview.
Config
Toggle project active/inactive status and add new projects. Changes are written to config.toml on disk.
Global Commands
| Key | Action |
|---|---|
r | Refresh data from all sources |
b | Run cerebro build (generates dashboard) |
q | Quit |
? | Toggle help overlay |
Esc | Close overlays, go back |
Mouse Support
Click any item in the sidebar to switch views. Click a project in the project list to select it.
What the TUI Does
- Browse OpenCode sessions, git commits, and TODOs per project
- View project status and next-session notes
- Edit status and next notes directly from the TUI
- Read journal entries from daily logs
- Toggle project active/inactive status
- Add new projects to config
- Refresh data on demand
- Build the markdown dashboard from the TUI
What the TUI Doesn’t Do (Yet)
- Session message content — Sessions show titles and timestamps but not individual messages
- Session preview — Can’t view the conversation inside a session
- Commit diff — Shows commit messages but not file changes
- TODO editing — Can view TODOs but not mark them complete (they’re code comments)
- Search/filter — No text search across sessions, commits, or TODOs yet
- Activity graph — No heatmap or timeline visualization
- Multi-project comparison — Can’t view two projects side by side
- Git branch info — Doesn’t show current branch or uncommitted changes per project
Configuration
Cerebro is configured via a config.toml file, typically placed in your cortex.
Example Configuration
[settings]
cache_ttl_hours = 24
opencode_db_path = "~/.local/share/opencode/opencode.db"
output_dir = "./content"
[[projects]]
name = "my-project"
repo_path = "~/Projects/my-project"
active = true
Settings
| Setting | Description | Default |
|---|---|---|
cache_ttl_hours | Hours to keep cached data fresh | 24 |
opencode_db_path | Path to OpenCode database | ~/.local/share/opencode/opencode.db |
output_dir | Where to write the generated dashboard | ./content |
Project Configuration
Each project is defined with:
| Setting | Description | Required |
|---|---|---|
name | Project name | Yes |
repo_path | Path to git repository | Yes |
active | Include in dashboard generation | Yes |
Manual Notes
Manual notes are not configured per-project. They live directly in your cortex:
| Path | Purpose | Edited by |
|---|---|---|
content/intent/ | Goals (daily, weekly, monthly, yearly) | Human only |
content/notes/ | Evergreen notes and documentation | Human only |
content/SUMMARY.md | Navigation structure | Human only |
The boundary between auto-generated and manual content is defined by an AGENTS.md file in your cortex. Cerebro only writes to content/index.md, content/projects/, content/journal/, content/today.md, and content/this-week.md.
Commands
Cerebro provides the following CLI commands:
Build Commands
cerebro build
Generate the dashboard. Uses cached data where fresh.
cerebro build # Build all projects
cerebro build --project my-proj # Build specific project
cerebro build --fresh # Force rebuild, ignoring cache
cerebro serve
Serve the generated dashboard with mdBook locally.
cerebro serve # Default port is 3000
cerebro serve --port 8080 # Custom port
Note: This spawns mdbook in the configured output_dir and exits immediately. For a persistent server, run mdbook serve directly in your cortex.
Status Commands
cerebro status
Check cache status for all projects.
cerebro status
Shows:
- Last build time per project
- Cache TTL remaining
- Any stale data
MCP Commands
cerebro mcp
Start the cerebro MCP server for OpenCode integration. Reads from the cortex directory containing the config file.
cerebro mcp
Requires CORTEX_PATH environment variable or a config file in the current directory.
TUI
cerebro tui
Launch the terminal UI for browsing projects interactively.
cerebro tui
The TUI shares data types with the CLI (cerebro-core) and reads the same cortex content that mdbook renders. A standalone binary cerebro-tui is also available for running the TUI independently.
Troubleshooting
Common issues and solutions.
Installation
“command not found: cerebro”
Make sure the cargo bin is in your PATH:
export PATH="$HOME/.cargo/bin:$PATH"
Add this to your shell profile (~/.zshrc or ~/.bashrc) to persist.
“could not find cerebro”
Run cargo install cerebro from the project directory:
cargo install --path .
Configuration
“Config file not found”
Create config.toml:
cp config.toml.example config.toml
Or create manually:
[settings]
cache_ttl_hours = 24
opencode_db_path = "~/.local/share/opencode/opencode.db"
output_dir = "./content"
[[projects]]
name = "my-project"
repo_path = "~/Projects/my-project"
active = true
“could not parse config”
Check your TOML syntax:
- Use
=not: - String values need quotes:
"path"notpath - Arrays use brackets:
[[projects]]not[projects]
Validate with:
cargo run -- build
“Repo not found”
Verify repo_path exists:
ls -la ~/Projects/my-project
Build
“No activity found”
Likely causes:
- No git commits yet — Commit something first
- No OpenCode sessions — Use OpenCode in that project
- No TODOs — Add a TODO or FIXME comment
This is normal for new projects. Activity appears as you work.
“Build is slow”
First build can be slow on large repos. Subsequent builds use cache.
Force a fresh build:
cerebro build --fresh
Clear cache manually:
cerebro status
# Note the cache location
rm {cache_file}
“OpenCode database not found”
Set the correct path in config:
opencode_db_path = "~/.local/share/opencode/opencode.db"
Verify the file exists:
ls -la ~/.local/share/opencode/opencode.db
MCP Server
“MCP tools not available”
Restart OpenCode after configuring the MCP server.
Ensure CORTEX_PATH is set to your cortex:
export CORTEX_PATH="~/Projects/my-data-dir"
Test the server directly:
cargo run -p cerebro-mcp
“No projects found in MCP”
Verify your config includes the project and it’s set to active = true.
Serving
“Port already in use”
Pick a different port:
cerebro serve --port 3001
“Dashboard not updating”
Rebuild with --fresh:
cerebro build --fresh
Then refresh your browser.
General
“Unexpected behavior”
Run with debug logging:
RUST_LOG=debug cargo run -- build
“It’s broken and I don’t know why”
Clear everything and start fresh:
# Remove output
rm -rf ~/cerebro-dashboard
# Remove cache
rm -rf ~/Library/Caches/cerebro
# Rebuild
cerebro build --fresh
Architecture Overview
This document explains how the cerebro system works end-to-end.
System Diagram
flowchart TB
subgraph cerebro_repo["~/Projects/cerebro (source code)"]
CLI_CRATE["crates/cerebro<br/>CLI binary"]
CORE_CRATE["crates/cerebro-core<br/>shared types"]
MCP_CRATE["crates/cerebro-mcp<br/>MCP library"]
TUI_CRATE["crates/cerebro-tui<br/>TUI binary (feature branch)"]
DOCS["docs/<br/>tool documentation"]
end
subgraph cortex_dir["~/Projects/<name> (your cortex)"]
CFG["config.toml"]
AUTO["content/ (auto-generated)<br/>index.md, projects/, journal/"]
MANUAL["content/ (manual)<br/>intent/, notes/, SUMMARY.md"]
BOOK["book/<br/>rendered HTML"]
AGENTS["AGENTS.md<br/>edit boundaries"]
end
subgraph external["External data sources"]
GIT["project git repos"]
OODB["opencode sessions.db"]
end
subgraph consumers["Consumers"]
MDBOOK["mdbook"]
OPENCODE["OpenCode"]
TERMINAL["Terminal user"]
end
CLI_CRATE -->|scrapes| GIT
CLI_CRATE -->|queries| OODB
CLI_CRATE -->|reads| CFG
CLI_CRATE -->|writes| AUTO
TUI_CRATE -->|reads same data| AUTO
TUI_CRATE -->|reads| MANUAL
TUI_CRATE -->|uses types| CORE_CRATE
MCP_CRATE -->|reads| AUTO
MCP_CRATE -->|reads| MANUAL
MANUAL -. "human edits" .-> MANUAL
AGENTS -. "defines boundaries" .-> MANUAL
AUTO -->|mdbook src| MDBOOK
MANUAL -->|mdbook src| MDBOOK
MDBOOK -->|renders| BOOK
OPENCODE <-->|JSON-RPC| MCP_CRATE
TERMINAL <-->|interactive| TUI_CRATE
style CLI_CRATE fill:#4a9eff,color:#fff
style TUI_CRATE fill:#9b59b6,color:#fff
style MCP_CRATE fill:#ff6b6b,color:#fff
style AUTO fill:#ff8
style MANUAL fill:#f8f
style BOOK fill:#8f8
The Two Repos
cerebro (~/Projects/cerebro)
The source code repository. Contains:
- CLI binary (
crates/cerebro/) — Scrapes data sources and generates markdown - Shared types (
crates/cerebro-core/) — Config, ProjectContext, Storage trait - MCP server (
crates/cerebro-mcp/) — JSON-RPC server for OpenCode - TUI (
crates/cerebro-tui/) — Terminal UI (feature branch) - Documentation (
docs/) — mdBook docs about the cerebro tool itself
Your cortex
The cortex (named whatever you choose — cortex in this project’s case). Contains:
- config.toml — Project list and settings (read by cerebro)
- content/ — mdBook source (mix of auto-generated and manual)
- book/ — Rendered HTML output
- AGENTS.md — Defines edit boundaries for AI agents
- book.toml — mdBook configuration
The Three Binaries
cerebro (CLI)
cerebro build # Scrape repos, generate markdown
cerebro build --fresh # Ignore cache
cerebro build --project X # Single project
cerebro status # Show cache status
cerebro serve # Spawn mdbook in output_dir
cerebro serve --port N # Custom port
cerebro mcp # Start MCP server
Data flow:
- Reads
config.tomlfrom your cortex - For each project: scrapes git, queries OpenCode DB, scans TODOs, reads manual notes
- Writes markdown to
output_dir(typically./content) - Cache stored alongside config to avoid redundant scraping
cerebro-mcp (MCP Server)
# Started by OpenCode via opencode.json:
# "command": ["cerebro", "mcp"]
# Or standalone:
cerebro-mcp # Reads CORTEX_PATH env var
Tools provided:
read_project— Combined generated + manual content for a projectlist_projects— All tracked projects with metadataread_journal— Journal entry by dateread_today— Today’s journal entryread_intent— Goals by period (daily/weekly/monthly/yearly)search_todos— Search TODOs across projectsget_stats— Overall statistics
Path resolution:
CORTEX_PATHenv var (required — points to your cortex)- Reads generated content from
{CORTEX_PATH}/content/ - Reads manual notes from
{CORTEX_PATH}/content/notes/and{CORTEX_PATH}/content/intent/
cerebro-tui (Feature Branch)
Interactive terminal UI for browsing projects without opening a browser. Shares cerebro-core types with the CLI and reads the same cortex content that mdbook renders.
Views implemented:
- Home/Dashboard — Project overview
- Project detail — Full context for a single project
- Journal — Date-grouped activity logs
- TODOs — Searchable/filterable TODO list
- Config — View/edit configuration
Content Boundaries
The cortex’s content/ has a strict split between auto-generated and manual content:
Auto-generated (cerebro writes, humans don’t edit)
| File | Content |
|---|---|
index.md | Dashboard homepage with project cards |
projects/{name}.md | Per-project status pages |
journal/{year}/{mm}/{dd}.md | Daily activity logs |
today.md | Last 24 hours of activity |
this-week.md | Last 7 days of activity |
Manual (humans write, cerebro doesn’t touch)
| File | Content |
|---|---|
intent/daily/ | Daily goals |
intent/weekly/ | Weekly goals |
intent/monthly/ | Monthly goals |
intent/yearly/ | Yearly goals |
notes/ | Evergreen notes and documentation |
notes/projects/ | Per-project manual notes |
SUMMARY.md | mdBook navigation structure |
The boundary is enforced by an AGENTS.md file in your cortex which instructs AI agents which files are safe to overwrite and which are human-only.
Cron Workflow
0 5,9 * * * cerebro build && mdbook build
59 23 * * * cerebro build && mdbook build
Runs from your cortex. Scrape → generate → render, three times daily.
Shared Type System
All binaries share types from cerebro-core:
ProjectConfig — Name, repo_path, active flag
ProjectContext — Full context: commits, sessions, todos, notes
ManualNotes — Status, next actions, journal excerpt
Config — Settings + project list
Cache — Timestamps for incremental scraping
The TUI uses these same types to render views, ensuring consistency between what you see in the browser (mdbook), the terminal (TUI), and what OpenCode reads (MCP).
Development Setup
Prerequisites
- Rust 1.85 or later
- Cargo (comes with Rust)
Building
# Development build
cargo build
# Release build
cargo build --release
Testing
cargo test
Quality Checks
# Format check
cargo fmt --check
# Lint check
cargo clippy -- -D warnings
# All quality checks
cargo check
Workspace Structure
cerebro/
├── crates/
│ ├── cerebro/ # CLI tool
│ ├── cerebro-core/ # Shared types
│ ├── cerebro-mcp/ # MCP server
│ └── cerebro-tui/ # Terminal UI
├── docs/ # Documentation
└── book.toml # mdbook config
Running Locally
# Build and run
cargo run -- build
# With arguments
cargo run -- build --project my-project
MCP Server
The MCP server lives in crates/cerebro-mcp/ and provides tools for OpenCode integration.
Building
cargo build --release -p cerebro-mcp
The binary is output to target/release/cerebro-mcp.
Running
# Via cargo
cargo run -p cerebro-mcp
# Or directly
./target/release/cerebro-mcp
Environment Variables
| Variable | Default | Description |
|---|---|---|
CORTEX_PATH | (required) | Path to your cortex (contains config.toml) |
RUST_LOG | info | Log level (debug, info, warn, error) |
AI Workflow Audit Plan
- Source
- Dru Knox, Stop Prompting, Start Engineering: The “Context as Code” Shift, YouTube, February 25, 2026
This document captures actionable infrastructure changes to improve how cerebro manages AI workflows. The goal is to treat AI context and session behavior as observable, measurable systems, not as opaque chat sessions.
Mindset: From IC to Steward
When using AI agents, the human role shifts from individual contributor to tech lead. The job is no longer writing all the code directly; it is ensuring good code can be written by maintaining standards, documentation, and quality gates.
This shift is noted here but requires no tool changes. It is a framing device for the infrastructure decisions that follow.
Problem: Non-Deterministic Tooling Waste
AI agents are non-deterministic. They repeat tasks, thrash between approaches, make unnecessary tool calls, and burn tokens on false paths. Without telemetry, this waste is invisible. We need to instrument the agent’s behavior so we can detect and eliminate waste programmatically, not by watching every session.
Audit Infrastructure
1. Session Log Analysis Scripts
OpenCode stores session logs locally in SQLite (~/.local/share/opencode/opencode.db). We
already read this database for dashboard rendering. We should add analysis scripts that
mine session history for waste patterns.
Waste Patterns to Detect
| Pattern | Description | Signal |
|---|---|---|
| Thrashing | Agent switches approaches repeatedly without progress | Same tool called >3x with similar args in one session |
| Retry loops | Agent retries after failures without changing strategy | cargo check fails, agent reruns same command |
| Over-tooling | Agent uses tools when direct reasoning suffices | File read followed by immediate file read of same content |
| Apology tax | Agent apologizes and backtracks | Phrases like “sorry”, “you’re absolutely right” in assistant messages |
| Token bloat | Context window fills with redundant planning | Repeated restatement of plan without new information |
Proposed Script: cerebro audit sessions
A new CLI subcommand (or standalone script in scripts/) that:
- Queries the opencode database for recent sessions
- Parses message history for waste patterns
- Outputs a summary report with:
- Sessions analyzed
- Waste events detected (by category)
- Estimated token cost of waste
- Suggested configuration changes
Example output:
Sessions analyzed: 12
Thrashing events: 3 (25% of sessions)
Retry loops: 7 (58% of sessions)
Over-tooling: 2 (17% of sessions)
Top suggestion: Add `cargo check` pre-validation to agent context
Affected sessions: 5
Waste pattern: Agent runs `cargo check`, sees error, proposes fix,
runs `cargo check` again without applying fix first.
2. Static Analysis for Hallucination Prevention
As we allow agents to perform more divergent and inductive reasoning, the risk of hallucinated APIs, incorrect types, and phantom dependencies increases. Static analysis is the first line of defense: it catches nonsense before it compiles, before it runs, before it gets committed.
We already enforce clippy::pedantic at the workspace level. This section proposes expanding
that enforcement specifically for AI-generated code paths.
Current State
The project already forbids unwrap(), panic!(), and expect() in production code. This
is an excellent baseline. We should extend this philosophy.
Proposed Additions
| Check | Purpose | How |
|---|---|---|
| Import validation | Prevent phantom crate references | cargo check in CI must pass before any PR |
| Type strictness | Prevent inferred-type hallucinations | Enable clippy::pedantic lints that reject implicit conversions |
| Documentation coverage | Force agents to document public APIs | cargo doc --no-deps must pass without warnings |
| Dead code detection | Catch abandoned experiments | clippy::dead_code as deny, not warn |
| TODO/FIXME enforcement | Prevent permanent placeholder code | Already exists; ensure it runs on AI-generated commits too |
Pre-Flight Hook for Agent Sessions
Consider a lightweight cargo alias or script that agents run before submitting:
# In .cargo/config.toml or agent context
[alias]
preflight = "fmt --check && clippy --workspace -- -D warnings && check"
Agents should be instructed to run cargo preflight before declaring a task complete. This
catches hallucinations at the agent’s workstation, not in CI.
3. Configuration to Prevent Thrashing
OpenCode and similar agents accept configuration that shapes their behavior. We should
codify anti-thrashing settings in the project’s AGENTS.md and explore opencode
configuration options.
Token Budget Awareness
| Setting | Suggestion | Rationale |
|---|---|---|
| Context window limit | Explicitly state the project’s preferred max | Prevents agents from stuffing irrelevant files into context |
| Tool call budget | Configure max sequential tool calls | Forces agent to reason rather than search |
| Retry limit | Cap retries at 2 with forced pause | Prevents infinite retry loops on flaky operations |
Context Hygiene Rules
Add to AGENTS.md:
## Agent Efficiency Rules
1. **Run `cargo preflight` before every completion claim.**
2. **If a command fails twice with the same error, stop and ask.**
3. **Do not read a file you already read in this session unless it changed.**
4. **Before using a new crate or API, verify it exists in `Cargo.lock`.**
5. **Keep context focused: only include files relevant to the current task.**
4. CI/CD Integration
We already use Woodpecker CI. The audit plan should extend CI to catch AI workflow regressions.
Proposed CI Checks
| Stage | Check | Trigger |
|---|---|---|
| Lint | cargo clippy --workspace -- -D warnings | Every push |
| Format | cargo fmt --check | Every push |
| Doc | cargo doc --no-deps | Every push |
| Test | cargo test --workspace | Every push |
| Audit | Run session waste analyzer on last 7 days | Weekly cron (or manual) |
The weekly audit stage is lightweight: it queries the local opencode database (or a centralized copy) and posts a summary comment on the PR if waste patterns spike.
5. Plugin and Linter Integration
Rather than building custom LLM-as-judge evals, we should leverage existing tools and explore opencode plugins that reduce waste.
Tool Inventory
| Tool | Current Use | AI Workflow Enhancement |
|---|---|---|
clippy | Lint enforcement | Add lints that catch common AI mistakes (e.g., unused imports from hallucinated code) |
cargo-deny | License checking | Could extend to detect unexpected crate additions |
lefthook | Pre-commit hooks | Add hook that warns if AGENTS.md context is stale |
dprint | Markdown formatting | Ensure AGENTS.md and context files stay parseable |
Opencode Plugin Opportunities
The opencode ecosystem may support plugins that:
- Intercept tool calls and cache file reads for the session duration
- Enforce a “budget” of tool calls per task
- Auto-run
cargo preflightbefore allowing the agent to report success - Summarize session waste and append it to the cortex journal
These are research items. This plan flags them for investigation.
Measurement: What We Track
We cannot improve what we do not measure. The audit infrastructure should collect:
| Metric | Source | Target |
|---|---|---|
| Session duration | opencode.db | Reduce median by 20% |
| Tool calls per session | opencode.db | Reduce median by 30% |
cargo check failures before success | opencode.db + git log | Reduce retry rate below 10% |
| Clippy warnings on AI-generated commits | git diff + cargo clippy | Zero warnings |
| Agent backtracks (“sorry”, “you’re right”) | opencode.db message text | Reduce by 50% |
Immediate Actions
- Write the session analyzer script. A standalone Rust binary or Python script that
reads
opencode.dband outputs waste statistics. - Update
AGENTS.mdwith agent efficiency rules. Codify the anti-thrashing guidelines. - Add
cargo preflightalias. Make it trivial for agents to self-check. - Schedule weekly CI audit job. Run the analyzer and surface trends.
- Research opencode plugin API. Determine if custom plugins can enforce tool budgets.
Deferred Actions
- Evals / statistical testing: Not pursued. The cost of LLM-as-judge evals outweighs the benefit for this project. We rely on deterministic static analysis instead.
- Automated context updates via PR scanning: Interesting but requires a stable context
format first. Revisit after
AGENTS.mdstructure matures.
References
- Dru Knox, “Stop Prompting, Start Engineering: The ‘Context as Code’ Shift,” YouTube, February 25, 2026
- Cerebro AGENTS.md: Current agent guidelines
- ADR 0005: MCP server for OpenCode: Existing OpenCode integration
Architecture
Cerebro is organized as a Rust workspace with three crates.
Crates
cerebro
The main CLI tool. Entry point that:
- Parses command-line arguments
- Coordinates collection and generation
- Manages the cache
crates/cerebro/src/
├── main.rs # Entry point
├── cli.rs # CLI argument parsing
├── config.rs # Configuration loading
├── cache.rs # Cache management
├── collectors/ # Data collection
└── generators/ # Output generation
cerebro-core
Shared types used across crates:
- Configuration structures
- Cache models
- Common utilities
cerebro-mcp
MCP (Model Context Protocol) server for OpenCode integration.
Allows AI assistants to query your cerebro dashboard directly.
Data Flow
flowchart TD
subgraph Config["Configuration"]
C[config.toml]
end
subgraph Collect["Collectors"]
O[OpenCode] --> S[Session history]
G[Git] --> CMT[Commits, files]
T[TODOs] --> TC[TODO/FIXME comments]
end
subgraph Generate["Generators"]
D[Dashboard] --> MD[Markdown]
J[Journal] --> MJ[Markdown]
P[Periodic] --> MP[Markdown]
end
subgraph Out["Output"]
ODIR[~/cerebro-dashboard/]
end
C --> Collect
Collect --> Generate
Generate --> Out
Collection Sources
| Source | Data Collected |
|---|---|
| OpenCode | Session history, AI interactions |
| Git | Commits, file changes, branch activity |
| TODOs | TODO, FIXME, HACK, XXX comments |
| Manual Notes | Status, journal entries, intent |
ADRs
1. Record architecture decisions
Date: 2026-04-22
Status
Accepted
Context
We need to record the architectural decisions made on this project.
Decision
We will use Architecture Decision Records, as described by Michael Nygard in his article “Documenting Architecture Decisions”.
Consequences
See Michael Nygard’s article, linked above. For a lightweight ADR toolset, see Nat Pryce’s adr-tools.
2. Monorepo structure with three crates
Date: 2026-04-22
Status
Accepted
Context
Cerebro needs to support multiple use cases: CLI usage for building dashboards, library usage for other tools, and OpenCode MCP integration.
Decision
We will use a Rust workspace with three crates:
- cerebro — CLI application (main binary)
- cerebro-core — Shared types and storage traits (library)
- cerebro-mcp — MCP server for OpenCode integration (binary)
Consequences
Pros
- Clear separation between CLI, library, and MCP concerns
- cerebro-core can be used as a library by other tools
- Each crate can evolve independently
Cons
- Workspace complexity
- More build artifacts to manage
Notes
See crates/ directory for actual structure.
3. Four data collectors
Date: 2026-04-22
Status
Accepted
Context
Cerebro aggregates signals from development activity to generate context. We need to decide which data sources to collect from.
Decision
We will collect from four sources:
| Source | Implementation | Data |
|---|---|---|
| OpenCode | SQLite via opencode_db_path | Session history |
| Git | git2 crate | Commits, modified files |
| TODOs | Regex scan on source files | TODO/FIXME/HACK/XXX comments |
| Manual Notes | notes/projects/{name}.md | Status, journal, intent |
Consequences
Pros
- Comprehensive signal aggregation
- Each collector is independent
- Manual notes provide human context
Cons
- Git collection can be slow on large repos
- TODO regex may false-positive on strings
Notes
Collectors are orchestrated in collectors/mod.rs. Each is async and can run in parallel.
4. Markdown output with mdbook serving
Date: 2026-04-22
Status
Accepted
Context
Cerebro generates a personal dashboard. We need to decide the output format and how to serve it.
Decision
Output will be markdown files served via mdbook:
- Generators produce
.mdfiles - mdbook serves as a local web server
- Output location configurable via
config.toml
Output Structure
{dashboard_path}/
├── index.md # Overview
├── projects/
│ └── {name}.md # Per-project pages
├── today.md # Today's activity
├── this-week.md # Weekly activity
└── journal/
└── {year}/
└── {mm}/
└── {dd}.md # Daily journal
Consequences
Pros
- Human-readable output
- Easy to version control
- mdbook provides search/navigation
Cons
- Requires mdbook for serving
- Static generation (no live updates)
Notes
Default port is 3000. Use cerebro serve --port X to customize.
5. MCP server for OpenCode integration
Date: 2026-04-22
Status
Accepted
Context
We want AI assistants (OpenCode) to query the dashboard directly. This requires a tool protocol.
Decision
We will implement a Model Context Protocol (MCP) server in cerebro-mcp:
Tools Exposed
| Tool | Purpose |
|---|---|
read_project | Read project info + generated page |
list_projects | List all tracked projects |
get_stats | Overall statistics |
read_journal | Read journal entry by date |
read_today | Read today’s journal |
read_intent | Read intent (daily/weekly/monthly/yearly) |
search_todos | Search TODOs across projects |
Configuration
Requires CORTEX_PATH environment variable pointing to your cortex.
Consequences
Pros
- AI can access context directly
- Enables AI-assisted workflow
- Standard protocol
Cons
- MCP SDK dependency
- Server maintenance
Notes
Binary: target/release/cerebro-mcp. Configure in OpenCode’s opencode.json.
6. Cache strategy for collectors
Date: 2026-04-22
Status
Accepted
Context
Collectors (git, opencode, todos) can be expensive. We need to avoid re-running them on every build.
Decision
We will use file-based caching:
- Cache stored in
cache.jsonin system cache directory - Each entry tracks:
opencode_last_query,git_last_scan,todo_last_scan --freshflag bypasses cache entirely--project <name>limits to specific project
Cache Invalidation
Cache is invalidated by:
--freshflag (user override)cache_ttl_hourssetting in config.toml- Manual
cerebro statusshows cache status
Consequences
Pros
- Fast subsequent builds
- Respects user intent
Cons
- Stale data if TTL too long
- System cache dependency
Notes
See cache.rs for implementation.
7. TOML configuration format
Date: 2026-04-22
Status
Accepted
Context
Cerebro needs a user-friendly configuration format that supports multiple projects and settings.
Decision
We use TOML with two sections:
[settings]
cache_ttl_hours = 24 # Cache TTL in hours
opencode_db_path = "..." # Path to OpenCode SQLite DB
output_dir = "..." # Dashboard output directory
[[projects]]
name = "project-name" # Display name
repo_path = "~/Projects/..." # Git repository path
note_path = "./Notes/..." # Manual notes path
active = true # Include in build
Consequences
Pros
- TOML is human-readable and well-supported in Rust
- Clear separation between settings and project definitions
- Easy to add new fields without breaking existing configs
Cons
- Requires toml parsing dependency
~path expansion needed
Notes
Parsed in cerebro-core via toml crate. ~ expansion in config.rs.
8. TODO regex pattern and file scanning
Date: 2026-04-22
Status
Accepted
Context
We need to reliably find TODO/FIXME/HACK/XXX comments in source code while avoiding false positives.
Decision
Regex pattern:
(?i)\b(TODO|FIXME|HACK|XXX)\b[\s:]*(.*)$
Features:
- Case-insensitive matching (
(?i)) - Word boundary anchors (
\b) - Captures keyword + optional text after
:or whitespace
File scanning:
- Uses
ignore::WalkBuilderto respect.gitignore - Skips binary/non-source extensions (png, jpg, pdf, zip, etc.)
Sorting priority: FIXME > TODO > HACK > XXX
Consequences
Pros
- Case-insensitive catches
todo:,TODO:,Todo: - Respects gitignore automatically
- Skips common false positives (minified JS, images)
Cons
- Won’t catch multi-line comments
- Won’t catch TODO in strings without keyword prefix
Notes
See collectors/todos.rs for implementation.
9. Storage trait for dependency injection
Date: 2026-04-22
Status
Accepted
Context
Collectors need to read files and access git/OpenCode databases. We want to enable testing without real filesystems.
Decision
We define Storage trait with default implementations:
#![allow(unused)]
fn main() {
pub trait Storage: Send + Sync {
async fn exists(&self, path: &Path) -> bool;
async fn read_to_string(&self, path: &Path) -> Result<String>;
// ...
}
pub trait Git: Send + Sync {
async fn get_commits(&self, repo: &Path, n: usize) -> Result<Vec<GitCommit>>;
async fn get_modified_files(&self, repo: &Path) -> Result<Vec<FileChange>>;
// ...
}
}
Implementations:
TokioStorage— Uses tokio for async file I/OGit2— Usesgit2crate for git operationsSqliteDb— Usesrusqlitefor OpenCode DB
Consequences
Pros
- Testable without real filesystem
- Swap implementations (e.g., mock storage for tests)
- Clear abstraction boundaries
Cons
- Trait indirection overhead
- More complex DI setup
Notes
See cerebro-core/src/storage.rs.
Why Cerebro Uses MCP: The Right Tool for the Job
The Job Being Solved
The cerebro MCP server solves this specific problem:
Provide AI assistants with standardized, secure access to cerebro’s aggregated developer activity data to enable context-aware assistance during coding tasks.
More specifically:
- Cerebro collects and processes data from: OpenCode sessions, git commits, TODO comments, manual notes, etc.
- This data is stored in a cortex (configured via
CORTEX_PATH) - The value isn’t just in collecting it, but in making it accessible to reduce context switching
- AI assistants (like those in OpenCode, Claude Code, etc.) need to query this data to provide relevant, personalized assistance
Why MCP is the Right Tool
1. MCP Matches the Data Access Pattern Perfectly
MCP has three core concepts that align exactly with cerebro’s needs:
Resources (for data exposure):
- Cerebro’s primary asset is its data store
- MCP Resources are perfect for exposing:
- Project information (
cerebro://projects/{name}) - Journal entries (
cerebro://journal/{date}) - Intent/goals (
cerebro://intent/{period}/{identifier}) - TODO items (
cerebro://todos?project={name}) - Search results (
cerebro://search?query={term})
- Project information (
Tools (for actions):
- Beyond reading data, users may want to trigger actions:
cerebro_build- Trigger a dashboard rebuildadd_journal_entry- Add a manual noteupdate_project_status- Mark project as active/inactiverefresh_cache- Force data re-collection
Prompts (for predefined interactions):
- Common query patterns could be predefined:
summarize_recent_activityget_project_statusfind_related_todos
2. Standards-Based Integration Eliminates Custom Work
Without MCP, cerebro would need to:
- Build custom HTTP/WebSocket APIs for each assistant type
- Document and maintain separate integrations for OpenCode, Claude Code, etc.
- Handle authentication, rate limiting, and error handling per integration
With MCP:
- Implement the MCP protocol once
- Any MCP-compatible assistant can automatically discover and use cerebro’s capabilities
- OpenCode, Claude Code, and other MCP hosts handle the client-side complexity
- Single source of truth for what data/actions are available
3. Security and Boundaries by Design
MCP provides natural security boundaries:
- The assistant can only access what the MCP server explicitly exposes
- No risk of arbitrary database access or unintended side effects
- Tool invocations require explicit approval (configurable via permissions)
- Read-only resources vs. write-capable tools are clearly distinguished
4. Layering on Existing Infrastructure is Efficient
Cerebro already had:
- Data collection logic (OpenCode, git, TODOs)
- Processing and storage systems
- Dashboard generation algorithms
- Query capabilities for the web interface
The MCP server is a thin adaptation layer that:
- Exposes existing functionality through standard MCP interfaces
- Requires minimal new business logic
- Leverages all the existing data processing work
- Avoids re-implementing core cerebro features
5. Enables Ecosystem Benefits
By adopting MCP, cerebro gains:
- Compatibility with growing list of MCP-hosted assistants
- Future-proofing as more tools adopt the standard
- Ability to benefit from MCP ecosystem improvements
- Reduced integration burden for users trying multiple assistants
Why It’s Not Just a RAG Problem
While cerebro’s data could be used in a RAG (Retrieval-Augmented Generation) system, MCP is more appropriate because:
RAG is a pattern; MCP is a protocol.
- RAG describes how to retrieve and use context within a single LLM interaction
- MCP defines how systems connect to provide that context and more
MCP is broader than just retrieval:
- RAG focuses on fetching relevant information for a prompt
- MCP also supports invoking actions (tools) and defining interaction patterns (prompts)
- Cerebro isn’t just about reading data - it may want to allow assistants to trigger builds, add notes, etc.
They can work together:
- An agent could use MCP to discover what cerebro offers
- Then use RAG techniques to find the most relevant parts of large datasets
- Or use MCP resources as the data source for a RAG system
Concrete Example: How an Assistant Uses Cerebro MCP
When a user asks in OpenCode: “What did I work on yesterday in my web-project?”
- OpenCode (as MCP host) connects to cerebro-mcp server
- Server advertises available resources/tools via MCP protocol
- OpenCode sees resources like:
cerebro://journal/2026-04-16,cerebro://projects/web-project - OpenCode reads the journal resource for yesterday
- Optionally reads project-specific data
- Combines this with the user’s question to form a complete prompt for the LLM
- LLM responds with a summary of yesterday’s work on web-project
- If user wants to take action (e.g., “Mark this project as inactive”), OpenCode can invoke the appropriate MCP tool
Addressing the “RAG-shaped problem” intuition
You’re right that at its core, this is about making data available to augment LLM context - which is what RAG does. However:
- MCP solves the “how do we get the data to the assistant?” problem (the connection and discovery layer)
- RAG solves the “how do we find the right data within a large corpus?” problem (the relevance filtering layer)
- Cerebro needs both layers:
- MCP provides standardized access to the cerebro data store
- RAG-like techniques could be used internally by cerebro to rank journal entries by relevance, or by the assistant to process large result sets
MCP is the right foundational choice because it establishes the standard connection mechanism. Whether that data then gets used via simple retrieval, RAG, or other methods is a separate concern that MCP doesn’t prescribe - it simply makes the data available in a standardized way.
Conclusion
The cerebro MCP is the right tool for the job because:
- Job: Make cerebro’s developer activity data accessible to AI assistants in a standard, secure way
- MCP Fit: MCP’s Resources/Tools/Prompts map directly to cerebro’s data access and action needs
- Advantages: Standards-based, secure, leverages existing infrastructure, enables ecosystem benefits
- Not Overkill: It’s not unnecessarily complex - it’s the minimally sufficient standard protocol for this exact use case
- Complementary: Works well with RAG techniques rather than replacing them
This isn’t just following trends - it’s applying the right tool (MCP) to the right problem (standardized AI assistant access to structured personal data stores).