# Installation Dieses Dokument richtet sich an Menschen. Es gibt vier Wege: ein **Release herunterladen** (der normale Weg zu einer neuen Instanz), eine Distribution **selbst exportieren**, **dieses Repo klonen** (Testbett und Demo, samt Beispielkorpus), oder eine **private Instanz mit diesem Repo als Upstream** aufsetzen. Der agent-seitige Ablauf steckt in `instructions/`; hier stehen nur die menschlichen Teile - für die vollständige Kommandoreferenz siehe [tools/CONTRACT.md](tools/CONTRACT.md). ## Voraussetzungen - Python 3.11 oder neuer - git - [ripgrep](https://github.com/BurntSushi/ripgrep) (`rg`) - wird von `search` und `sources coverage` gebraucht ## Weg A: Release herunterladen Der kürzeste Weg zu einer eigenen Instanz - kein Checkout dieses Repos nötig. Jedes Release trägt genau einen `dist export`-Baum plus eine Prüfsumme. Das Repo ist öffentlich, der Download braucht also weder Konto noch Token: ```bash BASE=https://gitea.nehmer.net/torben/chemenu/releases/download/v curl -LO $BASE/chemenu-stack-.tar.gz curl -LO $BASE/chemenu-stack-.tar.gz.sha256 sha256sum -c chemenu-stack-.tar.gz.sha256 tar xzf chemenu-stack-.tar.gz cd chemenu-stack- ``` Die Prüfsumme ist nicht Zierde: Sie ist das Einzige, was einen unterbrochenen Download von einem vollständigen unterscheidet, und `sha256sum -c` muss `OK` sagen, bevor irgendetwas entpackt wird. Danach weiter mit Schritt 2 aus Weg B: den Agenten [instructions/setup-instance.md](instructions/setup-instance.md) ausführen lassen. Der entpackte Baum ist bereits eine Distribution - Schritt 1 (`dist export`) entfällt. Die Liste der Releases: . ## Weg B: Neue, leere Instanz selbst exportieren Dasselbe Ergebnis aus einem Checkout dieses Repos - für einen Stand, der noch kein Release hat. Zwei Schritte, von denen nur der erste rein menschlich ist: 1. **Zielverzeichnis wählen** und die Distribution dorthin exportieren, aus einem Checkout dieses Repos: ```bash tools/wikitool dist export /pfad/zur/neuen/instanz ``` Das Ziel muss leer sein oder noch nicht existieren. `dist export` kopiert die Maschinerie (Werkzeuge, Typen, Instruktionen, die Collection-Contracts) ohne Wiki-Inhalt, ohne Git-Historie und ohne `instructions/dev/` (Stack-Entwicklung selbst, inkl. der vendorten `commonplace/`-Wissensbasis) - dauerhaft, ohne Restore-Weg. 2. **Den Agenten dort arbeiten lassen.** Öffne das Zielverzeichnis in deinem Agent-Harness (Claude Code, GitHub Copilot, Codex CLI, Mistral Vibe) und lass es `instructions/setup-instance.md` ausführen. Diese Anweisung fragt dich dabei explizit nach: - **Autor-Identität** (Name + E-Mail für `git config`) - wird nie geraten oder aus einem anderen Repo übernommen, und ist zugleich der Autorname jeder künftig angelegten Wiki-Seite (`$WIKI_AUTHOR` überschreibt dies bei Bedarf). - **Remote** (optional) - eine URL, wenn du das Repo auf einen Server pushen willst; sonst bleibt die Instanz lokal, und jedes `publish` läuft mit `--no-push`. - **KB-Sprache** - die exportierte Distribution bringt **Deutsch** mit: die Regel in `kb/CONTRACT.md`, das Vokabular in `instructions/german-terminology.md` und deutsche Abschnittsnamen in den Seitenvorlagen. Das ist eine Entscheidung dieser Ursprungsinstanz, keine Eigenschaft des Musters. Willst du eine andere Sprache, sag es **vor dem ersten Ingest** - danach ist es eine Migration jeder bereits angelegten Seite. - **Personalization** - wer diese Instanz bedient (`USER.md`) und wie sie klingt (`SOUL.md`). Die Distribution bringt nur `USER.md.template` und `SOUL.md.template` mit: persönlicher Inhalt gehört nicht in jede exportierte Kopie, aber beide Dateien werden in jeder Session gelesen, sind also Betriebsvoraussetzung. Der Agent interviewt dich entlang der Template-Abschnitte und schreibt deine Antworten **wörtlich** mit - inklusive der beiden Fragen, die er nicht raten darf: der **Persona-Name** und die **Themen, die bewusst draußen bleiben**. Danach ist die Instanz initialisiert, verifiziert und committet. Was von der Sprachwahl unberührt bleibt: die Trennung zwischen Prosa und Identifiern. Seitentitel, Wikilink-Ziele, Zitat-IDs, Schema-Werte, Tags, Befehle und Pfade folgen keiner KB-Sprache, sondern dem etablierten Namen der Sache - `Act Runner` heißt in jeder Instanz `Act Runner`. ## Weg C: Dieses Repo klonen Für die Arbeit am Stack selbst, oder um sich den mitgelieferten Korpus als begehbares Beispiel anzusehen. Was hier liegt, ist ein **Testbett und eine Demo**, keine produktive Wissensbasis: rund 170 Seiten, die den Stack selbst dokumentieren - Gates, Lint, Versionierung, Suche, das Wiki-Muster. Wer eigenes Wissen sammeln will, nimmt Weg A oder B und fängt mit einem leeren `kb/` an. ```bash git clone https://gitea.nehmer.net/torben/chemenu.git cd chemenu ``` Danach den Agenten `instructions/bootstrap.md` ausführen lassen (Werkzeugumgebung + Skills publizieren). Git-Repo, Autor-Identität und Inhalt existieren hier bereits. Ein Clone, der älter ist als die Personalization-Dateien, hat kein `USER.md`/`SOUL.md` - `doctor` meldet dafür `personalization: FAIL`. Das ist einmalig nachzuholen: nur **Schritt 6 (Personalization)** aus `instructions/setup-instance.md`, nicht der ganze Ablauf. `bootstrap.md` verweist an derselben Stelle darauf. `ENVIRONMENT.md` fehlt nach einem Clone immer - die Datei ist gitignored, weil sie *einen Checkout* beschreibt und nicht das Repo. Sie ist optional; wer sie anlegt, spart jeder folgenden Session die Fragen nach Harness, MCP-Servern und Remote. Vorlage: `ENVIRONMENT.md.template`, Ablauf: Schritt 5 in `instructions/bootstrap.md`. ## Weg D: Private Instanz mit diesem Repo als Upstream Die Kombination aus A und C: eine eigene, nicht öffentliche Instanz, die weiterhin Stack-Updates von hier zieht - per `git merge` statt per Tarball, also mit echtem Drei-Wege-Merge statt `cp -r`. Das ist der Weg mit dem höchsten Einsatz, weil ein Checkout dann zwei Remotes hat und git beim Push nicht unterscheidet, welcher welcher ist. Ein falsches `--remote` legt privaten Inhalt auf ein öffentliches Repo, und ein Force-Push holt das nicht zurück - die Objekte bleiben per SHA abrufbar, bis auf dem Server die Reflogs verfallen. Dagegen gibt es das **Publish-Remote-Gate**, und die Anleitung setzt es an die Stelle, an der es wirkt: *vor* dem ersten `publish`. Vollständiges Vorgehen: [instructions/private-instance.md](instructions/private-instance.md). ## Version und Updates Jede Instanz trägt die Version des **Stacks** (Werkzeuge, Typen, Instruktionen, Contracts) - nicht die ihres Inhalts. Sie steht in `VERSION`, und eine per Release oder `dist export` erzeugte Instanz trägt zusätzlich `.wikitool-release.json` mit Herkunft und Exportdatum. ```bash tools/wikitool version # was läuft hier, und woher kommt es tools/wikitool version check # gibt es ein neueres Release? ``` `version check` ist der einzige Befehl, der ins Netz geht. Er fragt den Release-Feed der Ursprungs-Instanz (`$WIKITOOL_UPDATE_URL` überschreibt; sonst der Wert aus dem Stamp). Ein nicht erreichbarer Feed wird als Fehler gemeldet - **nie** als „aktuell". **Was die Versionsnummer aussagt:** kompatibel ist, was in der *linkesten von Null verschiedenen Stelle* übereinstimmt. `0.1.3 → 0.1.4` ist ein sicheres Update, `0.1.3 → 0.2.0` verlangt eine Migration, und ab `1.0.0` liest sich dieselbe Regel als das gewohnte „MAJOR heißt Migration". `version check` sagt das direkt (`state: update` vs. `state: migration`). ### Eine Instanz aktualisieren Das Anwenden eines Updates ist ein bewusst manueller Vorgang - es schreibt in eine Instanz, die bereits Inhalt hat. Der Inhalt hat dabei eine **eigene Version**: `.wikitool-kb.json` sagt, in welcher Form die Seiten vorliegen, unabhängig davon, welche Maschinerie danebensteht. Genau dieser Unterschied ist der Zustand, in dem sich jede Instanz mitten im Upgrade befindet. 1. **Vor dem Tausch** prüfen, was ansteht - solange `VERSION` noch die alte ist: ```bash tools/wikitool migrate status ``` 2. Release-Tarball herunterladen und entpacken (Weg A), die Release-Notes lesen. 3. Die **Maschinerie** aus dem Tarball über die Instanz kopieren: `tools/`, `types/`, `instructions/`, `AGENTS.md`, `VERSION`, `.wikitool-release.json`. Nicht anfassen: `kb/`, `raw/`, `work/`, `.wikitool-kb.json` und `.git/` - das ist die Instanz selbst. 4. Achtung bei lokal angepassten Contract-Dateien: wer z. B. die KB-Sprache umgestellt hat (Schritt 5 in `setup-instance.md`), hat `kb/CONTRACT.md` und die Templates unter `types/` verändert. Diese Änderungen vorher sichern und danach wieder einspielen. Welche Dateien das sind, verrät ein Vergleich gegen die sha256-Summen im `files`-Block der alten `.wikitool-release.json`. 5. **Die Migrationskette abarbeiten.** `tools/wikitool migrate status` listet jetzt alle offenen Migrationen in der Reihenfolge, in der sie laufen müssen - bei einem Sprung über mehrere Versionen sind das mehrere. Für jede: das genannte Dokument unter `instructions/migrations/` ausführen lassen (die Prozedur dazu ist `instructions/migrate-corpus.md`), dann ```bash tools/wikitool migrate done ``` `done` verweigert jede Version, die nicht das nächste Glied ist - eine übersprungene Migration hinterlässt einen Korpus in einer Form, die keine Version beschreibt. Ein abgebrochenes Upgrade wird durch erneutes `migrate status` fortgesetzt. 6. Prüfen: `tools/wikitool migrate verify --from `, dann `doctor`, `docs verify`, `instructions verify` und `lint`. Zum Schluss `tools/wikitool instructions sync` (die Skills sind Kopien) und die Agent-Session neu starten. `doctor` warnt, solange `kb_version` hinter `VERSION` zurückliegt und noch Migrationen offen sind. Einer Instanz, die älter ist als `.wikitool-kb.json`, fehlt die Datei ganz - dann einmalig `tools/wikitool migrate baseline ` aufrufen; geraten wird nichts. ### Sonderfall: Update von 1.x auf 2.0.0 Mit `2.0.0` wurde das Ursprungs-Repo von `torben/llm-wiki-test1` auf `torben/chemenu` umbenannt. Eine Instanz, die vor diesem Release exportiert wurde, trägt in `.wikitool-release.json` noch den alten Feed - und `version check` fragt damit einen Pfad ab, den es unter diesem Namen nicht mehr gibt. Der Befehl bricht also nicht kaputt, er erfährt nur nichts mehr. Einmalig überschreiben: ```bash export WIKITOOL_UPDATE_URL="https://gitea.nehmer.net/api/v1/repos/torben/chemenu/releases/latest" tools/wikitool version check ``` Danach den Tarball aus Weg A holen - er heißt seit `2.0.0` `chemenu-stack-.tar.gz` statt `llm-wiki-stack-.tar.gz` - und den Ablauf oben normal durchlaufen. Das mitkopierte `.wikitool-release.json` trägt den neuen Feed, die Variable wird danach nicht mehr gebraucht. Zwei Nachräumarbeiten, weil Schritt 3 `tools/` kopiert und nichts löscht: das alte Paket `tools/wiki_tools/` bleibt neben dem neuen `tools/chemenu/` liegen und kann weg - der `tools/wikitool`-Shim ruft seit `2.0.0` `-m chemenu.cli` auf und rührt es nicht mehr an. Und eigene Skripte, die `from wiki_tools import …` machen, müssen auf `chemenu` gezogen werden. Eine Inhaltsmigration verlangt dieses Release nicht: `migrate status` bleibt leer, `kb/` behält Schema und Shape. ## Konfiguration | Variable | Zweck | Fallback | |----------|-------|----------| | `WIKI_AUTHOR` | Override für den Autornamen neuer Source-Seiten | `git config user.name` - fehlt beides, bricht `new` mit `ERROR` ab | | `WIKITOOL_SESSION_ID` | Scopt das Iteration-Budget-Gate auf eine Aufgabe statt auf ein Terminal | Parent-Process-ID (siehe [instructions/session-setup.md](instructions/session-setup.md)) | | `WIKITOOL_UPDATE_URL` | Release-Feed, den `version check` abfragt | Wert aus `.wikitool-release.json`, sonst der Feed der Ursprungs-Instanz | | `WIKITOOL_UPDATE_TOKEN` | Gitea-Token für den Release-Feed | keiner - gegen `torben/chemenu` nicht nötig, nur für einen privaten Fork (siehe unten) | **Gegen das Ursprungs-Repo braucht es kein Token.** `torben/chemenu` ist öffentlich lesbar; `version check` und der Download in Weg A funktionieren ohne Konfiguration. **Für einen privaten Fork schon.** Wer den Stack in ein eigenes, nicht öffentliches Repo legt und `WIKITOOL_UPDATE_URL` auf dessen Feed zeigen lässt, stößt auf eine Eigenheit, die man kennen sollte: Gitea antwortet anonymen Aufrufern für ein unsichtbares Repo mit demselben `404` wie für ein gar nicht existierendes. Ein fehlendes Release und ein fehlender Zugriff sehen dann identisch aus - „kein Update gefunden" wäre in dem Fall schlicht gelogen. Dagegen hilft ein Gitea-Token mit Lesezugriff: ```bash export WIKITOOL_UPDATE_TOKEN="" tools/wikitool version check ``` ## Verifikation ```bash tools/wikitool doctor ``` Prüft in einem Aufruf: Abhängigkeiten, Autor-Auflösung, Git-Identität/Branch/Remote, publizierte Skills, Struktur (Collection-Contracts, generierte Dateien), Personalization (`USER.md`/`SOUL.md` vorhanden **und** ausgefüllt), die optionale Umgebungsnotiz (`ENVIRONMENT.md`) und die Session-ID. `OK`/`WARN` sind unbedenklich (ein fehlender Remote z. B. ist ein gültiger Endzustand); nur ein `FAIL` bricht mit exit 1 ab, und jede Zeile nennt ihr eigenes Fix-Kommando. Danach zusätzlich: ```bash tools/wikitool docs verify tools/wikitool instructions verify ``` ## Troubleshooting - **`wikitool: venv not found`** - Schritt "Werkzeugumgebung anlegen" aus [instructions/bootstrap.md](instructions/bootstrap.md) bzw. [instructions/setup-instance.md](instructions/setup-instance.md) wurde noch nicht ausgeführt. - **Der Agent bietet keine Skills an (`wiki-ingest`, `wiki-query`, ...)** - `.agents/skills/` und `.claude/skills/` sind generiert und nicht committet. `tools/wikitool instructions sync` ausführen, dann die Agent-Session neu starten (Harnesses lesen Skills nur beim Start). - **`doctor` meldet `personalization: FAIL`** - `USER.md`/`SOUL.md` fehlen, oder sie tragen noch die Sentinel-Zeile aus dem Template (ein umbenanntes Template ist kein ausgefülltes). Den Personalization-Schritt (6) aus `instructions/setup-instance.md` ausführen lassen; bei einer Instanz nach Weg C ist das der einzige nachzuholende Schritt. - **`doctor` meldet `environment: WARN`** - `ENVIRONMENT.md` existiert, trägt aber noch die Sentinel-Zeile aus dem Template. Ausfüllen (Vorlage: `ENVIRONMENT.md.template`) und die Zeile entfernen, oder die Datei löschen - sie ist optional, und `absent` ist ein gültiger Endzustand. - **`new` bricht mit "No author configured" ab** - weder `$WIKI_AUTHOR` noch `git config user.name` sind gesetzt. `git config user.name ""` ausführen, oder `WIKI_AUTHOR` exportieren. - **`publish` endet mit Exit-Code 42 (Mass-Update-Gate)** - erwartetes Verhalten bei ≥10 gezählten Dateien (z. B. beim allerersten Commit einer neuen Instanz). Das ist kein Fehler, sondern die Aufforderung, die Ausgabe einem Menschen zu zeigen: sie enthält die vollständige Dateiliste und die exakte `--confirm `-Zeile, die nach Freigabe veröffentlicht. Details: [instructions/gates.md](instructions/gates.md). - **`publish` endet mit Exit-Code 42 (Publish-Remote-Gate)** - dieser Checkout hat eine `.wikitool-remotes.json`, und das angesteuerte Remote steht nicht darin. Ebenfalls kein Fehler: Die Ausgabe nennt die Push-URL, an die geschrieben würde, und die erlaubten. Anders als beim Mass-Update-Gate gibt es hier **keinen Token und keine Flagge** - stimmt das Ziel wirklich, trägt der Mensch dessen URL selbst in die Datei ein. Ein Agent, der die Datei anfasst, um an der Verweigerung vorbeizukommen, öffnet ein Gate aus eigenem Antrieb. - **Ich will am Tool-Stack selbst weiterarbeiten (nicht nur Wiki-Inhalt betreiben)** - eine neue Instanz hat dafür keinen Weg: `dist export` lässt `instructions/dev/` (Stack-Entwicklung, inkl. der vendorten `commonplace/`-Wissensbasis) bewusst und dauerhaft weg, ohne Restore-Mechanismus. Für Stack-Entwicklung im Ursprungs-Repo arbeiten (oder eine neue Dev-Instanz daraus exportieren) statt in dieser Instanz nachzurüsten.