Bicameral MCP — Architecture Deep Dive

# Git for Specs

A provenance-aware decision layer for your codebase

The Problem

## Hundreds of Verbal Decisions Per Week. None Linked to Code.

Every team makes decisions in meetings, PRDs, Slack threads. The disconnect creates five SDLC friction points:

# | Smell | What Happens | Bicameral Fix
--- | --- | --- | ---
CONSTRAINT_LOST | Rate limit surfaces mid-sprint, not at design time | pre-flight context via bicameral.preflight
CONTEXT_SCATTERED | The "why" split across Slack, Notion, and memory | unified graph via bicameral.ingest
DECISION_UNDOCUMENTED | Verbal "let's do X" never lands in a ticket | decided vs built via bicameral.history
REPEATED_EXPLANATION | Same context tax paid twice | full provenance via bicameral.search
TRIBAL_KNOWLEDGE | Only one person knows why | institutional memory via bicameral.drift

Core value: drift detection — knowing a 3-week-old decision is now inconsistent with what shipped.

Three Use Cases — Shipped Today

## What This Looks Like in Practice

Pre-flight Check
Requirement Gap Detection
→ Eliminates CONSTRAINT_LOST — no more surprise requirements mid-sprint
Dev starts a task. AI agent calls bicameral.preflight first.
🤖 Found 2 prior decisions about checkout rate limiting:
• reflected — "100 req/min per tenant" (Sprint Mar 5)
• pending — "Burst to 200 for enterprise tier" (PRD v3)
⚠ The enterprise burst tier isn't implemented yet. Should I account for it in this task?
Post-Meeting Ingest
Decisions → Status Board
→ Eliminates DECISION_UNDOCUMENTED — verbal agreements become trackable artifacts
Paste transcript. Bicameral extracts decisions, auto-grounds to code, shows live status.
SPRINT PLANNING — MAR 12
reflected Rate limit 100/min → RateLimiter.check
reflected Stripe-only payments → PaymentProcessor
pending Add retry with backoff → HttpClient.send
ungrounded Add SSO support → no match
4 decisions extracted • 3 auto-grounded • 1 needs code
Pre-Commit Drift Gate
Git Hook Blocks Drift
→ Eliminates TRIBAL_KNOWLEDGE — silent decision violations caught before merge
Developer commits. A pre-commit hook calls bicameral.drift on changed files.
$ git commit -m "switch to PayPal"
bicameral pre-commit hook
checking payments/processor.py...
✗ DRIFT DETECTED
Decision: "Stripe only for payments"
Source: Sprint planning Mar 5
Symbol: PaymentProcessor.charge
Evidence: PayPal import added
Commit blocked. Resolve with /bicameral:supersede or --no-verify
Decision context shared via version control, allowing for organic cross-functional context-sharing and alignment

Auto-Grounding

## From Transcript to Code — Automatically

Input Span
Sprint Planning — Mar 12
PM: "...so for the checkout flow, we need to apply a 10% discount on any order over $100. The marketing team confirmed this at the offsite..."
source: meeting transcript • speakers: [PM, Eng Lead]
→
extracted_from
Decision
"Apply 10% discount on orders over $100"
reflected confidence: 0.87
rationale: marketing offsite confirmation
→
maps_to
Code Region
pricing/discount.py:42–67
42 class DiscountService
43 def calculate
44 if order.total > 100:
45 return order.total * 0.9
content_hash: a3f2c8... (SHA-256) • pinned: c7a1b3e
No LLM in the grounding path — tree-sitter + BM25 + graph search. Deterministic. Fast. Auditable.

Design Principle

## Selection Before Generation

A deterministic core that any model can reason over. Confidence-scored edges bridge natural language decisions to code, turning probabilistic grounding into auditable, version-controlled knowledge.

The Challenge

## Two Paths That Never Meet

Product Evolution

Doc | Decision | Status
--- | --- | ---
PRD v1 | "Stripe only" | ✓ current
PRD v2 | "Add PayPal support" | ⚠ draft
Meeting | "Cache in Redis" | verbal
Slack | "Don't touch auth" | ✗ buried

