Root
A personal knowledge companion that keeps every idea anchored to its source
921 commits · last on Sep 27, 2026
I spend a lot of time with books, podcasts, and long-form interviews — and for years, most of it evaporated. I’d remember that I heard something interesting, but not where it came from, why it mattered, or what I actually thought about it at the time. The same frustrations kept surfacing in conversation:
- “I remember hearing something like X in a podcast once.”
- “What book was that stat from?”
- “What were my actual takeaways from that source?”
Root is the fix: a personal knowledge companion for capturing what I consume, keeping every idea anchored to its source, and building my own thinking on top.
Having spent much of my life learning about investing, I think in terms of compounding — small, consistent deposits that accumulate into something outsized. Learning works the same way, but only if each insight lands somewhere it can build on the last. Root is my attempt to compound learning itself.
How It Works
The easiest way to explain the pieces is to follow one real thread through my library.
Everything starts with a source — a book, podcast, interview, or article. Sources act as anchors, giving every idea a clear origin and preventing insights from becoming detached or misremembered.
Walter Isaacson
As I read, highlights become citations, and comments capture what I thought in the moment. Citations are concrete facts and quotes exactly as they appear in the source — precise, attributable, and free of interpretation. Comments are the margin notes attached to them: my own in-the-moment thinking, kept deliberately separate from the source material. A single citation can accumulate multiple comments over time as my thinking evolves.
““You son of a bitch!” Jobs said. But it was not in anger. There was a big grin on his face. As soon as he realized what Belleville and the other engineers had done behind his back, said Hertzfeld, “Steve swallowed his pride and thanked them for disobeying him and doing the right thing.”
”
Each source gets distilled into at most five takeaways. A source can hold dozens of citations, but Root caps takeaways at five — the limit is the point. It forces me to synthesize patterns and arguments instead of hoarding highlights.
Charm, Belief, and Getting Shit Done
Jobs learned to use his charisma and his attitude to motivate the people around him. His belief that he could do anything was placed in the other people he worked with, which allowed him to get things done. Not only that, but he was a fantastic storyteller. His ability to paint a picture and narrative to motivate, coerce or convince was incredible.
9 quotes
Notes sit above individual sources. Where a takeaway distills a single source, a note weaves citations and themes from many — books, podcasts, interviews — into a longer, coherent argument. When the same idea starts appearing across multiple sources, that’s when a note begins. Isaacson describes Jobs’s obsession with “whole widgets” — products designed end-to-end, software tailored to hardware — and when the Cerebras CEO made the same argument about wafer-scale chips on a podcast months later, the overlap became this note:
Strengths of Vertical Integration
I actually really like the advantages of owning the entire stack (vertical integration). I think it makes your life really easy, as you don’t need to over adapt and defensively program since you can’t make that many assumptions. On the other hand, when you own the entire stack, it’s quite clear what can happen, and what can’t. This cohesiveness also allows you to create better, more integrated products…
Search & Retrieval
As the library grows, I can ask questions across my takeaways, citations, and comments. Answers cite the specific citations and takeaways they draw on, and the agent’s searches are visible as it works, so I can check where an answer came from.
Graph
The graph projects sources, takeaways, and tags into a 2D embedding space and draws edges between semantically related items. Tag clusters surface as labeled regions — Business, AI, Venture, and so on — making it easy to see where my reading is concentrated and where adjacent threads connect. Sliders tune how much the layout weighs shared meaning versus shared tags.
Guiding Principles
Root uses AI to assist, not to think for me. Real learning comes from friction, and AI can easily rob us of it. So the rule is: remove friction from capturing, keep it in thinking.
Easy in, source always attached — Getting an idea into Root should take seconds, but its origin is always preserved. A citation without its source is just a floating quote.
AI proposes, I decide — AI can draft citations and suggest takeaways, but nothing enters my library until I approve it. Drafts from voice notes are cleanups of what I said, and anything that drifts into the speaker’s claims is rejected.
Compounding value — Every highlight, comment, and note makes future retrieval and synthesis richer.
Incremental refinement — Insights aren’t fixed. A takeaway you write today might look different after you’ve read three more books on the same topic. Root is designed to support that evolution rather than freeze your thinking at a single point in time.
How I Use Root
Reading
I upload PDFs directly into Root and highlight text as I read, the same way you’d mark up a physical book. Highlights become citations I can reference later, search across, and pull into notes.
Podcasts & Interviews
Most of my listening happens in the Root mobile app, which has its own player, offline downloads, and a car mode. Podcasts and YouTube interviews get interactive transcripts, so I can skim a long discussion and see my comments and citations pinned to the exact moment they refer to.
The Walk While Talk flow. Capturing ideas while listening on the go used to be high-friction. Now it looks like this:
- 1
Tap voice capture
The player pauses automatically and starts recording.
- 2
Dictate the thought
A quick voice memo — no typing while walking.
- 3
Queued in the offline outbox
Memos wait locally until connectivity returns.
- 4
Uploaded & processed
Audio is transcribed and drafted as comments or citations anchored to the right timestamp.
- 5
Reviewed at my desk
I step through the drafts inline on the transcript, editing, approving, or dismissing each one.
Synthesis
As I’m finishing a source, I’ll often notice a recurring theme and start drafting a takeaway. I’ll give it a rough title and attach citations as I go. For example, while reading the Steve Jobs biography, a pattern that stood out early was his ability to persuade through charm and conviction; I created a takeaway around it — “Charm, Belief, and Getting Shit Done” — and linked supporting quotes as they surfaced (nine, by the end). When the same idea starts appearing across multiple sources, that’s when I’ll open a note and start writing something longer.
Roadmap
- planned
Physical Book Highlights (OCR) — Quick photo capture of printed highlights, run through the suggestions review queue.
- planned
Guided Knowledge Synthesis — Proactive AI prodding on the dashboard — guided questions that help synthesize margin notes into takeaways via interactive chat, keeping the friction of active learning.
- planned
Global Search — Fuzzy search across citations, comments, and takeaways with filters.
- planned
Kindle & Web Clipper Extensions — Browser integrations for Kindle highlights and general article clips.
GitHub Activity
Commit history from project inception (up to 1 year).
Last updated Sep 27, 2026
Monthly Breakdown
Jun 16, 2026 — Python Backend + Dedicated Auth Server
Two big shifts. First, the Go API was fully migrated to Python: FastAPI now owns all CRUD, RAG, and external integrations, and Go was reduced to a migration runner that applies schema migrations on startup and serves /health. Second, Better-Auth was extracted out of the Next.js process into its own service (Hono on Bun) that owns the auth schema and exposes JWKS. The frontend stays same-origin by proxying auth traffic through Nginx, and FastAPI validates JWTs against the auth server’s JWKS endpoint over the internal network.
Services
- Frontend (Next.js): UI and routing. Proxies
/api/auth/*and/rag-api/*through Nginx; no longer runs Better-Auth in-process. - Auth Server (Hono/Bun): Dedicated Better-Auth service. Owns the
authschema (Drizzle migrations on startup), issues sessions + JWTs, and serves JWKS. - Python FastAPI: The application backend — all CRUD, RAG, embeddings, transcripts, and external integrations. Validates JWTs via JWKS.
- Go Migrator: Applies
public-schema migrations on startup, then idles serving/health. No application logic. - Database (Neon Postgres + pgvector): Source of truth for user data, the
authschema, and embeddings. - External Services: LLM + embedding providers, transcripts, and storage.
Jan 21, 2026 — Consolidated Ingress + Deploys
This iteration added a single entry point (Nginx) to simplify deployments, improve rate limiting, and make auth enforcement consistent across services.
Services
- Frontend (Next.js + Better-Auth): UI, routing, and session handling. Proxies API calls and reads auth/session data directly from Postgres.
- Nginx Gateway: Single ingress for
/go-apiand/rag-api, with rate limiting and routing. - Go API: CRUD, domain validation, and core write paths for sources, citations, captures, and tags.
- Python RAG Service: Embeddings, vector search, transcript workflows, and SSE streaming for LLM responses.
- Database (Postgres + pgvector): Source of truth for user data, metadata, and embeddings.
- External Services: LLM providers, embedding providers, transcripts, storage, and media APIs.
Dec 14, 2025 — Split RAG into Python
Early on everything lived in Go. I tried tool calls and RAG there, but it was verbose and slow to iterate. I then routed RAG through Go → Python, which added an extra hop and made the system feel like a brittle distributed proxy. The cleanest move was giving the Python service auth directly via JWKS, so the frontend could call it without a Go bridge.
I also moved the database from self-hosted Postgres on Dockploy to Neon for easier table visibility, safer backups, and less anxiety about losing data.
Services
- Frontend (Next.js + Better-Auth): UI plus proxy routes to Go and Python, adding JWTs on requests.
- Go API: CRUD and domain validation for the core app data.
- Python RAG Service: Vector search and LLM workflows, authenticated via JWKS.
- Database (Postgres + pgvector): Stores user content and embeddings.
- External Services: Embeddings + LLM providers.
Early Dec 2025 — Go Monolith
The first version was a single Go API focused purely on CRUD while I figured out the core entities and data model. This choice was primarily motivated by wanting to learn to use Golang and not having any prior experience using it. It worked well for basic operations. I briefly allowed server-side Drizzle reads to move faster during development, but dropped that to avoid splitting read paths and to keep a single, consistent CRUD interface through the Go API.
Services
- Frontend (Next.js + Better-Auth): UI and session handling, proxying everything to Go.
- Go API: CRUD only, no AI or RAG operations.
- Database (Postgres + pgvector): Stores user content and embeddings.
- External Services: Embeddings + LLM providers.
September 2026 · Sharper suggestions
After a scope audit and a big cleanup, I rebuilt the core of voice-note suggestions so every highlight lands where it should and every note stays mine.
- Sentence-level matching: Transcripts are split into sentences with interpolated timestamps. Instead of rewriting quote text, the matcher points at sentence ranges, so highlights are exact by construction.
- Faithful captures: Matching and writing are now separate LLM calls, and a fidelity gate rejects captures that drift into the host’s claims instead of what I actually said.
- Frozen review queue: Each review session works through a fixed snapshot of suggestions, which ended a whole class of index bugs. Dismissing a suggestion can now be undone.
- Podcasts, properly: Added per-user show follows, scheduled RSS polling with conditional requests and backoff, and “play is free”: sampling an episode no longer adds it to the library and queues a transcription.
- Mobile dark mode and cleanup: Mobile theming now switches at runtime and defaults to dark. A cross-service cleanup removed ~7,100 lines, and the Ask model picker picked up Claude Opus 5.5 and GPT-6.
August 2026 · Open source
Root went public, and the Ask experience got a visual rebuild.
- Open-source release: Scrubbed the history, rotated credentials, trimmed the docs, and published Root under the MIT license.
- New Ask UI: The chat is now a chrome-free rail of rows. Reasoning, tool activity, streaming text, and inline citation markers each render as a lightweight row instead of a bordered card.
- Model catalog: The backend now publishes which models are available and what they can do, which drives a redesigned model picker.
- Route prefetching: Pages prefetch their data on hover or navigation, so moving around the app renders straight from cache.
June – July 2026 · New foundations
With a single backend in place, the rest of the stack got rebuilt around it.
- Dedicated auth server: Better-Auth moved out of the web app into its own Hono-on-Bun service that owns sessions, JWTs, JWKS, and passkeys.
- Next.js → Vite SPA: Ported every route to TanStack Router and deleted the Next.js app. The frontend is now a static bundle behind nginx.
- Review in the transcript: Suggestions are reviewed inline on the real transcript page, where you can edit, remove, or re-run each one with guidance. This replaced a separate reviewer screen.
- Atomic citations: A citation and all of its captures are saved in a single request.
- Local stack: One Docker Compose file runs the whole system locally with hot reload.
May – June 2026 · One backend
The Go API that had been the source of truth since December was retired. FastAPI now owns every endpoint.
- Go API retired: Deleted ~9,600 lines of handwritten Go and ~8,500 lines of generated code, replaced by ~1,900 lines of Python and ~900 lines of tests. Go now only runs database migrations.
- Graph v1: Sources, takeaways, and tags are projected into a 2D embedding map, with semantic edges and region labels derived from tag clusters.
- Multiple captures per citation: A highlight can now carry several margin notes, on both web and mobile.
- Unified pipelines: YouTube and podcast transcription run through a single pipeline, and all vector search runs on a shared core.
- Stats dashboard: Added a 90-day engagement view across sources, citations, takeaways, and comments.
May 2026 · Agents & voice
This is when Root started talking back: a persistent assistant, real-time voice, and suggestions drawn from what I’d listened to.
- Assistant surface: A slide-out assistant, available from anywhere in the app, with reasoning, tool-call tracking, and conversation history that persists across sessions.
- Voice agent: Real-time voice conversations with the knowledge base on mobile, first over WebRTC and then over ElevenLabs.
- Suggestions engine: Finds uncaptured highlights and potential takeaways in transcripts and turns spoken voice notes into draft citations for review.
- Mobile listening: Rebuilt the mobile home around what’s in progress, with offline podcast downloads, car mode, and a voice-capture button in the player.
- Takeaways in TipTap: Takeaways moved into the same rich-text editor as notes, with inline citations.
February – April 2026 · Library & notes
The focus shifted from capturing to thinking: long-form notes, a real library, and a workflow that pushes you to reflect before moving on.
- Notes: A rich-text writing space with embedded citations and autosave. Notes can stand alone or belong to a source.
- Four-stage lifecycle: Sources move through
todo → in_progress → reflecting → done. A dedicated Reflect tab nudges you to synthesize before starting something new. - Library & collections: Navigation was reorganized around a Library, with Collections for themed groups of sources. The home page was redesigned around resuming where you left off.
- Command palette v2: A plugin-based, context-aware command engine with composable pickers, multi-step flows, and global shortcuts.
- Durable media: Podcast audio is archived to R2, source files are cleaned up when a source is deleted, and each source type gets its own dedicated page.
January – February 2026 · Transcripts everywhere
Root grew beyond text. Podcasts, videos, and PDFs all became first-class sources you can highlight.
- Video & podcast transcripts: YouTube transcripts, RSS podcast ingestion, and on-demand AssemblyAI transcription, with in-app players that stay in sync with the transcript.
- PDF support: Upload a PDF, highlight text, and have those highlights included in retrieval. I forked an open-source PDF highlighter to fix its underlying API issues.
- Production launch: Stood up a separate prod environment behind nginx with rate limiting, CAPTCHA on auth, and Doppler-managed config.
- Takeaway flexibility: Citations can now belong to several takeaways, and the app installs as a PWA.
- Better retrieval: Re-embedded everything with Voyage, added summary embeddings, and moved telemetry to Logfire.
December 2025 – January 2026 · One source of truth
Consolidated the data layer behind a Go API and started on spaced review.
- Go API as source of truth: Moved sections, takeaways, and captures off Drizzle routes into Go, with generated types on the frontend.
- Review system v1: LLM-generated review items with structured prompts, validation, and streak tracking.
- Richer retrieval: Added BM25 hybrid search, speaker and context metadata on citations, takeaways in retrieval, and upgraded embeddings and reranking.
- Admin tooling: An admin dashboard with per-user stats and trends.
December 2025 · RAG v1
The first version that felt like a product: structured citations and an assistant grounded in them.
- Structured citations: Citations gained locations, sections, speakers, and context, plus standalone captures. The old recall feature was removed.
- RAG v1: Voyage embeddings, hybrid retrieval, and streamed answers grounded in your citations, running as a dedicated Python service.
- Agent orchestration: Moved to a Jetflow-based agent built from modular search actions.
- Tagging v1: Tags across all core entities, alongside takeaway editing and a first command palette.
Key Takeaways
Deployment & Infrastructure
- Docker Compose vs. Individual Dockerfiles: Switching to Docker Compose
allowed me to more clearly see exactly what variables are needed for specific
services. In Dockerfiles, it’s often not that clear-cut since you’re just
injecting environment variables. Seeing it all defined in a single
docker-compose.ymlis significantly more useful for maintaining a clear overview of service dependencies and configurations.
Language & Tooling
- Golang: Go is really great. Its error-first approach is kind of nice and makes you think about errors early. However, if you’re developing a product while trying to figure out the kinks, it’s a little slow since it’s so verbose (especially if you’re doing DB migrations etc). That said, its declarative approach is really nice—compared to something like Spring Boot where everything is super “magicky,” in Go, 99% of behavior is explicitly defined somewhere.
- Python / FastAPI Ecosystem for AI: While Go is highly performant, Python’s ecosystem is simply far riper once you start building AI or RAG features and integrating various SDKs (Voyage, OpenAI, ElevenLabs, AssemblyAI). Furthermore, keeping a split backend creates unwanted duplication of repository methods, types, and database utilities. Consolidating the backend entirely in FastAPI avoids this duplication.
- Voice APIs & Real-time Audio Cost: Real-time voice agents (via ElevenLabs WebSockets) are cool, but API cost scaling is incredibly high and tool-calling documentation remains immature.
UX and Development
- Super easy to do db migrations early — it’s better to spec out user flows and figure out what workflows you want to develop (also faster to iterate FE)
- Vibe Coding & Rapid UX Prototyping: It is highly valuable to spend a few hours “vibe coding” new features and UX workflows to get a feel for what constitutes a high-leverage action before committing to database migrations or rigid schemas. Because the entire FastAPI backend and API surface was already set up, throwing together a new mobile app took only a couple of hours since all the backend heavy lifting was already done. This low-friction environment allowed for rapid experimentation; for example, building out the mobile app with the suggestions mechanic has been a game-changer—10x’ing the amount of podcast listening I do and exponentially increasing the volume of insights I actually retain.