Read in:
English

Philosophy

Why publish knowledge as a graph rather than a book. How AI changes the rules. Why subscription over one-time sales. Below are all the essays, newest first; for a curated, themed list see the sidebar.

Filming the demo is a test

Recording a clean video of a feature forces you to walk its entire happy path on the real product. The bugs that surface are the ones that otherwise wait for a live demo in front of a client.

We set out to record an onboarding video: download the starter vault, install the plugin, save a note, watch it appear on the site. Nothing exotic, the exact path every new user takes. The recording took days longer than planned, and almost none of the delay was about video. Take after take failed because the product, on the real production system, kept refusing to do what every test said it could do. That turned out to be the value. Filming is a rehearsal of your demo, and it catches demo-day bugs while they still cost a re-shoot instead of a client's trust.

Video: coming soon. The finished recording will be embedded here.

Good MCP instructions make a cheap model find answers faster

What this is: a measured A/B on two cheap models. I gave Claude Haiku and GPT-5.4-nano an MCP connection to the trip2g docs and asked each eight questions, once with a short instructions note in its context and once without. Same tools, same questions. The instructions note made Haiku search 26% faster with 41% fewer whole-note dumps. nano, already frugal on its own, barely needed it. Read it if you run a knowledge base over MCP and wonder whether the instructions note earns its keep.

The short answer: a good instructions note does not make a cheap model smarter. It corrects a wasteful default. The catch is that not every cheap model is wasteful. On Haiku the instructions note was a clear win. On nano, which already reads carefully without being told, the instructions bought almost nothing and even cost tokens. Both stories are below, because the honest lesson is in the contrast.

Alerts belong in a knowledge base

What this is: we wrote alert-sink, a small open-source service that turns Alertmanager webhooks into incident notes in a trip2g instance. Every alert becomes a markdown note, the notes add up to a permanent searchable incident history, and the knowledge base can narrate incidents to a Telegram group on its own. Read it if your incident history currently lives in a chat scrollback.

Alerts today are fire-and-forget. Prometheus notices a problem, Alertmanager pushes a message to Telegram or email, someone reacts or doesn't, and that's the end of the record. A month later you're asking "when did this node last flap?" and the honest answer is: scroll the chat and hope. Alertmanager itself only shows what is firing right now. History survives as a Prometheus time series, bounded by retention, or as a message that scrolled past.

That gap annoyed me for a while, because the fix is not a monitoring product. It's a place to write things down.

We Built a Benchmark, Then Fixed Five Search Bugs

Here is what we found when we actually measured trip2g's vector search.

Long-document track (notes split across 6–10 chunks):

Numbers come from committed eval artifacts in docs/superpowers/eval-runs/. The story behind them is below.

The universality tax

What universal tools cost — to the people who build on them, and to the people who use them.

A universal substrate makes any given use case possible but almost never cheap. Each door costs real work built on top of the substrate, and that cost is easy to underestimate before you start and easy to enjoy more than the actual work once you do. That second part is the trap: the tool invites you to build the tool instead of using it. Sociology has a name for the mechanism (goal displacement), maker culture has a mascot (the 3D printer that mostly prints parts for itself), every other garage holds a car that is never quite finished, and trip2g has a receipt: a "simple kanban template" that forced six rounds of changes into the core. Universality is a promise and a tax. The discipline is to pay the tax deliberately, when the content demands it, and to notice when you've started paying it for fun.

This is the companion to Universal tools have no elevator pitch. That piece says: explain a substrate by picking a door. This one says: doors aren't free.

Paths not taken

Features we built and deleted, or evaluated and refused — with the numbers that decided.

Frost's two roads, by his own account, were "really about the same"; the road less traveled is a story the traveler invents afterwards, with a sigh. No sighs here. These paths weren't heroic forks — we walked them, measured, and turned back, usually the same day. Not the road less traveled. Just the road we tried and left.

Most product pages list what got built. This one lists what got built and then deleted, or evaluated and refused. Not because the ideas were stupid — most of them are textbook recommendations — but because we measured them against this system and the numbers said no. A knowledge platform that asks you to trust it with your notes should show you how it makes decisions, including the reversals.