Scattered across tools. Contradicts itself silently.
⇵
the gap
Code Evolution
main
└─ feat/payments
adds PayPal (violates PRD v1)
✓ git merge: clean
⚠ decision conflict: invisible
Git tracks what changed, not why it should or shouldn't.

Everyone holds a piece of the truth. Drift is invisible until it's expensive.

The Solution

## Claude as the Meeting Ground

1. Everyone talks to Claude — PMs share product intent, devs surface code constraints, architects record trade-offs. Discoveries and new insights are captured instantly.
2. Decisions become an append-only log — exposed as JSONL event files committed to git, per-user files (events/{email}.jsonl) = zero merge conflicts
3. Local DBs materialize on demand — binary databases are local views, rebuilt from the decision log on startup. Always re-derivable.
Jin ingests transcript → git push
Silong does git pull → Jin's decisions appear locally
Silong ingests PRD → git push
Jin does git pull → Silong's decisions appear locally
No coordination beyond normal git workflow.
git merge → ZERO CONFLICTS. Always.
.bicameral/
events/ ← COMMITTED
jin@co.com.jsonl
silong@co.com.jsonl
config.yaml ← shared
local/ ← GITIGNORED
ledger.db (materialized)
code-graph.db
watermark

CocoIndex Materialization

## Two Sources, One Unified Decision Ledger

Two fundamentally different data sources — an append-only decision log and a branching git DAG — are incrementally ingested by CocoIndex and materialized into a unified SurrealDB decision graph.

Decision Log
events/*.jsonl
append-only, immutable
•
Git DAG
source files at HEAD
branching, mutable, non-linear
↓
Decision Ledger
SurrealDB graph
input_span → decision → code_region

CocoIndex Property | How It Applies
--- | ---
Fingerprint-based change detection | Decision log: replay only after watermark offset. Code: re-index only changed files by mtime
Multi-source composition | Two flows with different update cadences (append-only vs DAG) → unified decision graph
Content-addressed identity | Code regions identified by SHA-256 hash — immune to rename, reformat, rebase
Behavior versioning | Grounding algorithm improves? Bump version → force re-materialization

On startup / after git pull: read watermark → glob new events + changed files → incrementally replay into ledger — idempotent & incremental

Complete Architecture

## Bicameral MCP Server

MCP Tool Layer (13 tools)
bicameral.ingest
decisions from meetings
bicameral.preflight
pre-flight context
bicameral.drift
file drift check
bicameral.search
search decisions
bicameral.brief
feature brief
bicameral.history
decision dashboard
bicameral.link_commit
sync commit hashes
+ 6 more
judge_gaps, ratify, resolve_compliance, update, reset, dashboard
Code Locator: validate_symbols • search_code (BM25 + graph) • get_neighbors • extract_symbols
Adapter Layer (dual-write)
Solo
write → local ledger.db only
Team
write → local DB + event file (git-committed)
Local State (.bicameral/local/) — gitignored
ledger.db
SurrealDB decision graph
code-graph.db
SQLite + sqlite-vec index
Shared State (.bicameral/events/) — committed
events/
per-user .jsonl files, append-only, zero merge conflicts
Materialization (CocoIndex) — incremental, fingerprint-based, idempotent
On startup: watermark → glob events → filter new → chronological replay → update watermark
Intelligence Pipeline
Auto-Grounding
BM25 → tree-sitter → maps_to edges
Drift Detection
SHA-256 hash comparison → drift flag (L1)
Re-Grounding
re-check stale intents on index refresh
Without Bicameral
✗AI generates fast — no one knows if it matches what was decided
✗Decisions in Slack, memory, one person's head
✗Drift invisible until QA — rework is the default
✗Code review = only gate, reviewers = bottleneck
✗More AI = more slop = more expensive misalignment
With Bicameral
✓Every decision captured, grounded, tracked
✓AI checks prior decisions before writing a line
✓Drift caught at commit time — not in production
✓Context shared via git — no tribal knowledge
✓More AI = compounding quality

Bicameral is the companion for building quality software in the age of AI.

Preparing for a new paradigm of software development.

← → or scroll