Coding Compendium

Answers about development, faster than opening a browser tab.

A Windows desktop app that holds a handwritten reference library and finds the right page the moment you are stuck. The search, the language identifier and the answers all run on your machine. No account, no API key, and no internet once it is installed.

Fully Offline Windows 11 GPLv3 · corpus CC0
Download Source on GitHub
Overview

One markdown file that got out of hand.

It started as vibecoding-knowledge.md, a single 44KB file of notes about working with coding agents. That file is still in the repository as the seed. This is what happens when you turn it into something you can actually reach for at the moment you need it, and then write about eleven times more of it.

Everything the app knows lives in content/ as plain markdown with a YAML header. You can read it in any text editor, every edit shows up as a readable diff, and the database the app searches is compiled from those files rather than hand-edited. Fix the markdown, rebuild, and the app is fixed.

What It Does

Four things, done properly.

Search that understands what you meant
Type "how do I undo the thing I just did" and get the right card, even though the guide calls it git revert. Two engines run at once: one matches your literal words, one matches your meaning, and the results are merged.
Identify anything you paste
Code, an error message, a terminal command, a config file. It names the language and shows the evidence: which tokens gave it away and why. Being told "this is Rust" answers the question once. Being shown why means you recognize it next time.
A panic button for git
When you have broken something and do not know what, it asks one question at a time in plain language. Every option says what it will destroy before you pick it, and offers to cut a backup branch first.
A sidecar window
A narrow strip you dock to the edge of the screen and leave open while you work. Alt-tabbing to look something up is a habit you have to build. Having the answer already on screen is not.
The Identifier

It shows its work.

Paste a snippet and the answer comes with the reasoning attached, token by token.

Rust, 92%
  because  fn        only Rust uses exactly `fn`. Go uses `func`,
                     Kotlin uses `fun`, Python uses `def`
           let mut   Rust variables cannot change by default
           ::        the separator between modules and types
           println!  the `!` means macro, nothing else looks like this
Search

Two engines, opposite blind spots.

Lexical search matches the words you typed. SQLite's FTS5 with BM25 ranking, the same family of algorithm that ran search engines for twenty years. Fast, exact and completely literal. Search for "detached HEAD" and it finds every card with those words in it. Search for "my commits went somewhere weird" and it finds nothing, because none of those words appear anywhere.

Semantic search matches meaning. Every card runs through a small neural network that turns text into 384 numbers, and text that means similar things produces similar numbers. Your query gets the same treatment, then it is arithmetic. "My commits went somewhere weird" lands near the detached HEAD card with zero words in common. The failure mode is the mirror image: it is fuzzy, so an exact search for git reset --hard can drift to merely related cards.

Each one covers the other's blind spot, so the app runs both and merges the ranked lists with Reciprocal Rank Fusion. RRF ignores the raw scores, which are not comparable between the two engines, and looks only at position. A card ranked 3rd by one engine and 2nd by the other beats a card ranked 1st by one and 40th by the other. Simple, and hard to fool. All of it runs locally and finishes in under 50 milliseconds.

Honesty

Nothing here writes you an answer.

The app never generates prose. When search finds relevant cards it highlights the sentences that match your question and pulls the two or three closest into a quote block with the card's name attached. Everything you read was written by a person and is sitting in content/ where you can go check it.

The model that was benchmarked and did not ship

The plan was a small language model, about 380MB, trained to abstain, that would read the retrieved cards and write a short cited answer for questions the corpus does not directly cover. It was measured on 50 questions, 15 of which the corpus deliberately does not answer. It abstained on 14 or 15 of those 15, which cleared the bar.

It did not ship. Asked how to connect Prisma to Postgres, which the corpus does not cover, it answered from a card whose entire purpose is to warn against pasting connection strings into a chat window. It lifted the redacted example out of the warning and presented it as instruction. Well formed, correctly cited, literally quoted, and it had inverted a security warning into advice. One question in fifteen.

That failure mode cannot be defended against by being careful, because it looks exactly like success. And it lands hardest on the person least able to catch it: you are asking because you do not already know, which is precisely why you cannot check the answer. So the app extracts instead of generating. It cannot invert a warning into advice, because it can only show you what a card already says.

The full measurement is in docs/PHASE0-LLM-GATE.md, and the trait boundary in src-tauri/src/synth/ is built so the decision can be revisited without disturbing anything else. The 66MB embedding model that powers semantic search is a different thing entirely and does ship. It turns text into numbers so meanings can be compared. It does not write anything.

The Corpus

What is actually in it.

Tracks
Twelve, A through L. The long explanations, for when you want the whole picture rather than one answer.
Language cards
Twenty-two, covering the languages you will actually meet plus the config formats (JSON, YAML, TOML, Dockerfile) that everyone hits and nobody explains because they are "not really code."
Errors
Fifty error messages and what they mean.
Commands
Eighty terminal commands, flag by flag.
Glossary
Two hundred and sixty terms, frozen so ids stay stable across rebuilds.
Panic trees
The git disaster decision trees, plus intents that map plain-language goals onto the cards that answer them.
Under The Hood

Specifications.

Platform
Windows 11, x64. Signed installer.
Stack
Rust behind Tauri for search, embeddings, the identifier and the corpus compiler. React and TypeScript for everything you see.
Search
SQLite FTS5 with BM25, plus 384-dimension embeddings, merged by Reciprocal Rank Fusion. Under 50ms.
Bundled model
66MB embedding model, downloaded once at build time and shipped inside the installer.
Network
None at runtime. The built app makes no outbound requests, and there is no telemetry.
Source of truth
content/, plain markdown with a YAML header, validated against JSON Schemas and a voice linter in CI.
License

Two licenses, because a program and a paragraph are different things.

The program is GPLv3. Everything that compiles or runs: the Rust and TypeScript, the tooling, the schemas, the build configuration. Ship a modified build and the people you ship it to are entitled to the source for it.

The corpus is CC0. Everything under content/, the seed document, the style guide, and any database compiled from them. Public domain, no attribution required, no conditions at all.

The split is deliberate. Copyleft is the right answer for a program, because it keeps improvements available to the people the program is for. It is the wrong answer for a paragraph explaining what a branch is. Take the writing, fork it, sell it, relicense it, feed it to a model. It was written to be read by someone who is stuck, and every condition attached to it is one more reason it does not reach them.

Get It

Install, or build it yourself.

The installer is the short path. To run it from source you need Node, Rust and pnpm installed once.

winget install OpenJS.NodeJS.LTS
winget install Rustlang.Rustup
npm install -g pnpm

pnpm install              # frontend dependencies
pnpm build:content        # compiles content/ into the searchable database
pnpm tauri dev            # runs the app with live reload

pnpm build:content downloads the 66MB embedding model the first time it runs and never again. It is the only step that touches the network, and the built app does not. pnpm package produces the installer.

Get the latest release