Markdown as an operating system

What this is: trip2g read as a literal operating system, notes as the filesystem, MCP as syscalls, federation as the network, agents as processes. Every row in the map is tagged by how real it is, so you can see where the metaphor is earned and where it is not. Read it if you want to judge whether "Markdown OS" is a real claim or just a label.

trip2g began as a way to publish an Obsidian vault as a website. Somewhere along the way it grew the shape of an operating system. Notes are the filesystem. The MCP endpoint is the system-call interface that agents go through. Federation is the network stack. A note edit can start an agent. All of that runs on main today, including the piece that makes the comparison land: agents as processes, merged as the fleet runtime after a spell on a feature branch. This is the honest version of the claim, with the remaining gaps marked as such.

The framing is borrowed. "Markdown as an Operating System" puts it in one line: your operating system runs on binaries, your AI agents should run on Markdown. The older root is Unix, where everything is a file. trip2g's version is that everything is a note.

Anatomy of trip2g: 15 Months of Code

trip2g is a publishing platform: Obsidian vaults → websites with subscriptions and Telegram integration. Go monolith + $mol frontend + SQLite.

After 15 months I counted what's actually inside.

Universal tools have no elevator pitch

Why Obsidian is so hard to explain in one sentence, why trip2g has the same problem, and why that's a property of the tool, not a failure of marketing.

Universal tools resist a one-line pitch because every user enters through a different door. Obsidian is the proof: "a markdown editor with wiki-links and plugins" is technically accurate and sells it completely short. The reason is structural. Obsidian is a substrate, not a feature, and substrates get their meaning from what people build on them. trip2g inherits the same substrate shape and the same problem. The honest response is not to search for the one true pitch. It is to accept that there are many valid ones, each true for a different reader.

Ask for the turn, not the interval

A language model is good at seeing where a conversation turns. It is bad at arithmetic on timestamps. My first attempt at splitting call transcripts into topics ignored that. I asked for [start–end] blocks, and the model couldn't keep the intervals straight. What fixed it wasn't a sharper prompt, and it wasn't a bigger model. It was a different question: ask where each topic starts (one real timestamp from the transcript) and let code work out the spans. The cheapest model then placed transitions 100% in order and 97% on real timestamps, and it beat the bigger model.

I spent half a year blaming SQLite for my own bug

What this is: the story of a SQLITE_BUSY error I chased for half a year, blamed on SQLite, and finally found in my own connection pool. Part war story, part the case for running a database inside one process. Read it if you have ever seen "database is locked" and wondered whether SQLite was the wrong call.

The error was mine. For about half a year trip2g kept throwing SQLITE_BUSY and database is locked under load, and for about that same half a year I kept deciding the problem was SQLite. It was not. I had the connection pool configured to lie to me about how many writers I had. The day I finally understood that is the day I stopped being afraid of running a database inside my own process, and started to actually like it.

I came to this from years on Postgres. On Postgres you do not think about how many writers there are. You open a pool of thirty connections, they all write whenever they want, and the server sorts it out. So when I moved trip2g onto a single embedded SQLite file, the model felt wrong in my hands. One writer at a time, even in WAL mode? It read like a limitation I would have to route around, not a contract I should design for. I spent months treating it as the former, and I was quietly furious at the engine the whole time.

The database was re-reading its own queries

After the page cache shipped, we profiled again. Rendering had disappeared from the hot path. A third of the CPU was now in SQLite's SQL parser.

The server: a cx23, 2 vCPU, €6.49/month on Hetzner. The profile, taken under load, showed _yy_reduce and the query planner sitting where the cosine similarity scan used to be. The database was parsing the same SQL strings on every single request and throwing the compiled result away.

The page cache and the surprise bottleneck

The profiler said the plain documentation page was 30× more expensive than the custom-designed landing. We expected the opposite.

Two pages under load: the Jet home (a custom layout with a mesh grid, brand design, hand-tuned markup) and a default-template docs page, the kind you get without any configuration. Common sense says the fancy one costs more to render. The profiler said the docs page ran at ~28 ms/request; the Jet home ran at ~0.9 ms/request. Thirty times slower. All of it in one place: a synchronous, per-request cosine similarity scan over every note embedding, labeled "similar notes."

