← One-pager

// case study · detailed

brain — Detailed case study

The build narrative, key architectural decisions, privacy model, and proof points behind the two-day weekend ship.

A self-hosted, agent-readable personal memory and identity system. Postgres + pgvector behind an MCP server, owned end to end, built to be queryable by any AI tool from any device, and built so the schema itself reads as a portfolio piece.

The hook

Every new Claude or ChatGPT session started as a stranger. Brian was re-litigating the same decisions because his own past reasoning was not queryable, and the obvious fixes were all dead ends. Notion and Obsidian were siloed and not machine-readable, hosted memory products were shallow and vendor-locked, and built-in AI memory could not be pointed at a real schema or carried between tools. So over a single weekend in late April 2026 he built brain: four data layers (Capture, Attention, Identity, Thinking) on top of a vendored open-source foundation, fronted by an MCP endpoint on his own domain, with a two-tier privacy model that lets a work device read a curated slice and never the rest. He shipped v0 in two days, backfilled three years of his own thinking history into it, and stood up a public dashboard that reads straight from the database, so the artifact and the proof of the artifact are the same object.

Timeline

The dated record below reconciles Brian's own captured-thinking entries against real commit history across four repositories (brain, brain-dashboard, bfurg-brain, brain-landing). Every motivation and date claim in his reasoning records corroborates the git history; no date conflicts were found. The only divergences are growth and doc-drift, flagged inline.

2026-04-27, day one: foundation. First commit to brain/: "Initial scaffold: vendor OB1 + identity/thinking layer schema." The same day, the server moves into Supabase's functions convention, the Edge Function is deployed and verified end to end, and the first identity-layer backfills land (Notion, ~/.claude/, Helical projects, with embeddings via OpenRouter). 13 commits in one day. This matches the canonical framing record dated the same day: a portable, privacy-tiered AI memory layer built schema-first as a portfolio artifact.

2026-04-28, day two: v0 ships, and the corpus arrives. 12 more commits. The full ChatGPT export is ingested ("Stage 2: ChatGPT export backfill - 114 thinking_records + 92 lessons"), the Attention layer is added (YouTube + ChatGPT temporal backfill), and the cross-layer differentiator lands: correlate_attention_with_thinking. The canonical origin record, "Shipped v0 in two days (2026-04-27 to 2026-04-28)," is exactly right. The same day the canonical public URL is wired: bfurg-brain is created ("Vercel proxy for brain.bfurg.com/mcp") and brain's README is updated to make brain.bfurg.com/mcp canonical. The public dashboard is also born here (brain-dashboard initial commit plus "dashboard v0 shell, vaporwave-helical fusion").

2026-04-29, the heaviest build day (26 commits in brain, 9 in the dashboard). This is where the OB1 vendoring is taken to its full depth: enhanced-thoughts columns (Phase 1.5), typed reasoning edges (Phase 2), and the live-retrieval skill (Phase 3). Telegram capture goes multi-modal (voice via Whisper, photo and video via Haiku vision). The Claude.ai export is backfilled (plus 22 thinking_records, plus 26 lessons). The dashboard gets wired to live data behind anon-key RLS. This day is the substance behind the record's observation that each ingestion source paints a structurally different portrait of the same person: ChatGPT reads as experiential and practical, Notion and Helical as professional craft.

2026-04-30, hardening and portfolio polish (15 commits). quality_score is wired to a graph-derived signal (proximity to the thinking corpus), the metadata-sync trigger retires a whole class of backfill, RLS is refreshed, and the docs are brought up to shipped state (README, SCHEMA, RLS-DESIGN, OB1-PROVENANCE). One commit is named "day summary, portfolio credibility through-line."

2026-05-01, the MCP endpoint becomes real infrastructure. OAuth 2.1 and Dynamic Client Registration land ("Bucket E: OAuth 2.1 + DCR - claude.ai connector working"), and the bfurg-brain proxy is taught to forward OAuth and well-known paths and to sanitize the Supabase consent HTML so the claude.ai connector renders. Tooling grows (link_by_search, timezone-correct timestamps). This is also the dated home of the Obsidian positioning record: "Obsidian is the studio. OB1/brain is the field recorder," complement, not competitor.

