System Architecture Overview
Bitcoinology is a multi-layer system that ingests podcast transcripts, extracts beliefs using AI, and serves them through a semantic search interface with multi-agent orchestration.
High-Level System Diagram
Layer Breakdown
User Layer
A single-pane terminal-style Next.js 14 app deployed on Vercel. The entire UI operates within a fixed viewport — no scrolling. Navigation happens through screen transitions managed by a Zustand store.
API Layer
Next.js Route Handlers serve as the API surface. All routes require Supabase JWT authentication except public routes (/login, /walkthrough, /share).
| Route | Purpose | Max Duration |
|---|---|---|
/api/query | Main search — routes to direct search or playbook | 60s |
/api/playbook | Deep 4-lens analysis (beliefs, timeline, sentiment, context) | 120s |
/api/graph/data | Speaker aggregations + similarity for graph viz | 1h cache |
/api/threads | Thread CRUD (max 5 active per user) | — |
/api/feed | Community cards, cursor-based pagination | — |
AI / Orchestration
Uses the Vercel AI SDK v6 with OpenAI provider. Two models (aliased as haiku/sonnet in code):
- GPT-4o-mini (
haiku) — Direct search (fast, cheap) - GPT-4o (
sonnet) — Playbook synthesis (deeper reasoning)
AI tools (searchBeliefs, semanticSearch, getEpisode) allow the model to call into Supabase RPC functions and Qdrant vector search.
Data Layer
- Supabase — Postgres 17 with pgvector extension, Row-Level Security, Google OAuth
- Qdrant Cloud — 1536-dim vector similarity search for beliefs
- HuggingFace — Dataset backup (
ryan-beliefengines/podcast-transcripts)
Offline Pipelines
Two separate repos handle data ingestion:
- be-flow-dtd — GPU pipeline: download → Whisper transcription → Pyannote diarization → ECAPA-TDNN speaker ID
- be-podcast-etl — 10-stage belief extraction pipeline (see Pipeline docs)
Key Architectural Decisions
| Decision | Choice | Rationale |
|---|---|---|
| Single-pane UI | No scrolling, fixed viewport | "The Matrix, but orange" — app-like feel |
| Zustand over React Context | Global state with URL sync | Simple, performant, supports URL-driven state |
| pgvector + Qdrant | Dual vector stores | pgvector for co-located queries, Qdrant for dedicated vector ops |
| AI SDK tools | Function calling over RAG chain | Direct tool use gives model control over retrieval strategy |
| SSE streaming | Server-sent events for playbook | Progressive results, real-time agent visibility |
| RLS everywhere | Row-level security on all tables | Zero-trust data access, auth baked into queries |
Non-Negotiable Invariants
These are enforced across the entire system:
- Every claim cites a source — No factual claim leaves the system without an evidence record
- Bounded retries — Max 2 attempts per stage, never infinite loops
- Safe fallback — If evidence is insufficient, return "insufficient evidence" instead of guessing
- Tenant isolation — Every retrieval includes user identity context
- Observable — Every orchestrated step emits trace data