What Is Vibe Coding?

TL;DR. Vibe coding is building software by prompting an AI in natural language and accepting the output without reading, understanding, or reviewing the code. The same activity has two opposite reputations — democratizing miracle and silent bug factory — and the dividing line is not whether AI wrote the code, but whether a human understands what shipped.

A trip2g network on preemptible nodes

Short version. A trip2g knowledge network (markdown vaults backed by SQLite) can run on preemptible nodes. They cost far less and can vanish at any moment. In a synthetic test the network survives it: a node dies, comes up on another machine, and restores its data in about 35 seconds, losing no more than 1 second of writes. What holds the data is not the local disk but a copy in object storage (Litestream). The rest is detail: what I tested, how it works, and where the limits are.

I tested on a throwaway two-node cluster, a real power-off via the Hetzner API. The test is synthetic, not production: it shows the mechanism holds, not that you will never lose data.

What a markdown vault is

A vault is a folder of markdown notes you navigate as a linked graph. The same thing Obsidian users call a "vault." The one difference: ours is not tied to Obsidian.

We Benchmarked Obsidian Sync, and the Bottleneck Was Invisible

We re-reviewed trip2g's Obsidian sync, expecting to tune a slow hashing path. Then we built a benchmark and measured. The slow part was somewhere else entirely — one missing flag that turned a 3-second push into a 4-minute one.

The headline: a cold push of 2000 notes with 2000 small images.

xychart-beta
    title "Cold push: 2000 notes + 2000 images (seconds, lower is better)"
    x-axis ["CLI before fix", "CLI after fix", "Obsidian plugin"]
    y-axis "seconds" 0 --> 240
    bar [231.8, 8.8, 6.0]

All numbers come from an isolated benchmark stack (vector search off, local server). The story is below.

One endpoint, many knowledge bases

A bit over a month after the first federation commit, our public trip2g hub is
live: one MCP endpoint that searches across several independent knowledge bases
at once.
The demo is the small part. The bet is the network — bases owned by
different people, reachable through a single address, queryable by any agent with
no central registry.

Patching Obsidian Canvas on minimal Linux

Ubuntu 24.04 LTS aarch64, VMware on a Mac, no desktop environment — dwm under bare X11, startx from TTY. Obsidian 1.12.7 (tested both Flatpak and AppImage).

Canvas opens. Nodes render. You can click them. But you can't drag existing nodes, and you can't draw edges between them. New nodes created via the toolbar drag fine. Console: silent.

The fix: a two-file Obsidian plugin that rewrites all non-mouse pointer events to pointerType: "mouse" before Obsidian's handlers see them. Install it, restart, done. The root cause and the dead ends are below if you want to understand why.

The agent reports to the team on its own

When you work with an agent all day, the team sees nothing. A commit might appear by evening — if it appears at all. What the agent was doing for six hours is a mystery. This skill closes that gap: after every turn, the agent automatically writes a short report and sends it to trip2g.

The agent keeps a team journal

Every morning the agent reads what team members worked on yesterday and writes a daily note. Every Monday, a weekly summary. Nobody enters anything manually — the data comes from each member's trip2g instance via MCP.

Dogfooding

Dogfooding

Dogfooding is a development philosophy where the team uses its own product in real work. The term originated at Microsoft in the 80s: "eating your own dog food."

Content Infrastructure for Human-AI Workflows

trip2g is content infrastructure. People and AI agents work with the same content on equal footing. Content doesn't sit idle — it flows between participants and transforms at every step.

Not a CMS where you "create and publish." Not a wiki where only humans edit. Not a static site generator where you "build and deploy." This is a programmable platform where content flows between people, bots, AI agents, Telegram, and Obsidian — and changes at every transition.

The Admin Panel as a Universal Config

Every feature needs settings. A Telegram bot needs a token and group IDs. OAuth needs keys for Google and GitHub. Patreon needs an API token and subscription tiers.

You could build a separate editor for each entity. A form for the bot, a form for OAuth, a form for Patreon. But that's just duplication.