← Zurück zum Portfolio
L
Fallstudie6 Min. Lesezeit

Ein Vault, den Agenten
per Abfrage lesen, nicht per grep.

Eine Engine komplett in Rust, die einen reinen Markdown-Vault in SQLite indexiert und dreifach bereitstellt: als MCP-Server für Claude, als CLI und als native Desktop-App für Menschen. Quelloffen, veröffentlicht, signiert und notarisiert. Sie indexiert gerade jetzt das Repository dieser Seite.

15
MCP-Tools
3
Oberflächen
1
Rust-Core
v0.2
Signiertes Release
Zum Lesen scrollen
00Das Problem

Ein Agent sieht die Struktur eines Repos nicht.

Das Studio läuft auf einem Markdown-Vault: Hunderte Notizen, Specs, Pläne und Memory-Dateien, verbunden über [[Wikilinks]] und YAML-Frontmatter. Wenn ein Agent darin etwas finden muss, hat er nur find und grep. Beide liefern Rauschen, und beide verbrauchen Kontext für ein Repository, dessen Struktur das Modell nicht sieht.

Obsidian löst die menschliche Seite mit Graph und Backlinks, aber das ist für eine klickende Person gebaut, und es ist eine Drittanbieter-App ohne Maschinen-API. Ich wollte eine Engine für beide Seiten: eine Abfrage-API für Agenten und einen nativen Reader und Editor für mich, über genau dieselben Markdown-Dateien.

01Die Engine

Ein Rust-Core, ein aus den Dateien abgeleiteter Graph.

Lattice ist eine einzige Rust-Core-Crate ohne eigenes I/O. Sie durchläuft einen Vault, parst jede Markdown-Datei und baut einen Graphen: Jede Datei ist ein Knoten (eine README ist ein Index, alles andere eine Notiz), und drei Kantenarten verbinden sie. Wikilinks, Frontmatter-Referenzen und der contains-Baum von der README eines Verzeichnisses zu den darunterliegenden Dateien.

Der Graph liegt in SQLite mit einem FTS5-Volltextindex, aber diese Datenbank ist nur ein abgeleiteter Cache. Die .md-Dateien sind die Quelle der Wahrheit. Lösche den Index, und Lattice baut ihn von der Platte neu auf.

Tech Stack
Rustrusqlite (SQLite + FTS5)comrakserde_yamlignoreblake3
Wie es funktioniert
Vault durchlaufen, Frontmatter, Links und Überschriften parsen, Knoten anlegen. Die Link-Auflösung ist ein zweiter Durchlauf, da ein Ziel nach der referenzierenden Notiz definiert sein kann.
Warum es zählt
Der Index ist neu aufbaubar und wegwerfbar. Nichts an deinem Wissen ist in Lattice eingeschlossen. Es bleibt reines Markdown auf der Platte.
In der Praxis
Eine .aiignore (gitignore-Syntax) hält System-Dateien komplett aus dem Graphen heraus.
02Die KI-Oberfläche

Agenten fragen den Graphen ab, statt zu greppen.

Agenten durchstöbern einen Vault nicht, sie fragen ihn ab. Lattice stellt dieselbe Core-Engine als MCP-Server bereit (über stdio, direkt in Claude Code einsteckbar) und als passende CLI, beide mit einer JSON-Form. Ein Agent fragt nach Backlinks, ausgehenden Links, einem Frontmatter-Filter, Volltextsuche, Orphans oder kaputten Links und bekommt Struktur zurück statt einer Wand von grep-Ausgabe.

Das Kernwerkzeug ist vault_context_bundle: gib ihm eine Notiz und ein Token-Budget, und es liefert diese Notiz plus ihre relevantesten Nachbarn, dedupliziert und gewichtet, passend gepackt. Budgets sind weich, und ein Manifest listet genau auf, was aufgenommen und was verworfen wurde. Kein stilles Abschneiden.

Tech Stack
rmcp (Rust MCP SDK)claptiktoken-rsstdio transport
Wie es funktioniert
15 Tools über einen JSON-Vertrag, den MCP-Server und CLI teilen. Navigation ist nur lesend; strukturierte Änderungen (eine Notiz umbenennen und jeden Backlink korrigieren, Frontmatter patchen) sind separat und standardmäßig Dry-Run.
Warum es zählt
Ein Agent verbraucht seinen Kontext für Denken, nicht für das Greppen eines Repos, dessen Form er nicht sieht. Er fragt nach dem Ausschnitt, den er braucht, und bekommt ihn.
In der Praxis
Das sind die vault_*-Tools, die in der Sitzung laufen, die diese Seite geschrieben hat.
03Die menschliche Oberfläche

Eine native App über genau denselben Dateien.

Menschen lesen und bearbeiten denselben Vault durch Lattices eigenes natives Fenster: ein Rust-Backend (die Core-Crate, als Tauri-Commands bereitgestellt) mit einem SvelteKit-Webview. Kein Electron, keine gebündelte Laufzeit, ein Binary.