2026-05-02, synthesis tooling. weekly_review (end-of-window synthesis with optional Telegram broadcast), composite ranking on search, and topic-synonym consolidation (353 to 281 tags). The ChatGPT plus Claude.ai memory migration session is logged here.

2026-05-07, self-critique becomes a feature. The "twenty gaps" register ships: 20 known-unknowns the system cannot answer about itself, alongside the Adversary skill and a dashboard zone ("09 / horizon (twenty gaps)") to surface them. This matches the strategy record dated the same day, including the signature it flags: roughly 180 thoughts against 11 thinking_records over the first nine days, capture outpacing reasoning depth.

2026-05-20, gaps become schema. The gap-tag convention is promoted into the database: gaps smallint[] columns, an extraction trigger, the gap_tally tool, and a gap distribution line in get_context.

2026-05-22, focus thesis locked, and the product gets its own front door. brain-landing is created ("brain.helical.design static landing"), the brain product page is rewritten from the cut Essay 2, and Telegram /search becomes LLM-routed. This matches the strategy record of the same day: helical is a product company building a single product, brain, not a multi-product studio. Essays live on the personal domain (bfurg.com); the product lives on helical.design and brain.helical.design.

Growth since the records, not conflicts: the MCP tool surface grew from 11 at v0 to 16; thinking_records grew from the initial 114 to 130+ after the Claude.ai backfill; the README prose still describes "three layers" in one spot and the feature inventory caught it saying "14 tools." Both are stale against the authoritative four-layer, 16-tool state in SCHEMA.md and the tool registry.

The pain points it was built to solve

The motivation is unusually well-documented, because Brian captured it in his own words as he built, and then narrated it again in the cut Essay 2 ("Why I built a personal AI memory layer"). Five problems sit underneath the project.

Every session starts from zero. New Claude and ChatGPT sessions begin as strangers. Past reasoning is not queryable, so the same decisions get re-litigated and the cost compounds with every new conversation. brain exists to make accumulated context portable across tools and devices, owned rather than rented.

The incumbents each fail in a specific way. Notes apps capture what you think but never how you think over time. Notion holds projects but is not machine-readable. Obsidian is private and AI-grafted-on rather than AI-native. Hosted memory products (Mem, Reflect, ChatGPT memory) are shallow, vendor-locked, weakly private, and, critically for Brian's goal, expose no queryable schema you could hand an interviewer. Each tool was a silo; none survived a device switch with the reasoning intact.

The bottleneck moved from execution to judgment. Essay 2's framing: AI made building cheap, so the scarce thing is no longer can I build it but am I building the right thing, am I thinking clearly or just fast, is the pattern I'm running today the one I want compounding for five years. No tool Brian owned was built to answer those.

Drift looks like productivity. In the first nine days he captured 180 thoughts and produced only 11 thinking_records. Capture is cheap; thinking is slow; the ratio is the tell. brain is partly an instrument to catch the failure mode where you look busy while transforming nothing, which is exactly the trap a cheap-to-build era sets one level up.

Cross-source patterns are invisible from inside any single source. The recurring example: a ChatGPT conversation about upgrading an M1 MacBook looked like indecision on its own, but read together with six YouTube searches on the same topic in the prior two weeks, it was clearly a decision being confirmed, not opened. That read only exists because the instrument can join the Attention and Capture layers. No off-the-shelf product offered that join.

Build narrative and key decisions

Build on a real foundation, then make the extension the point. brain vendored OB1, an open-source personal-brain framework (Supabase + pgvector + MCP server) under FSL-1.1-MIT, rather than starting from a blank file. The provenance is documented table by table in OB1-PROVENANCE.md down to the upstream commit SHA, which is itself a portfolio signal: it shows the judgment of what to reuse, what to adapt, and what to leave behind. The base thoughts table came from OB1; everything that makes brain Brian's, the Identity and Thinking layers, the privacy tiers, the cross-layer correlation, is original work layered on top.

