The Open Brain

A shared brain for every MOTMaster repository

The Open Brain — the MOTLogs Architectural Ledger — reads all nine MOTMaster codebases, understands each piece of code, and serves that understanding to AI agents and developers over one authenticated endpoint. It turns "grep the whole tree and read files until you find it" into a single token-cheap, graph-aware question.

In one sentence: a .NET 10 service that chunks every repo on real code boundaries, asks an LLM what each chunk is for, embeds it locally, stores it in Qdrant next to a cross-stack dependency graph, and exposes it as Model Context Protocol (MCP) tools at https://brain.motlogs.com/mcp — 46 declared, of which 25 are advertised today.

⤢ Click to enlarge
The Open Brain load & analysis harness Source repositories are shipped to the host and trigger an ingest that discovers changed files, chunks and analyses each one, embeds it locally, builds a cross-stack graph, writes everything to Qdrant, runs whole-corpus post-passes, and serves it to AI agents over MCP. The load & analysis harness Source repositories → understood, embedded, graphed & served — the end-to-end ingest pipeline Ship / store / serve Per-file compute Graph Skip / guardrail 1 SHIP & TRIGGER — operator-driven (Deploy-Hetzner.ps1) 9 SOURCE REPOS motlogs · agent · scout · sql · wikiopenbrain · n8n · global-spec · infra HOST SNAPSHOT sources/current — atomic symlinkshipped as git bundles INGEST WEBHOOK POST /api/ingest · shared secretacks 202, runs in background IngestionEngine.RunAsync single run-lock (Semaphore 1,1) —one ingest at a time 2 DISCOVER — incremental, cache-gated MERKLE SUBTREE SCAN skip an unchanged directory in onehash compare — no files read PER-FILE BYTE-HASH SKIP SHA-1 the raw bytes;an unchanged file is skipped UNCHANGED → SKIP ( ≈ $0 ) no chunk · no LLM call · no embed —a no-op re-sync does almost nothing 3 PER-FILE PIPELINE — for every changed file (parallel up to MaxParallelism) CHUNK Roslyn C# · MD headings1/proc SQL · TS/Vue · plain NORMALIZE + HASH CRLF / whitespace fold →stable content_hash (SHA-1) GROQ ANALYSIS intent · layer · pattern (+rubric)1 call · cached · budget-capped QUALITY + SIGNALS q_* rubric · pattern signatures· log-template hashes LOCAL EMBED · 384-d code_vector +design_vector (ONNX, on CPU) 4 GRAPH BUILD — parallel lane (runs before file processing; enriches the chunk payload) GRAPHIFY / REPO pre-shipped graph.json oron-demand CLI (never fatal) SQL PRE-EXTRACT procs · tables · views(regex — graphify skips T-SQL) MERGE cross-repo name-match+ cross-stack edges ORDERED ENRICHMENT PASSES Join → Reachability → LayerSkip →UsageEdges → Layout → Binary tiles PARALLEL LANE STORE QDRANT — motlogs_unified_architecture 1 point per chunk · named vectors code_vector + design_vectorpayload: layer · pattern · intent · q_* · git · graph · line-coords · is_latest POST-PASSES · FULL INGEST ONLY CROSS-STACK EDGES route ↔ fetch ·sproc ↔ CREATE PROC CONCEPT CLUSTERS k-means / design_vector→ concept_id AGENTS.md per-repoorientation docs SERVE · ALWAYS-ON, SERVER-SIDE MCP /mcp — 46 tools (25 advertised) · Bearer auth Hybrid RRF (design + code + BM25) · graph & trace ·orient · refactor-safety · recall · cited answers AI AGENTS Claude Code · Antigravity · any MCP client —ask the brain instead of grepping the tree HARNESS GUARDRAILS › content-hash → analysis cache — $0 re-runs › Groq budget cap — never overspends › idempotent MD5 chunk IDs — no duplicates › ledger_id carry — history survives renames › versioning + GC — drift without bloat › source & graph snapshots — restorable › require-ledger hook — answers stay grounded
The end-to-end harness. A deploy ships each repo to the host and fires the ingest webhook; the engine discovers only what changed, then chunks, analyses, scores and embeds every file while building the cross-stack graph in parallel — all of it landing as one enriched point per chunk in Qdrant, which whole-corpus post-passes stitch together and the MCP endpoint serves to agents. In the code the graph build actually runs before per-file processing (its edges enrich each chunk's payload), and the cross-stack & concept passes run only on a full ingest; they are drawn in reading order here for clarity.

Scale, as of 2026-09-13: golden-set retrieval baseline recall@1 0.5125 / recall@5 0.75 (2026-09-12, PR #149; latency p50 25 ms uncached); against a real 79,633-chunk large-codebase corpus (efcore) the same retrieval held recall@5 0.950, recall@1 0.825, MRR 0.8865 at p95 43.8 ms (target was ≤1.5 s); 1,535 C# tests passing (up from 1,503) plus Ran 299 tests … OK on the Python tools. Figures and sources on Measured value.

What changed recently

The upgrade wave of 2026-08-07 → 2026-08-09, plus the 2026-09-12/13 scale-plan push. Dates are the commit dates on main; each row links to the page that documents it in full.

DateWhat shippedRead more
2026-09-13The precise C# lane goes live. find_definition/find_references/find_implementations (Roslyn-backed, compiler-verified) are advertised now that Precise:Enabled=true in production, and a fail-loud fix (#191) makes a degraded workspace distinguishable from "the symbol genuinely doesn't exist". Also: the mot-ledger consult gate moved to a single, versioned, user-level wiring, and its pre-registered A/A/B test started. MCP tools & deploy · Governance layer
2026-09-12Eight reference/refactor-safety tools un-hidden. reference_set, blast_radius, blast_radius_diff, refactor_plan, cross_stack_path, prior_decisions, find_similar and caller_recall_audit were previously trimmed from tools/list and were never called in the change-safety suite as a result; advertising them changed usage decisively (reference_set: 0 → 16 calls in the next re-test). Also: compact answers went live by default (Mcp:DefaultFormat=toon, Mcp:DefaultLimit=3). MCP tools & deploy
2026-08-07A cheaper MCP surface. Every query_ledger hit now leads with its navigable span (path L<from>-<to>); symbol_lookup inlines the definition of an exact match instead of telling the agent to fetch it next turn; the advertised tool list was trimmed to the 14 that carried the measured usage at the time (since grown — see the 2026-09-12 row above). MCP tools & deploy
2026-08-08The Ask page. One human question box over the same hybrid search the agents use, with symbol type-ahead. It is the only surface that sends source=ask — which is what makes a human question separable from an agent's. Ask
2026-08-09Three coverage holes closed. motmaster-infra — the deploy engine — is indexed for the first time, so "how do we deploy X" is answerable from the deploy scripts themselves rather than reconstructed from other repos' mentions. Consolidated SQL schema files are chunked per CREATE TABLE. Plain .js files the chunker had been silently discarding are back. Chunking · The load process
2026-08-09Asked & answered. An FAQ mined from real query traffic — 25 entries, built by tools/faq-builder.py from 20,781 logged calls spanning 2026-05-25 → 2026-08-09. No answer text is generated: the builder only ever selects between hits the store already recorded, and a cluster with no recorded answer is dropped rather than given a plausible-looking one. Asked & answered
2026-08-09The weekly digest. Eight endpoints' worth of "what changed this week" assembled into one dated page, every figure read from a live response body captured at generation time. Weekly digest
2026-08-09The change-safety suite. 40 cold sessions — 20 tasks × 2 arms — against the live build. The change-plan half is n=10 per arm; the trap half is the other ten. The verdict is parity, and it is quoted rather than paraphrased below. Measured value

The change-safety verdict, in its own words

The suite that asked whether the ledger makes change planning safer is written up in docs/CHANGE_SAFETY_RESULTS.md. Its §9 conclusions are reproduced here without softening, because a result this equivocal is exactly the kind that gets rounded up in a summary:

"On this suite, against the live build, the ledger and control arms are at parity on change planning: committed touch-point recall 0.542 vs 0.559 (−1.7 points) and precision 0.766 vs 0.791 (−2.5 points), with head-to-head 1 win / 7 ties / 2 losses […] The one defensible advantage is efficiency: 12.8 vs 14.8 turns for plans of equal correctness — cheaper and slightly tighter, not righter […] blast_radius, reference_set, refactor_plan and cross_stack_path were on the allowlist and were called zero times across all 20 ledger sessions, so what was measured is the ledger being available rather than its blast-radius surface being used […] Nothing here supports building the PR pre-flight bot on a better-blast-radius claim, and nothing here refutes that claim either — it was never exercised."

The PR pre-flight tool referred to there exists — tools/pr-preflight.sh asks the ledger what a diff disturbs and prints the report. It is print-only by default: posting a comment requires an explicit --post. Its acceptance run against a real merged PR is captured in docs/PR_PREFLIGHT_ACCEPTANCE.md.

"Zero times" above is no longer current: those four tools were un-hidden from tools/list on 2026-09-12, and a same-suite re-test found agents pick them up once advertised (reference_set 0 → 16 calls) but that this did not resolve the parity finding — see the dated 2026-09-12/13 section on Measured value for both re-tests, stated exactly as their evidence READMEs state them.

Why it exists

An AI coding agent with no shared memory rediscovers the codebase on every task: it greps, opens files, reads thousands of tokens, and still misses the cross-repo link between a UI button and the stored procedure it ultimately calls. That is slow, expensive in tokens, and error-prone.

The Open Brain is the durable, cross-repo memory that removes that tax. Because embedding and search run locally and server-side, an agent asks the brain instead of reading the tree — and the brain answers with the exact file, the exact lines, the callers, the tests, and the prior decisions.

Why it matters

Every question answered from the index is a multi-grep, multi-file-read detour that never happens. Recall is measured as token efficiency: a hit the brain surfaces is tokens the agent never spends hunting.

The engine in one screen

Two paths meet at one Qdrant collection. Ingest is operator-driven and does the heavy, cache-warmable work; query is always-on and cheap. Everything below is the ingest path, left to right, feeding the query path on the right.

  1. Discover — a Merkle directory walk finds changed files across every repo and skips unchanged subtrees with a single hash comparison.
  2. Chunk — each file is split on real declaration boundaries (Roslyn for C#, headings for Markdown, one-per-proc for SQL, brace-depth for TS/Vue) — never a blind window where structure is known.
  3. Analyse — one Groq LLM call per chunk names its intent, architectural layer, and design pattern, plus a code-quality rubric — cached by content hash so it is paid once.
  4. Embed — a local 384-dimension ONNX model embeds each chunk twice: a code vector and a design/intent vector. No API, no per-token cost.
  5. Graph — per-repo dependency graphs are merged and enriched with cross-stack edges (frontend → API → controller → stored proc), reachability, and layout.
  6. Store — every chunk becomes one Qdrant point carrying both vectors and a rich payload (identity, quality, git, graph, coordinates), with idempotent IDs.
  7. Serve — agents query over MCP: hybrid RRF search fuses the two dense lanes with a BM25 lexical lane, then the graph answers "who calls this?" and "what breaks if I change it?"

Two stores, two questions — semantic vs structural

The Store step lands two indices side by side, and they answer different kinds of question. The vector store (Qdrant) is semantic — it finds code by meaning. The graph is structural — it traces relationships someone extracted as edges. Neither subsumes the other: the vector store finds the door; the graph walks the building.

What you wantVector store — semanticGraph — structural
Find code from a description ("where do we validate a VRN?") ✅ matches on meaning — no shared identifier needed ✕ needs a node you already know to anchor on
"What calls this? What breaks if I change it?" ✕ has no notion of edges ✅ node_neighbours, blast_radius, cross_stack_path
Similar / sibling code — even across languages ✅ find_similar, concept_neighbours — no edge required ✕ blind unless a literal call links them
Pin an exact identifier or rare token ✅ the BM25 lexical lane catches it (RRF-fused with the vectors) ~ only if it happens to be a named node
Rank results by relevance ✅ graded similarity score ✕ boolean adjacency only
Still answer when an edge was never extracted ✅ finds it by meaning anyway ✕ returns nothing

That last row is the crux. The graph is only as complete as edge extraction, and it is honest about the gaps — caller recall is partial (the graph is forward-only) and cross-stack lineage reaches SQL for only a fraction of routes. Where an edge is missing, structural traversal is blind but semantic search still surfaces the code. Conversely, vectors never prove a call — only the graph does. So the two pair up rather than compete: query_ledger / orient_me use the vectors to locate; node_neighbours / blast_radius use the graph to trace.

Why it matters

Two indices, one point per chunk. Ask by meaning to get in, then walk verified edges to reason about impact — you never have to choose between "find it" and "prove how it connects". Full detail lives on Vectors & search and Dependency graphs.

What the harness gives you

Each area below is documented in full on its own page — what it does, how it works in the code, and the concrete benefit.

📊

Measured value

What the ledger is actually worth, measured in real sessions with caching on both sides: 27% fewer agent turns, 8.9% less wall clock, better answers where a written reference exists — and cost and tokens reported honestly as unsettled, with every superseded headline kept and explained.

⚙️

The load process

Source → searchable index, end to end: the webhook, incremental Merkle scan, idempotent IDs, ordered enrichment passes, snapshots and versioning.

✂️

Chunking

One language-aware chunker per file type, body-folding skeletons, surgical line coordinates, and the full Qdrant chunk payload.

🕸️

Dependency graphs

A merged cross-repo, cross-stack graph: edge kinds, reachability smells, ForceAtlas2 layout, the WebGL viewer, and honest caller-recall.

🔍

Vectors & search

Local embeddings, two named vectors, three-lane RRF hybrid fusion with BM25, synonyms, cited answers, and the recall eval harness.

🧪

Analysis & quality

Groq intent, the quality rubric, and the multi-agent detect → approve → fix → PR loop with its safety gates.

🧠

Context saving

Session ingest, conversation recall, prior work & decisions, and the visited-node ledger that flattens per-turn token growth.

👥

Team analysis

Per-developer identity, learning-needs, cohort clustering & consistency, adoption metrics, policy enforcement and audit.

💬

Asked & answered

The questions the ledger is actually asked, mined from the query store — each paired with the answer it actually gave, and with the provenance to check that pairing. Generated, never written.

🗞️

Weekly digest

What moved in the corpus this week — size, ingests, routes, load-bearing files, churn, caller reach, outstanding work. Every figure is read from a live endpoint at generation time and the endpoint is named under each heading; an empty section says so rather than carrying last week's number forward.

🛡️

Governance layer

The control plane for agents: prompt/action policy, deny & defer rules, task→model routing with a measured replay engine, and the expert-persona suggestion engine — across four operator screens.

📊

Dashboard & admin

Every dashboard tile and every admin control, and the loopback/tailnet trust boundary that keeps them safe.

🔌

MCP tools & deploy

The full catalog of 46 declared agent tools (25 advertised today), the token-efficiency benchmark, and how the service is deployed and re-ingested.

Three ideas that run through everything

Free to re-run

Embedding is local and offline; LLM analysis is cached by content hash and hard-capped by a dollar budget. A rebuild re-chunks and re-embeds the whole corpus for roughly $0 when the analysis cache is warm — that is, when neither the chunk text, the prompt version nor the model has changed. When any of those moves, every affected chunk is re-analysed and paid for: the 2026-08-05 method-level re-chunk cost $13.62, and the follow-up run against the now-warm cache cost $0.41. Both are on the Measured value page.

Honest about its gaps

Where a capability is wired but dormant — runtime-log edges, the cross-encoder reranker, versioned drift — the system says so rather than faking a number. Those caveats are documented on each page.

Additive and safe

Identity, versioning, auto-fix and telemetry all default off or to "shared", so the brain behaves exactly as before until an operator opts in. Nothing risky happens without a human in the loop.

This handbook is generated from the source code. Every claim links to a file and line so you can open it in the graph viewer or the repo and verify it yourself.

Open Brain — the MOTMaster Architectural Ledger · generated from source 2026-07-07