Es durchblättert Notizen mit Backlink- und Ausgangslink-Panels, macht die Graph-Abfragen (Orphans, kaputte Links, Frontmatter-Filter, Suche) zu erstklassigen Ansichten und bearbeitet Markdown in einem CodeMirror-Editor, der direkt in die .md-Datei zurückschreibt. Markdown wird einmal gerendert, über den Rust-comrak-Pfad, damit App und Agenten denselben Inhalt sehen.

Tech Stack
Tauri 2SvelteKitCodeMirror 6comrak → HTMLammonia
Wie es funktioniert
Das Speichern ruft ein Tauri-Command auf, das die Datei schreibt; der Index synchronisiert sie wie jede andere Änderung. Hat sich die Datei seit dem Laden auf der Platte geändert, warnt der Editor und bietet ein Diff an, bevor er überschreibt.
Warum es zählt
Ein Vault, zwei Zielgruppen. Der Mensch bekommt einen Obsidian-artigen Reader und Editor; der Agent bekommt eine Abfrage-API. Keiner ist zweitklassig.
In der Praxis
Hell und dunkel, ausgeliefert als signierte .app und .dmg.
04Technik für Vertrauen

Nie eine veraltete Antwort, nie eine zerstörte Notiz.

Ein Werkzeug, dessen ganzer Wert Aktualität ist, darf nie eine still veraltete Antwort liefern, und ein Werkzeug, das in deine Notizen schreibt, darf sie nie beschädigen. Zwei Entscheidungen tragen dieses Gewicht.

Der erste Index-Entwurf baute bei jedem Aufruf neu (etwa 9 Sekunden) oder beobachtete das Dateisystem mit notify. Der Watcher erwies sich in einem gepipten MCP-Server als unzuverlässig: der gestartete Thread bekam nie Dateisystem-Events, und ein still veralteter Index ist der schlimmstmögliche Fehler. Lattice hält den Index stattdessen im Speicher und macht bei jedem Aufruf ein günstiges inkrementelles Re-Sync: durchlaufen, mtimes vergleichen, nur Geändertes neu parsen. Sechs Aufrufe plus Start fielen von etwa 9 Sekunden auf etwa 1,3, und die Antwort ist immer aktuell.

Die zweite: der Frontmatter-Patcher fasst nichts an, was er nicht sicher zurückschreiben kann. Gib ihm eine Block-Style-YAML-Liste oder CRLF, das er nicht sauber parst, und er gibt die Datei unverändert mit einer Warnung zurück, statt eine Beschädigung zu riskieren.

Tech Stack
Arc<Mutex<Vault>>lazy revalidationblake3 hashingdry-run default
Wie es funktioniert
Jeder Schreibvorgang ist rein strukturell, standardmäßig Dry-Run und fasst git nie an. Ein blake3-Body-Hash überspringt No-op-Schreibvorgänge; Abfragen warnen, wenn der Index der Platte hinterherhinkt.
Warum es zählt
Datensicherheit schlägt Features. Die Verträge (rein strukturell, Dry-Run, nie Fäulnis erzeugen) sind tragend, und jedes neue Schreib-Feature wird daran gemessen.
In der Praxis
Beide Entscheidungen kamen aus dem Dogfooding plus einem externen Code-Review.
05Veröffentlicht

Öffentlich, getestet, signiert und notarisiert.

Lattice ist ein öffentliches Repository, kein privates Experiment. GitHub Actions führt bei jedem Push cargo test, cargo clippy, cargo fmt und den Svelte-Build aus, und die grünen Häkchen gehören zum Punkt.

v0.2.0 wird als echte macOS-App ausgeliefert: Developer ID signiert, von Apple notarisiert und gestapelt, sodass sie mit sauberem Doppelklick und ohne Quarantäne-Warnung öffnet. Und sie verdient ihren Platz durch Dogfooding. Der Vault, den sie indexiert, ist dieses Studio, dasselbe Repository, das die Seite enthält, die du gerade liest.

Tech Stack
GitHub ActionsDeveloper ID signingApple notarizationDMG
Wie es funktioniert
Ein Release-Skript führt die volle Kette aus Signieren, Notarisieren und Stapeln aus; App und dmg verifizieren beide offline.
Warum es zählt
Quelloffen, veröffentlicht und signiert ist eine andere Aussage als ein Demo. Das Ganze ist baubar und einsehbar.
In der Praxis
github.com/anrasch/lattice, v0.2.0, 15 MCP-Tools.
Das Große Ganze

Die Wissensschicht
des Studios.

Der Harness betreibt das Studio; Lattice ist, wie es sich erinnert und navigiert. Das eine sind die Hände, das andere das Gedächtnis. Beide sind Werkzeuge, die ich gebaut habe, weil die, die ich brauchte, noch nicht existierten.