Schema-first, because the schema is the artifact. The guiding decision, stated in the very first reasoning record, was that "the system itself is the portfolio piece." SCHEMA.md opens with: "If an interviewer asks 'show me how you think about modeling a personal knowledge system,' this is the page I'd hand them." Every table choice carries an explicit rationale: why framing, reasoning, and conclusion are three columns rather than one blob; why outcome is nullable and separate from conclusion (the gap between them is the highest-information field for a reasoning post-mortem); why mental_models is a text[] rather than a join table (low cardinality, informal vocabulary, no premature taxonomy).

Four layers, joined at query time. Capture ("what did I just notice?"), Attention ("what did I consume, when?"), Identity ("who am I as an operator?", spanning skills, work patterns, career arc, lessons, and context snapshots), and Thinking ("how do I reason, and how has that reasoning evolved?"). There are deliberately no foreign keys between layers; relationships are computed at query time from embedding similarity plus temporal proximity, which keeps the schema flat and lets new ingestion sources compose without migrations.

The Thinking layer is the differentiator. thinking_records (decision records, mental models, reasoning post-mortems) and the typed thinking_edges graph between them (supports, contradicts, evolved_into, supersedes, depends_on, related_to) are what no notes app and no hosted memory product offered. contradicts answers "have I changed my mind?"; evolved_into drives decay weighting on retrieval. The edges were deliberately deferred at v0, because with zero records there were no edges to draw, and only added once the corpus passed roughly 95 records, when curation made the text clean enough for an LLM classifier to nominate pairs with usable precision. That restraint, not building the graph until the join earns its keep, is a recurring decision pattern.

Privacy as defense-in-depth and fail-closed. Every identity- and thinking-layer row carries a visibility tier (private, work_safe, public, defaulting to private). Three independent layers enforce it. Two pre-shared MCP keys scope which tier an agent can read, and guardWrite rejects a worksafe-scoped write tagged private (Layer A). Postgres tier views fail closed to public (Layer B). Anon-role RLS means the public dashboard only ever sees work-safe rows (Layer C). The thinking_edges_visible view even closes a subtle leak: an edge touching a private record could betray that record's existence, so the view filters edges where both endpoints are non-private before the dashboard sees a row. A work device, by construction, can never read the private corpus.

Backfill three years of self, from multiple sources. v0 was not a demo with three rows. Brian ingested the full ChatGPT export (474 conversations spanning 2023 to 2026, structured-extracted with gpt-4o-mini into 254 high-signal conversations, then 114 thinking_records plus 92 lessons), the Claude.ai export (71 conversations, then plus 22 records and plus 26 lessons), YouTube watch and search history (roughly 70K attention signals), and Notion, Helical, and ~/.claude material into the identity tables. The insight that fell out: the identity layer triangulates across sources rather than aggregating, because each source portrays a structurally different version of the same person.

An MCP endpoint that real clients can actually connect to. The canonical URL is brain.bfurg.com/mcp, served by a small Vercel edge proxy (bfurg-brain) in front of the Supabase origin. Making the claude.ai web connector work required OAuth 2.1 and Dynamic Client Registration (vendored @mcpauth/auth) and a proxy that re-serves the Supabase consent screen as real HTML. Claude Code, Claude Desktop, claude.ai web, ChatGPT, Cursor, and a multi-modal Telegram bot can all reach it. This is the difference between "a database I query" and "memory my agents have."

The public dashboard makes the artifact legible. brain-dashboard (Next.js and React, reading Supabase directly via PostgREST with no app server) renders the work-safe slice as nine numbered zones ("Signal Threads"), including a Knowledge Radar, an activity pulse, cross-domain thinking-edge bridges, top thoughts by graph-derived quality, and a "twenty gaps" horizon zone. It reads from the same database the agents do, so the demo is the system.

Self-critique built into the system. The "twenty gaps" register names 20 questions brain cannot answer about itself, with a gap-tagging convention ([gap N]) promoted all the way into the schema (gaps smallint[] columns plus an extraction trigger plus gap_tally). The Adversary skill surfaces contradicting records on demand, because semantic search returns agreement by default. Building the instrument to audit the instrument is treated as the practice itself.

Positioning resolved into focus. Two strategic calls bracket the project: brain complements Obsidian rather than competing ("Obsidian is the studio; brain is the field recorder"), and, locked 2026-05-22, helical is a product company building a single product (brain), not a multi-product studio. Essays live on the personal domain; the product gets brain.helical.design.

Proof points and metrics

Shipping speed. v0 designed, built, deployed, and backfilled in two days (2026-04-27 to 2026-04-28), corroborated by 25 commits across those two dates. Roughly 92 commits total in brain over the build window.

Corpus (verified against the backfill scripts in-repo). 474 ChatGPT conversations spanning 2023-03-29 to 2026-04-22 (about three years), structured-extracted to 254 high-signal (89 HIGH, 148 MEDIUM, 17 LOW); 71 Claude.ai conversations (2,961 messages, about 20 months); roughly 70K YouTube attention signals (about 130 per day over about 17 months); 114 thinking_records at first ingest, 130+ today after the Claude.ai backfill; roughly 118+ lessons across sources; 5 Notion sources mapped into the identity tables.

Surface. Four data layers, an 8-table typed schema, 16 tier-aware MCP tools (up from 11 at v0), a typed reasoning-edge graph with six relation types, and a 9-zone public dashboard.

Live and owned. MCP endpoint at brain.bfurg.com/mcp (Vercel proxy to a Supabase Edge Function) with OAuth 2.1 and DCR for the claude.ai connector; public dashboard at dashboard.bfurg.com; product page at brain.helical.design. Reachable from Claude Code, Claude Desktop, claude.ai web, ChatGPT, Cursor, and Telegram.

Stack. Supabase Postgres and pgvector (HNSW), Deno and Hono Edge Functions, the MCP SDK over StreamableHTTP, OpenRouter (text-embedding-3-small, 1536-dim; gpt-4o-mini and Claude Haiku for extraction and classification), Next.js, React, and D3 for the dashboard, and Vercel for hosting and the proxy.

Cost discipline as a design value. The whole three-year ChatGPT extraction ran at roughly $0.40; embeddings were made selective (attention signals use a nullable embedding plus a partial index so passive watches are not embedded) precisely so the system scales cheaply. The economics are part of the engineering judgment.

Portfolio framing

Elevator

brain is a self-hosted, agent-readable personal memory system, Postgres plus pgvector behind an MCP endpoint, that gives any AI tool persistent, portable context about how its operator thinks, owned end to end rather than rented from a vendor. Brian designed it schema-first, shipped v0 in two days, backfilled three years of his own reasoning history across ChatGPT, Claude, YouTube, and Notion, and stood up a public dashboard that reads straight from the live database. It is deliberately built so the schema is the portfolio piece: the artifact and the evidence are the same object.

What it demonstrates

Systems and architecture judgment. Vendoring a real foundation and documenting provenance to the commit; choosing a flat, FK-free, four-layer schema that composes new sources without migrations; deferring the reasoning graph until the corpus made it earn its keep; promoting a tagging convention into the schema only once it proved out. The recurring signature is restraint: building the next thing only when the join surfaces something neither column can see alone.

Product thinking. Naming failure modes (drift, over-philosophizing) before features; positioning explicitly against Obsidian and the hosted-memory incumbents; resolving a multi-surface effort into a single-product company thesis; and treating the public dashboard as the demo because it reads from the same database the agents do.

Privacy engineering. A genuine threat model, that work devices must never read the private corpus, answered with three independent, fail-closed enforcement layers (scoped keys plus guarded writes, tier views, anon RLS) and a view that closes a non-obvious leakage path through relationship edges.

Shipping speed with substance. Two days to a deployed, OAuth-reachable, multi-client endpoint backfilled with three years of real data, not a prototype with placeholder rows, at a total extraction cost under a dollar.

Reasoning in public. The "twenty gaps" register, the Adversary skill, and the captured-thinking records show a builder who instruments his own judgment and names, in public, the open questions the system cannot yet answer about itself.