feat: INSTALL.md is the English installation tutorial; new tutorial docs/tutorials/first-source-to-first-answer.md with a shipped sample source; README.md links it as its first-ingestion step (#191)
Files changed: - CHANGES.md - INSTALL.md - README.md - VERSION - docs/reference/commands/types-instructions-and-docs.md - docs/tutorials/README.md - docs/tutorials/first-source-to-first-answer.md - docs/tutorials/sample-source.md - instructions/dev/doc-pull-through.md - tools/CONTRACT.md - tools/chemenu/commands/docs_verify.py - tools/chemenu/install_doc.py - tools/chemenu/tests/test_install_doc.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
1 parent
f9056c04f7
commit
fe1de63e0f
13 files changed
+403
-190
No files matched your search
+6
-1
@@ -14,7 +14,7 @@ place only: `instructions/dev/version-parts.md` § The candidate model.
|
||||
|
||||
---
|
||||
|
||||
## 9.0.0-beta.6 - 2026-10-06 - docs/: how-to guides, configuration reference and two explanation pages carved out of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md; the last two retired
|
||||
## 9.0.0-beta.7 - 2026-10-07 - INSTALL.md is an English installation tutorial; new tutorial from a first source to a first answer with a shipped sample; README.md a landing page
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
@@ -31,6 +31,7 @@ place only: `instructions/dev/version-parts.md` § The candidate model.
|
||||
- docs reference: human command reference under docs/reference/, generated from the command records
|
||||
- docs reference: skill catalogue and page types under docs/reference/, generated from the shipped defaults in the origin repo only
|
||||
- docs/: how-to guides, configuration reference and two explanation pages carved out of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md; the last two retired
|
||||
- INSTALL.md is an English installation tutorial; new tutorial from a first source to a first answer with a shipped sample; README.md a landing page
|
||||
|
||||
**Low impact**
|
||||
- version bump: Abschlussmeldung nennt Stichpunkt oder Themenabsatz statt pauschal Prosa
|
||||
@@ -38,6 +39,10 @@ place only: `instructions/dev/version-parts.md` § The candidate model.
|
||||
- tools/README.md module tree names reference_doc.py and the fourth view cli_contract renders
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
### Tutorials: installation in English, and a first source to a first answer (#191)
|
||||
|
||||
`INSTALL.md` stays at the root and is now the English installation tutorial, the first one `docs/tutorials/README.md` lists; its generated prerequisites lists and `setup-question` markers are unchanged, and `docs verify`'s finding for a missing question names the English section "What the agent asks you". The new `docs/tutorials/first-source-to-first-answer.md` walks a fresh instance through one ingest and two questions, one the wiki answers with citations and one it has no source for, using `docs/tutorials/sample-source.md`, a short made-up note that ships with every instance. `README.md`'s "Your first ingestion" is a link to it, which finishes `README.md` as a landing page.
|
||||
|
||||
### The root documents split into `docs/` pages (#190)
|
||||
|
||||
The task and explanation parts of `README.md`, `INSTALL.md`, `INSTALL-MCP.md` and `EVALS.md` are now single English pages: eleven how-to guides under `docs/how-to/` (ingest, capture, guideline export, query, maintenance, weekly review, Obsidian, updating an instance, troubleshooting, the MCP read server, tracing and scoring sessions), a hand-written `docs/reference/configuration.md`, and `docs/explanation/architecture.md` and `telemetry-and-evaluation.md`. A guide says what to prepare, what to tell the agent and where it stops; it links an agent's procedure instead of retelling it. `INSTALL-MCP.md` and `EVALS.md` are gone from the root and from `dist export`, so an upgrade removes them as retired; `README.md` is a landing page, and `INSTALL.md` keeps only the installation itself. Pointers in messages and command records, among them `version check`'s, name the new pages.
|
||||
|
||||
+136
-136
@@ -1,27 +1,27 @@
|
||||
# Installation
|
||||
# Install a Chemenu instance
|
||||
|
||||
Dieses Dokument richtet sich an Menschen. Es gibt genau einen Weg zu einer Chemenu-Instanz: Ein
|
||||
Agent installiert das **neueste Release** in ein leeres Verzeichnis, das du vorgibst. Die
|
||||
Schritte führt der Agent aus, nach `instructions/setup-instance.md` aus demselben Release. Hier
|
||||
steht, was du vorher bereitstellst, welchen Satz du ihm gibst, was er dich fragt und was zu tun
|
||||
ist, wenn er anhält. Die vollständige Kommandoreferenz steht in
|
||||
This tutorial takes you from an empty folder to a running Chemenu instance. There is exactly one
|
||||
way to get one: an agent installs the **latest release** into an empty folder you choose. The
|
||||
agent runs the steps, following `instructions/setup-instance.md` from that same release. This
|
||||
page covers what you prepare beforehand, the sentence you give the agent, what it asks you, and
|
||||
what to do when it stops. The full command reference is in
|
||||
[tools/CONTRACT.md](tools/CONTRACT.md).
|
||||
|
||||
Den optionalen **MCP-Leseserver** richtet
|
||||
[docs/how-to/set-up-the-mcp-server.md](docs/how-to/set-up-the-mcp-server.md) ein: derselbe
|
||||
Korpus, lesend, für einen Konsumenten, der kein Terminal auf dieser Maschine ist.
|
||||
The optional **MCP read server** is set up separately, once the instance runs:
|
||||
[docs/how-to/set-up-the-mcp-server.md](docs/how-to/set-up-the-mcp-server.md). It serves the same
|
||||
corpus, read-only, to a consumer that is not a terminal on this machine.
|
||||
|
||||
<!-- dist:strip-start -->
|
||||
Wer am Stack selbst arbeiten will, klont dieses Repo. Das ist eine Entwicklungsumgebung mit
|
||||
Demo-Korpus und keine Instanz; sie steht in [docs/dev/development.md](docs/dev/development.md).
|
||||
To work on the stack itself, clone this repository instead. That is a development checkout with a
|
||||
demo corpus, not an instance; it is described in [docs/dev/development.md](docs/dev/development.md).
|
||||
<!-- dist:strip-end -->
|
||||
|
||||
## Was vorher da sein muss
|
||||
## What you need first
|
||||
|
||||
Diese Programme prüft der Preflight, bevor irgendein `wikitool`-Befehl läuft. Installieren musst
|
||||
du sie selbst - der Agent tut es nie, auch nicht mit deiner Zustimmung. Wo eines fehlt, nennt
|
||||
der Preflight den Installationsbefehl für dein System. Die Liste wird aus
|
||||
`tools/prerequisites.txt` erzeugt, derselben Datei, die der Preflight liest:
|
||||
The preflight checks these programs before any `wikitool` command runs. You install them
|
||||
yourself - the agent never does, not even with your permission. Where one is missing, the
|
||||
preflight names the install command for your system. The list is generated from
|
||||
`tools/prerequisites.txt`, the same file the preflight reads:
|
||||
|
||||
<!-- wikitool:prerequisites -->
|
||||
- **Python** ≥ 3.11
|
||||
@@ -29,166 +29,166 @@ der Preflight den Installationsbefehl für dein System. Die Liste wird aus
|
||||
- **ripgrep (rg)**
|
||||
<!-- /wikitool:prerequisites -->
|
||||
|
||||
Dazu:
|
||||
You also need:
|
||||
|
||||
- **Ein Agent-Harness**: Claude Code, GitHub Copilot (in VS Code oder als CLI), Codex CLI oder
|
||||
- **An agent harness**: Claude Code, GitHub Copilot (in VS Code or as a CLI), Codex CLI or
|
||||
Mistral Vibe.
|
||||
- **Ein leeres Verzeichnis**, in dem die Instanz liegen soll, und dein Harness darin geöffnet.
|
||||
Leer heißt: nichts außer einem `.git`. Ein frisch geklontes, leeres Repo für deine Instanz ist
|
||||
also genau richtig - liegt dein Repo `torben/nathan` etwa in `~/src/nathan`, installierst du
|
||||
dorthin, und der Agent übernimmt dessen `origin` als Ziel für `publish`.
|
||||
- **An empty folder** for the instance, with your harness opened in it. Empty means nothing but a
|
||||
`.git`. A freshly cloned, empty repository for your instance is exactly right: if your
|
||||
repository `torben/nathan` lives in `~/src/nathan`, install there, and the agent keeps its
|
||||
`origin` as the target for `publish`.
|
||||
|
||||
Unter Windows zusätzlich, ebenfalls vom Preflight geprüft:
|
||||
On Windows, additionally, also checked by the preflight:
|
||||
|
||||
<!-- wikitool:prerequisites-windows -->
|
||||
- **PowerShell 7 (pwsh)** ≥ 7
|
||||
<!-- /wikitool:prerequisites-windows -->
|
||||
|
||||
Und außerdem:
|
||||
And on Windows also:
|
||||
|
||||
- **PowerShell 7 als Standardterminal in VS Code.** Windows PowerShell 5.1 reicht nicht, und WSL
|
||||
ist nicht vorgesehen.
|
||||
- **Execution Policy `RemoteSigned`** - auf vielen Rechnern ab Werk gesetzt
|
||||
(`Get-ExecutionPolicy -List` zeigt es).
|
||||
- **Git for Windows.** Es bringt Git Bash mit, in dem Claude Code seine Befehle ausführt.
|
||||
- **Ein Installationsverzeichnis mit höchstens 95 Zeichen**, zum Beispiel `C:\Chemenu`. Windows
|
||||
erlaubt ohne eingeschaltete lange Pfade nur 259 Zeichen je Pfad, und die Dateien des Wikis
|
||||
brauchen den Rest. Wer Administratorrechte hat, kann stattdessen lange Pfade einschalten
|
||||
(`LongPathsEnabled`); verlangt wird das nicht.
|
||||
- **PowerShell 7 as the default terminal in VS Code.** Windows PowerShell 5.1 is not enough, and
|
||||
WSL is not supported.
|
||||
- **Execution policy `RemoteSigned`** - the factory setting on many machines
|
||||
(`Get-ExecutionPolicy -List` shows it).
|
||||
- **Git for Windows.** It brings Git Bash, which Claude Code runs its commands in.
|
||||
- **An installation folder of at most 95 characters**, for example `C:\Chemenu`. Without long
|
||||
paths switched on, Windows allows only 259 characters per path, and the wiki's files need the
|
||||
rest. If you have administrator rights you can switch long paths on instead
|
||||
(`LongPathsEnabled`); that is not required.
|
||||
|
||||
## Der Satz für den Agenten
|
||||
## The sentence for the agent
|
||||
|
||||
Öffne das leere Verzeichnis in deinem Harness und gib dem Agenten diesen Satz:
|
||||
Open the empty folder in your harness and give the agent this sentence:
|
||||
|
||||
> Richte in diesem Verzeichnis eine neue Chemenu-Instanz ein. Hol dazu das neueste Release von
|
||||
> `https://gitea.nehmer.net/api/v1/repos/torben/chemenu/releases/latest` und folge dessen Asset
|
||||
> `setup-instance.md`. Lies vor dem Start des Preflights das Asset `preflight.md` aus demselben
|
||||
> Release.
|
||||
> Set up a new Chemenu instance in this folder. Fetch the latest release from
|
||||
> `https://gitea.nehmer.net/api/v1/repos/torben/chemenu/releases/latest` and follow its asset
|
||||
> `setup-instance.md`. Before you start the preflight, read the asset `preflight.md` from the same
|
||||
> release.
|
||||
|
||||
Damit liest der Agent die Beschreibung des neuesten Releases und daraus die beiden Anleitungen.
|
||||
Dann lädt er das passende Preflight-Skript (`preflight.ps1` für PowerShell, `preflight.sh` für
|
||||
eine POSIX-Shell) mit einem Befehl seiner Shell ins Verzeichnis - nicht über den Browser, damit
|
||||
Windows die Datei nicht als „aus dem Internet“ markiert - und startet es. Das Skript lädt den
|
||||
Tarball desselben Releases, prüft dessen sha256, entpackt ihn in das Verzeichnis, löscht sich
|
||||
selbst und prüft dann im entpackten Baum, ob alles da ist.
|
||||
With that, the agent reads the description of the latest release, and from it the two
|
||||
instructions. It then downloads the matching preflight script (`preflight.ps1` for PowerShell,
|
||||
`preflight.sh` for a POSIX shell) into the folder with a command of its shell - not through the
|
||||
browser, so that Windows does not mark the file as "from the internet" - and runs it. The script
|
||||
downloads the tarball of the same release, checks its sha256, unpacks it into the folder, deletes
|
||||
itself, and then checks in the unpacked tree that everything is in place.
|
||||
|
||||
Die Liste aller Releases: <https://gitea.nehmer.net/torben/chemenu/releases>. Das Repo ist
|
||||
öffentlich; der Download braucht weder Konto noch Token.
|
||||
All releases are listed at <https://gitea.nehmer.net/torben/chemenu/releases>. The repository is
|
||||
public; the download needs neither an account nor a token.
|
||||
|
||||
## Was der Agent dich fragt
|
||||
## What the agent asks you
|
||||
|
||||
Raten darf der Agent keine dieser Antworten, und keine übernimmt er aus einem anderen Repo:
|
||||
The agent may guess none of these answers, and it carries none of them over from another
|
||||
repository:
|
||||
|
||||
- <!-- setup-question: identity --> **Autor-Identität** - Name und E-Mail für `git config`. Das ist
|
||||
zugleich der Autorname jeder künftig angelegten Wiki-Seite (`$WIKI_AUTHOR` überschreibt ihn bei
|
||||
Bedarf).
|
||||
- <!-- setup-question: remote --> **Remote** - bei einem leeren Klon nur die Bestätigung, dass
|
||||
`origin` stimmt; sonst eine URL, wenn du auf einen Server pushen willst. Ohne Remote bleibt die
|
||||
Instanz lokal, und jedes `publish` läuft mit `--no-push`.
|
||||
- <!-- setup-question: kb-language --> **Sprache und Ton der Seiten** - sie landen in
|
||||
`kb/CONVENTIONS.md`, dazu je Collection `kb/<name>/COLLECTION.md`. Fertige Profile, darunter ein
|
||||
vollständiges deutsches, hält `instructions/kb-profiles.md` bereit. Entscheide das **vor dem
|
||||
ersten Ingest**: Danach ist ein Wechsel der Abschnittsnamen eine Migration jeder bestehenden
|
||||
Seite. Titel, Wikilink-Ziele, Zitat-IDs, Schema-Werte, Tags, Befehle und Pfade folgen keiner
|
||||
Sprache - `Act Runner` heißt in jeder Instanz `Act Runner`.
|
||||
- <!-- setup-question: domain --> **Anwendungsgebiet** - woraus dieses Wiki seine Quellen zieht.
|
||||
Daraus schlägt der Agent eine `source_type`-Liste vor (bei einem Verein etwa Satzung, Protokoll,
|
||||
Spielbericht). Das ist ein Startpunkt, keine Festlegung: Später wird sie an echtem Bestand
|
||||
korrigiert (`instructions/evolve-subtypes.md`).
|
||||
- <!-- setup-question: personalization --> **Personalisierung** - wer diese Instanz bedient
|
||||
(`USER.md`) und wie sie klingt (`SOUL.md`). Der Agent interviewt dich entlang der Vorlagen und
|
||||
schreibt deine Antworten wörtlich mit. Zwei Fragen beantwortest nur du: den **Namen der Persona**
|
||||
und die **Themen, die bewusst draußen bleiben**.
|
||||
- <!-- setup-question: environment --> **Umgebung** (optional) - Harness, MCP-Server, Remotes,
|
||||
damit spätere Sitzungen nicht erneut fragen. „Weiß ich nicht“ ist eine gültige Antwort.
|
||||
- <!-- setup-question: telemetry --> **Telemetrie** - standardmäßig aus; der Agent fragt nur, ob du
|
||||
sie einschalten willst.
|
||||
- <!-- setup-question: task-tracker --> **Aufgaben-Tracker** (optional) - siehe
|
||||
- <!-- setup-question: identity --> **Author identity** - name and email for `git config`. This is
|
||||
also the author name of every wiki page created from now on (`$WIKI_AUTHOR` overrides it when
|
||||
needed).
|
||||
- <!-- setup-question: remote --> **Remote** - for an empty clone, only the confirmation that
|
||||
`origin` is right; otherwise a URL, if you want to push to a server. Without a remote the
|
||||
instance stays local, and every `publish` runs with `--no-push`.
|
||||
- <!-- setup-question: kb-language --> **Language and tone of the pages** - they go into
|
||||
`kb/CONVENTIONS.md`, plus `kb/<name>/COLLECTION.md` per collection. Ready-made profiles,
|
||||
including a complete German one, are in `instructions/kb-profiles.md`. Decide this **before the
|
||||
first ingest**: afterwards, changing the section names is a migration of every existing page.
|
||||
Titles, wikilink targets, citation ids, schema values, tags, commands and paths follow no
|
||||
language - `Act Runner` is called `Act Runner` in every instance.
|
||||
- <!-- setup-question: domain --> **Subject area** - where this wiki draws its sources from. From
|
||||
it the agent proposes a `source_type` list (for a sports club, say: statutes, minutes, match
|
||||
report). That is a starting point, not a commitment: it gets corrected against real material
|
||||
later (`instructions/evolve-subtypes.md`).
|
||||
- <!-- setup-question: personalization --> **Personalization** - who operates this instance
|
||||
(`USER.md`) and how it sounds (`SOUL.md`). The agent interviews you along the templates and
|
||||
writes your answers down verbatim. Two questions only you answer: the **name of the persona**
|
||||
and the **topics that deliberately stay out**.
|
||||
- <!-- setup-question: environment --> **Environment** (optional) - harness, MCP servers, remotes,
|
||||
so that later sessions don't ask again. "I don't know" is a valid answer.
|
||||
- <!-- setup-question: telemetry --> **Telemetry** - off by default; the agent only asks whether
|
||||
you want to switch it on.
|
||||
- <!-- setup-question: task-tracker --> **Task tracker** (optional) - see
|
||||
[docs/reference/configuration.md](docs/reference/configuration.md#task-tracker).
|
||||
|
||||
Am Ende legt der Agent den ersten Commit an. Dabei hält das Mass-Update-Gate an (Exit 42), weil
|
||||
eine neue Instanz aus weit mehr als zehn Dateien besteht. Das ist erwartet: Der Agent zeigt dir
|
||||
die Dateiliste und die `--confirm`-Zeile, und erst nach deiner Freigabe wird veröffentlicht.
|
||||
Danach startest du die Agent-Sitzung im selben Verzeichnis neu, damit sie die Skills lädt.
|
||||
At the end the agent makes the first commit. The Mass-Update Gate stops it there (exit 42),
|
||||
because a new instance consists of far more than ten files. That is expected: the agent shows you
|
||||
the file list and the `--confirm` line, and nothing is published until you approve. Afterwards,
|
||||
restart the agent session in the same folder so that it loads the skills.
|
||||
|
||||
## Wenn der Agent anhält
|
||||
## When the agent stops
|
||||
|
||||
Der Preflight hält mit **Exit 42** an, wenn du etwas tun musst. Seine Ausgabe nennt in einem
|
||||
nummerierten Block, was fehlt, warum, den Befehl, der es behebt, und wie es weitergeht. Der
|
||||
Agent zeigt dir diesen Block unverändert, setzt eine Übersetzung höchstens darunter und wartet.
|
||||
Sag ihm Bescheid, wenn du fertig bist; dann prüft er erneut. Ausweichen oder selbst installieren
|
||||
darf er nicht.
|
||||
The preflight stops with **exit 42** when you have to do something. Its output names, in a
|
||||
numbered block, what is missing, why, the command that fixes it, and how to continue. The agent
|
||||
shows you this block unchanged, adds a translation below it at most, and waits. Tell it when you
|
||||
are done; then it checks again. It may not work around the stop or install anything itself.
|
||||
|
||||
**Beim Herunterladen und Entpacken** (das Skript aus dem Release, bevor es einen Baum gibt):
|
||||
**While downloading and unpacking** (the script from the release, before there is a tree):
|
||||
|
||||
- **Werkzeuge zum Laden oder Entpacken fehlen** (Exit 42). Unter Linux und macOS braucht das
|
||||
Skript `curl`, `tar` und `sha256sum` (oder `shasum`), unter Windows nur das `tar.exe` aus
|
||||
Windows 10/11. Installiere, was die Ausgabe nennt; unter Windows liefert Git for Windows alles
|
||||
für Git Bash mit.
|
||||
- **Das Verzeichnis ist zu lang** (Exit 42, nur Windows ohne lange Pfade). Nimm ein kürzeres,
|
||||
etwa `C:\Chemenu`, öffne es im Harness und gib den Satz dort noch einmal.
|
||||
- **Das Verzeichnis ist nicht leer** (Exit 1). Es darf nichts enthalten außer dem Skript und
|
||||
einem `.git`. Räume es selbst auf oder nimm ein anderes - der Agent löscht dort nichts.
|
||||
- **Download fehlgeschlagen oder Prüfsumme falsch** (Exit 1). Es wurde nichts entpackt. Prüf die
|
||||
Internetverbindung und lass es erneut versuchen; einen anderen Download-Weg sucht der Agent
|
||||
nicht. Ohne direkten Download kannst du Tarball und `.sha256` von der Release-Seite selbst
|
||||
nebeneinander ablegen; der Agent startet das Skript dann mit `--archive <tarball>`.
|
||||
- **Tools for downloading or unpacking are missing** (exit 42). On Linux and macOS the script
|
||||
needs `curl`, `tar` and `sha256sum` (or `shasum`); on Windows only the `tar.exe` that comes
|
||||
with Windows 10/11. Install what the output names; on Windows, Git for Windows brings
|
||||
everything for Git Bash.
|
||||
- **The folder path is too long** (exit 42, only on Windows without long paths). Take a shorter
|
||||
one, such as `C:\Chemenu`, open it in the harness and give the sentence there again.
|
||||
- **The folder is not empty** (exit 1). It may hold nothing but the script and a `.git`. Clean it
|
||||
up yourself or take another one - the agent deletes nothing there.
|
||||
- **Download failed or checksum wrong** (exit 1). Nothing was unpacked. Check the internet
|
||||
connection and let it try again; the agent does not look for another way to download. Without a
|
||||
direct download you can put the tarball and its `.sha256` from the release page side by side
|
||||
yourself; the agent then runs the script with `--archive <tarball>`.
|
||||
|
||||
**Im entpackten Baum** (jeder weitere Lauf ist `tools/preflight.sh` bzw. unter PowerShell
|
||||
**In the unpacked tree** (every further run is `tools/preflight.sh`, or under PowerShell
|
||||
`pwsh -NoProfile -ExecutionPolicy Bypass -File tools/preflight.ps1`):
|
||||
|
||||
- **Ein Werkzeug fehlt** - Python, git, ripgrep, unter Windows auch PowerShell 7. Die Ausgabe
|
||||
nennt den Installationsbefehl für dein System. Ist es schon installiert, nur woanders, nenn dem
|
||||
Agenten den Pfad; er reicht ihn mit `--set <werkzeug>=<pfad>` weiter.
|
||||
- **Eine Version ist zu alt** - zum Beispiel Python unter 3.11. Neuere Version installieren oder
|
||||
deren Pfad nennen.
|
||||
- **Ein genannter Pfad funktioniert nicht** - der Pfad muss auf das Programm selbst zeigen, nicht
|
||||
auf seinen Ordner.
|
||||
- **Die Python-Umgebung (`tools/.venv`) oder ihre Bibliotheken ließen sich nicht einrichten.** Die
|
||||
Ausgabe zeigt, was Python oder pip gemeldet haben. Meist blockiert ein Proxy oder ein
|
||||
Sicherheitsprogramm den Download; das klärt, wer deinen Rechner betreut.
|
||||
- **Skripte tragen die Markierung „aus dem Internet“** (nur Windows). Das passiert, wenn das
|
||||
Release im Browser geladen und im Explorer entpackt wurde. Einmal im Verzeichnis, in
|
||||
PowerShell 7: `Get-ChildItem -Recurse -File | Unblock-File`. `doctor` zeigt den Stand unter
|
||||
`script-marks`.
|
||||
- **Die Execution Policy verbietet Skripte** (`Restricted` oder `AllSigned`, nur Windows). Die
|
||||
Ausgabe nennt die eine Zeile für ein PowerShell-7-Fenster
|
||||
(`Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned`). Setzt eine
|
||||
Gruppenrichtlinie sie, hilft nur die IT - oder du arbeitest aus Git Bash mit `tools/wikitool`.
|
||||
`doctor` zeigt den Stand unter `execution-policy`.
|
||||
- **Das Installationsverzeichnis ist zu lang** (nur Windows ohne lange Pfade). Die Instanz muss
|
||||
in ein kürzeres Verzeichnis umziehen, etwa `C:\Chemenu`.
|
||||
- **A tool is missing** - Python, git, ripgrep, on Windows also PowerShell 7. The output names
|
||||
the install command for your system. If it is installed, just somewhere else, tell the agent the
|
||||
path; it passes it on with `--set <tool>=<path>`.
|
||||
- **A version is too old** - Python below 3.11, for example. Install a newer version or name its
|
||||
path.
|
||||
- **A path you named does not work** - the path must point at the program itself, not at its
|
||||
folder.
|
||||
- **The Python environment (`tools/.venv`) or its libraries could not be set up.** The output
|
||||
shows what Python or pip reported. Usually a proxy or a security program blocks the download;
|
||||
whoever looks after your machine can sort that out.
|
||||
- **Scripts carry the "from the internet" mark** (only on Windows). That happens when the release
|
||||
was downloaded in the browser and unpacked in Explorer. Once, in the folder, in PowerShell 7:
|
||||
`Get-ChildItem -Recurse -File | Unblock-File`. `doctor` shows the state under `script-marks`.
|
||||
- **The execution policy forbids scripts** (`Restricted` or `AllSigned`, only on Windows). The
|
||||
output names the one line for a PowerShell 7 window
|
||||
(`Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned`). If a group policy sets
|
||||
it, only your IT department can help - or you work from Git Bash with `tools/wikitool`. `doctor`
|
||||
shows the state under `execution-policy`.
|
||||
- **The installation folder path is too long** (only on Windows without long paths). The instance
|
||||
has to move to a shorter folder, such as `C:\Chemenu`.
|
||||
|
||||
Hält der Agent an einer anderen Stelle an und ist die Ursache nicht offensichtlich, bietet er dir
|
||||
einen Fehlerbericht an - siehe
|
||||
If the agent stops anywhere else and the cause is not obvious, it offers you a bug report - see
|
||||
[docs/how-to/troubleshoot.md](docs/how-to/troubleshoot.md).
|
||||
|
||||
## Verifikation
|
||||
## Check the instance
|
||||
|
||||
```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`), den Aufgaben-Tracker (`.wikitool-tasks.json` - fehlt sie, ist das `OK`; ist
|
||||
ein Provider konfiguriert, zusätzlich ob sein Lesepfad bereitsteht und seine API gerade
|
||||
antwortet, beides nie ein `FAIL`) 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.
|
||||
This checks in one call: dependencies, author resolution, git identity/branch/remote, published
|
||||
skills, structure (collection contracts, generated files), personalization (`USER.md`/`SOUL.md`
|
||||
present **and** filled in), the optional environment note (`ENVIRONMENT.md`), the task tracker
|
||||
(`.wikitool-tasks.json` - if it is missing, that is `OK`; if a provider is configured, also
|
||||
whether its read path is ready and its API is answering right now, neither ever a `FAIL`) and the
|
||||
session id. `OK`/`WARN` are harmless (a missing remote, for example, is a valid end state); only a
|
||||
`FAIL` ends with exit 1, and every line names its own fix command.
|
||||
|
||||
Danach zusätzlich:
|
||||
Then also:
|
||||
|
||||
```bash
|
||||
tools/wikitool docs verify
|
||||
tools/wikitool instructions verify
|
||||
```
|
||||
|
||||
## Danach
|
||||
## Next steps
|
||||
|
||||
- **Aktualisieren** auf ein neueres Release: [docs/how-to/update-an-instance.md](docs/how-to/update-an-instance.md).
|
||||
- **Konfiguration** - Umgebungsvariablen und die Dateien pro Checkout:
|
||||
- **Your first source and your first answer:**
|
||||
[docs/tutorials/first-source-to-first-answer.md](docs/tutorials/first-source-to-first-answer.md)
|
||||
walks you through both in the instance you just set up.
|
||||
- **Updating** to a newer release: [docs/how-to/update-an-instance.md](docs/how-to/update-an-instance.md).
|
||||
- **Configuration** - environment variables and the files per checkout:
|
||||
[docs/reference/configuration.md](docs/reference/configuration.md).
|
||||
- **Wenn etwas nicht geht:** [docs/how-to/troubleshoot.md](docs/how-to/troubleshoot.md).
|
||||
- **Mit dem Wiki arbeiten:** [docs/how-to/](docs/how-to/README.md).
|
||||
- **When something does not work:** [docs/how-to/troubleshoot.md](docs/how-to/troubleshoot.md).
|
||||
- **Working with the wiki:** [docs/how-to/](docs/how-to/README.md).
|
||||
@@ -45,7 +45,7 @@ Two starting points, depending on what you're doing:
|
||||
The human documentation lives under `docs/`, sorted by what you want from it:
|
||||
|
||||
- [docs/tutorials/](docs/tutorials/README.md) - learning: a guided first walk through an
|
||||
instance. Installation is still [INSTALL.md](INSTALL.md).
|
||||
instance, starting with the installation in [INSTALL.md](INSTALL.md).
|
||||
- [docs/how-to/](docs/how-to/README.md) - doing: one task per page, for the operator of an
|
||||
instance.
|
||||
- [docs/reference/](docs/reference/README.md) - looking up: commands, exit codes, skills, page
|
||||
@@ -61,26 +61,8 @@ How the parts fit together is [docs/explanation/architecture.md](docs/explanatio
|
||||
|
||||
## Your first ingestion
|
||||
|
||||
### First Steps
|
||||
|
||||
1. Read `AGENTS.md` - the control plane (invariants, routing, gates) - then the stage contract
|
||||
for whichever of `raw/`, `types/` or `kb/` you are working in, and, inside `kb/`, the
|
||||
`COLLECTION.md` of the collection you are writing to
|
||||
2. Add your first source to `incoming/`
|
||||
3. Run: `Ingest <your-file>`
|
||||
4. Review the created pages
|
||||
5. Ask your first query
|
||||
|
||||
### Example First Ingestion
|
||||
|
||||
```bash
|
||||
# Add a source
|
||||
cp ~/Downloads/my-notes.md incoming/my-notes.md
|
||||
|
||||
# Tell the LLM to process it
|
||||
# (in your LLM agent)
|
||||
Ingest incoming/my-notes.md
|
||||
```
|
||||
Once the instance runs, [From your first source to your first answer](docs/tutorials/first-source-to-first-answer.md)
|
||||
takes a sample document that ships with it through an ingest and a cited answer, step by step.
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ tools/wikitool docs prerequisites --apply
|
||||
|
||||
**Behaviour**
|
||||
|
||||
- Rewrites each `<!-- wikitool:prerequisites -->` region in `INSTALL.md` (tools every platform needs) and `<!-- wikitool:prerequisites-<platform> -->` region (tools only that platform needs) from the manifest: one list item per tool, its label and minimum version. The manifest's reason field stays out - it is English prose, and the region sits in a document that need not be.
|
||||
- Rewrites each `<!-- wikitool:prerequisites -->` region in `INSTALL.md` (tools every platform needs) and `<!-- wikitool:prerequisites-<platform> -->` region (tools only that platform needs) from the manifest: one list item per tool, its label and minimum version. The manifest's reason field stays out - it explains a tool to whoever reads the preflight's own output, while the region only says what to install.
|
||||
- Never places a region: where a list belongs in the human guide is that guide's own decision. A region the manifest calls for but the file lacks is an error naming the marker pair to add.
|
||||
- Dry-run by default (says whether the file would change); `--apply` writes.
|
||||
- `docs verify` checks the result stays current.
|
||||
|
||||
@@ -4,5 +4,10 @@ Learning-oriented pages: a guided first walk through an instance, start to finis
|
||||
who has not used one before. A tutorial shows one path that works; it does not list options or
|
||||
explain why.
|
||||
|
||||
Nothing is here yet. The installation tutorial is still [INSTALL.md](../../INSTALL.md) at the
|
||||
repository root, which stays there; a walk from the first source to the first answer is planned.
|
||||
Take them in this order:
|
||||
|
||||
1. [Install a Chemenu instance](../../INSTALL.md) - from an empty folder to a running instance.
|
||||
It stays at the repository root, where someone who has nothing else yet finds it first.
|
||||
2. [From your first source to your first answer](first-source-to-first-answer.md) - ingest a
|
||||
sample document, look at the pages it became, and ask the wiki a question about it.
|
||||
[sample-source.md](sample-source.md) is the document it uses.
|
||||
@@ -0,0 +1,157 @@
|
||||
# From your first source to your first answer
|
||||
|
||||
In this tutorial you put one document into a fresh instance, let the agent turn it into wiki
|
||||
pages, look at what it wrote, and then ask the wiki a question and follow the answer back to the
|
||||
document. It takes about a quarter of an hour. You need nothing but the instance and your harness:
|
||||
the document is a sample that ships with the instance.
|
||||
|
||||
You start from an instance that [INSTALL.md](../../INSTALL.md) has just set up, with the agent
|
||||
session restarted afterwards so that it has loaded its skills. Ask the agent `Which skills do you
|
||||
have?` if you are unsure - `wiki-ingest` and `wiki-query` should be among them.
|
||||
|
||||
<!-- wikitool:toc -->
|
||||
## Contents
|
||||
|
||||
- [1. Put the sample source into `incoming/`](#1-put-the-sample-source-into-incoming)
|
||||
- [2. Ask the agent to ingest it](#2-ask-the-agent-to-ingest-it)
|
||||
- [3. Tell the agent what matters](#3-tell-the-agent-what-matters)
|
||||
- [4. Answer the two capture questions](#4-answer-the-two-capture-questions)
|
||||
- [5. Let the agent publish](#5-let-the-agent-publish)
|
||||
- [6. Look at what it wrote](#6-look-at-what-it-wrote)
|
||||
- [7. Ask a question](#7-ask-a-question)
|
||||
- [8. Optional: browse it in Obsidian](#8-optional-browse-it-in-obsidian)
|
||||
- [What next](#what-next)
|
||||
<!-- /wikitool:toc -->
|
||||
|
||||
## 1. Put the sample source into `incoming/`
|
||||
|
||||
`incoming/` is where everything you want in the wiki waits until it is ingested. Copy the sample
|
||||
there - copy, not move, so the tutorial page keeps its sample:
|
||||
|
||||
```bash
|
||||
cp docs/tutorials/sample-source.md incoming/home-lab-backups.md
|
||||
```
|
||||
|
||||
On Windows in PowerShell 7:
|
||||
|
||||
```powershell
|
||||
Copy-Item docs/tutorials/sample-source.md incoming/home-lab-backups.md
|
||||
```
|
||||
|
||||
Open [the sample](sample-source.md) and read it once. It is a page of notes about the backups of a
|
||||
small home file server called Atlas: which tool makes them (restic), where they go, and why there
|
||||
are two targets (the 3-2-1 backup rule). Knowing what it says will let you check the agent's work.
|
||||
|
||||
## 2. Ask the agent to ingest it
|
||||
|
||||
In the agent session, say:
|
||||
|
||||
```text
|
||||
Ingest
|
||||
```
|
||||
|
||||
A bare `Ingest` takes the oldest entry waiting in `incoming/` - here, the only one. The agent
|
||||
reads the whole file before it writes anything.
|
||||
|
||||
## 3. Tell the agent what matters
|
||||
|
||||
The agent comes back with the key takeaways of the document and a few questions: which points
|
||||
matter most, which things should get a page of their own, and whether the document carries
|
||||
something you have to *do*. Answer in your own words, for example:
|
||||
|
||||
```text
|
||||
Atlas, restic and the 3-2-1 rule are what matter. Nothing to do from this one.
|
||||
```
|
||||
|
||||
The pages it writes next follow your answer, so this is the moment to steer. The agent may well
|
||||
notice that the notes leave something untested and offer to track it as a task; "nothing to do"
|
||||
declines that.
|
||||
|
||||
Often the same message already asks the two questions of the next step. Then answer them in the
|
||||
same reply.
|
||||
|
||||
## 4. Answer the two capture questions
|
||||
|
||||
Before the file leaves `incoming/`, the agent asks two things about the capture itself:
|
||||
|
||||
- **`fidelity`** - how faithful is this file to the original? The sample is the notes exactly as
|
||||
written, so the answer is `verbatim`.
|
||||
- **`authority`** - what may the material claim about its subject? The notes describe how a setup
|
||||
works; they do not set a standard anyone else has to follow. The answer is `reporting`.
|
||||
|
||||
```text
|
||||
verbatim, reporting
|
||||
```
|
||||
|
||||
The agent never guesses these two. Only you know them, and only now: once the file is in the wiki,
|
||||
nobody can tell any more where it came from. [raw/CONTRACT.md](../../raw/CONTRACT.md#capture-fields-fidelity-and-authority)
|
||||
lists every value, for the sources you add later.
|
||||
|
||||
## 5. Let the agent publish
|
||||
|
||||
The agent now moves the file into `raw/`, writes the pages, and publishes everything as one
|
||||
commit. For a source this small that goes straight through; the agent tells you what it committed.
|
||||
If your instance has no remote, the commit stays on your machine.
|
||||
|
||||
A larger source - ten or more new or changed pages and files, not counting the generated indexes
|
||||
and log - stops at the Mass-Update Gate instead: you see the list of files and a line ending in
|
||||
`--confirm <token>`, and nothing is committed until you tell the agent to go ahead.
|
||||
|
||||
## 6. Look at what it wrote
|
||||
|
||||
Ask the agent where the pages are, or look yourself. You will find:
|
||||
|
||||
- **The file itself under `raw/`**, in a folder for the current year and month. It is never edited
|
||||
again.
|
||||
- **A source page under `kb/sources/`**, summarising the notes. Its frontmatter carries your two
|
||||
answers, `fidelity: verbatim` and `authority: reporting`, and `raw_files:` points at the file in
|
||||
`raw/`.
|
||||
- **Entity and concept pages** for what you said matters - Atlas, restic, the 3-2-1 backup rule,
|
||||
in the language and naming your instance chose at setup. Each one links back to the source page,
|
||||
and each claim taken from the notes carries a footnote citing it.
|
||||
- **A new entry at the end of `kb/log.md`**, recording the ingest.
|
||||
|
||||
The exact set of pages depends on your answer in step 3, and on the agent: two runs of this
|
||||
tutorial do not produce word-for-word the same wiki. What is always the same is that every page is
|
||||
tied back to the file in `raw/`.
|
||||
|
||||
## 7. Ask a question
|
||||
|
||||
Start a new agent session, so that the answer can only come from the wiki and not from what the
|
||||
agent remembers of the ingest, and ask:
|
||||
|
||||
```text
|
||||
How are the backups of Atlas protected against a fire in the house?
|
||||
```
|
||||
|
||||
The answer names the storage box outside the house as the copy that survives, and the 3-2-1 rule
|
||||
as the reason it exists. It cites the pages it came from and the source behind them. Open one of
|
||||
the cited pages and follow its footnote: it leads to the source page, and that one to the file in
|
||||
`raw/` - the notes you copied in step 1.
|
||||
|
||||
Now ask something the notes do not answer:
|
||||
|
||||
```text
|
||||
How long does a full restore of Atlas take?
|
||||
```
|
||||
|
||||
The notes say only that one has never been tried. The agent tells you that the wiki has no source
|
||||
for this, rather than estimating one. That is the rule behind every answer: no claim without a
|
||||
source.
|
||||
|
||||
## 8. Optional: browse it in Obsidian
|
||||
|
||||
Open the instance's root folder as a vault in [Obsidian](https://obsidian.md). The graph view shows
|
||||
the pages you just made and the links between them. Read there as much as you like, but change
|
||||
pages through the agent: [Browse the wiki in Obsidian](../how-to/browse-with-obsidian.md) explains
|
||||
why.
|
||||
|
||||
## What next
|
||||
|
||||
You have taken one source all the way from a file to a cited answer. From here on, the how-to
|
||||
guides cover the everyday tasks:
|
||||
|
||||
- [Ingest a source](../how-to/ingest-a-source.md) - your own files, folders and web pages
|
||||
- [Query the wiki](../how-to/query-the-wiki.md) - and search it yourself
|
||||
- [Maintain the wiki](../how-to/maintain-the-wiki.md) - the lint the agent suggests every ten
|
||||
sources
|
||||
@@ -0,0 +1,48 @@
|
||||
# Home lab backups - how they work now
|
||||
|
||||
Notes written after reworking the backups in September 2026. This file is the sample source for
|
||||
the tutorial "From your first source to your first answer"; the machine and its setup are made
|
||||
up for it.
|
||||
|
||||
## The machine
|
||||
|
||||
**Atlas** is the small file server in the hall cupboard: a fanless mini PC with two 4 TB disks
|
||||
in a mirror, running Debian 13. It holds the family photo archive, scanned documents and the
|
||||
configuration of every other machine in the house. Everything else on the network is replaceable;
|
||||
what is on Atlas is not.
|
||||
|
||||
## The tool
|
||||
|
||||
Backups are made with **restic**, an open-source backup program. restic splits files into chunks,
|
||||
stores each chunk only once and encrypts everything before it leaves the machine, so the backup
|
||||
target never sees a file name or a byte of content in the clear. A restic *repository* is the
|
||||
storage location it writes to; a *snapshot* is one backup run.
|
||||
|
||||
restic was chosen over plain `rsync` for two reasons: deduplication keeps the daily runs small,
|
||||
and encryption makes it safe to put a copy on storage someone else operates.
|
||||
|
||||
## How it is set up
|
||||
|
||||
Atlas runs restic every night at 02:30 from a systemd timer. Each run writes one snapshot to two
|
||||
repositories:
|
||||
|
||||
- a USB disk that stays plugged into Atlas, for fast restores;
|
||||
- a rented storage box at a hosting provider, reached over SFTP, as the copy outside the house.
|
||||
|
||||
Snapshots are thinned out by `restic forget` after each run: the last 7 daily, 5 weekly and
|
||||
12 monthly snapshots are kept.
|
||||
|
||||
## Why two targets
|
||||
|
||||
The setup follows the **3-2-1 backup rule**: keep three copies of the data, on two different
|
||||
kinds of storage, with one copy off site. Here the three copies are the mirror on Atlas itself,
|
||||
the USB disk, and the storage box. A fire or a burglary takes the first two; the storage box is
|
||||
what is left.
|
||||
|
||||
The mirror alone does not count as a backup. It protects against a dead disk, but a deleted or
|
||||
encrypted file is deleted or encrypted on both disks at once.
|
||||
|
||||
## What is still open
|
||||
|
||||
The restore has been tried once, for a single folder, from the USB disk. It worked and took
|
||||
under a minute. A full restore from the storage box has not been tried.
|
||||
@@ -41,7 +41,7 @@ touched; a row that does not apply needs no action.
|
||||
| A task-tracker adapter (`tools/chemenu/tasks/`), its recorded fixtures, or the live suite | [instructions/dev/tracker-testing.md](tracker-testing.md), and `MANIFEST.json` beside the fixtures when they were re-recorded |
|
||||
| A skill's own step sequence or catalogue | The skill's `SKILL.md` source under `instructions/<name>/` or `instructions/dev/<name>/`; for a shipped skill (not under `instructions/dev/`) whose name or `description` changed, or one added or removed, `wikitool docs reference --apply` for the skill catalogue `docs/reference/skills.md` |
|
||||
| A per-checkout configuration file an instance owns (`.wikitool-tasks.json`, `.wikitool-telemetry.json`, `.wikitool-remotes.json`, `.wikitool-upload.json`) | [docs/reference/configuration.md](../../docs/reference/configuration.md), where an operator looks the shape up - written by hand, since nothing generates it; the [setup-instance.md](../setup-instance.md) decision point that offers it during setup; and `doctor`'s own row in [tools/CONTRACT.md](../../tools/CONTRACT.md), since `doctor` is what reports the file's state |
|
||||
| An installation instruction - [preflight.md](../preflight.md), [setup-instance.md](../setup-instance.md), [bootstrap.md](../bootstrap.md), [upgrade-instance.md](../upgrade-instance.md) - or `tools/prerequisites.txt` | [INSTALL.md](../../INSTALL.md), the human guide to the same procedure - for `upgrade-instance.md`, [docs/how-to/update-an-instance.md](../../docs/how-to/update-an-instance.md) instead. Read it against the instruction: what to prepare, the sentence for the agent, what the agent asks, where it stops and why. `docs verify` checks only the two enumerable overlaps - the prerequisites lists, which `wikitool docs prerequisites --apply` regenerates from the manifest, and the setup questions: a question the agent asks the user carries `<!-- setup-question: <key> -->` where it is asked in `setup-instance.md`, and `INSTALL.md` § "Was der Agent dich fragt" names it with the same marker. Every other sentence is this session's to compare. `INSTALL.md` does not retell the steps, so a change to their order or wording alone moves nothing there |
|
||||
| An installation instruction - [preflight.md](../preflight.md), [setup-instance.md](../setup-instance.md), [bootstrap.md](../bootstrap.md), [upgrade-instance.md](../upgrade-instance.md) - or `tools/prerequisites.txt` | [INSTALL.md](../../INSTALL.md), the human guide to the same procedure - for `upgrade-instance.md`, [docs/how-to/update-an-instance.md](../../docs/how-to/update-an-instance.md) instead. Read it against the instruction: what to prepare, the sentence for the agent, what the agent asks, where it stops and why. `docs verify` checks only the two enumerable overlaps - the prerequisites lists, which `wikitool docs prerequisites --apply` regenerates from the manifest, and the setup questions: a question the agent asks the user carries `<!-- setup-question: <key> -->` where it is asked in `setup-instance.md`, and `INSTALL.md` § "What the agent asks you" names it with the same marker. Every other sentence is this session's to compare. `INSTALL.md` does not retell the steps, so a change to their order or wording alone moves nothing there |
|
||||
| [dev-setup.md](dev-setup.md), the release workflow (`version bump`/`version release`/`publish`/CI), or another developer-facing process | [docs/dev/development.md](../../docs/dev/development.md), read against it the same way - nothing checks this pair at all. A page under `docs/dev/` is never shipped, so it may link into `instructions/dev/` and cite issue numbers |
|
||||
| A new page type the stack requires, or a new collection | Its type-spec and `COLLECTION.md` (both as the `.template` an instance adopts), the collection table in [kb/CONTRACT.md](../../kb/CONTRACT.md), and **both adoption paths**: [setup-instance.md](../setup-instance.md) for a fresh instance and [upgrade-instance.md](../upgrade-instance.md) for an existing one, where an unadopted template is what `docs verify` refuses. A new or changed `root: kb` type-spec or its schema - description, `layout:`, subtype enum, required fields - also needs `wikitool docs reference --apply` for `docs/reference/page-types.md` |
|
||||
|
||||
|
||||
+1
-1
@@ -2651,7 +2651,7 @@ Regenerate `INSTALL.md`'s prerequisites lists from `tools/prerequisites.txt`.
|
||||
|
||||
**NOTES**
|
||||
|
||||
- Rewrites each `<!-- wikitool:prerequisites -->` region in `INSTALL.md` (tools every platform needs) and `<!-- wikitool:prerequisites-<platform> -->` region (tools only that platform needs) from the manifest: one list item per tool, its label and minimum version. The manifest's reason field stays out - it is English prose, and the region sits in a document that need not be.
|
||||
- Rewrites each `<!-- wikitool:prerequisites -->` region in `INSTALL.md` (tools every platform needs) and `<!-- wikitool:prerequisites-<platform> -->` region (tools only that platform needs) from the manifest: one list item per tool, its label and minimum version. The manifest's reason field stays out - it explains a tool to whoever reads the preflight's own output, while the region only says what to install.
|
||||
- Never places a region: where a list belongs in the human guide is that guide's own decision. A region the manifest calls for but the file lacks is an error naming the marker pair to add.
|
||||
- Dry-run by default (says whether the file would change); `--apply` writes.
|
||||
- `docs verify` checks the result stays current.
|
||||
|
||||
@@ -1555,8 +1555,8 @@ def toc_command(
|
||||
"Rewrites each `<!-- wikitool:prerequisites -->` region in `INSTALL.md` (tools every "
|
||||
"platform needs) and `<!-- wikitool:prerequisites-<platform> -->` region (tools only that "
|
||||
"platform needs) from the manifest: one list item per tool, its label and minimum "
|
||||
"version. The manifest's reason field stays out - it is English prose, and the region "
|
||||
"sits in a document that need not be.",
|
||||
"version. The manifest's reason field stays out - it explains a tool to whoever reads "
|
||||
"the preflight's own output, while the region only says what to install.",
|
||||
"Never places a region: where a list belongs in the human guide is that guide's own "
|
||||
"decision. A region the manifest calls for but the file lacks is an error naming the "
|
||||
"marker pair to add.",
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
"""The two places `INSTALL.md` overlaps the installation instructions, held to them.
|
||||
|
||||
`INSTALL.md` is written for a human and in the instance's KB language;
|
||||
`instructions/setup-instance.md` is written for an agent and in English. A
|
||||
single file serving both was rejected: an agent reads every sentence as an
|
||||
instruction, and the human needs preparation and decisions where the agent
|
||||
needs steps and exit codes. So the human document does not retell the
|
||||
procedure, and what it still shares with the instructions is two enumerable
|
||||
lists - both checked here, so neither can drift silently:
|
||||
`INSTALL.md` is written for a human, `instructions/setup-instance.md` for an
|
||||
agent; both in English (`AGENTS.md` § File naming). A single file serving
|
||||
both was rejected: an agent reads every sentence as an instruction, and the
|
||||
human needs preparation and decisions where the agent needs steps and exit
|
||||
codes. So the human document does not retell the procedure, and what it still
|
||||
shares with the instructions is two enumerable lists - both checked here, so
|
||||
neither can drift silently:
|
||||
|
||||
1. **What the machine needs.** `tools/prerequisites.txt` is the one list; the
|
||||
preflight and `doctor` read it. `INSTALL.md` carries it as a generated
|
||||
region per platform value (`<!-- wikitool:prerequisites -->` for `all`,
|
||||
`<!-- wikitool:prerequisites-<platform> -->` otherwise), rendered from the
|
||||
label and minimum version only. The manifest's `why` field stays out: it is
|
||||
English prose, and the region sits in a document that is not. A region is
|
||||
never placed by the tool - where it goes is the human document's own
|
||||
decision - so a missing one is reported, not appended.
|
||||
label and minimum version only. The manifest's `why` field stays out: it
|
||||
explains a tool to whoever reads the preflight's own output, while the
|
||||
region only says what to install. A region is never placed by the tool -
|
||||
where it goes is the human document's own decision - so a missing one is
|
||||
reported, not appended.
|
||||
2. **What the agent asks the user.** Every place `setup-instance.md` puts a
|
||||
question to the user carries `<!-- setup-question: <key> -->`, and the
|
||||
bullet in `INSTALL.md` that tells the human about it carries the same
|
||||
marker. The two key sets must be equal: a question the human guide does not
|
||||
mention catches them unprepared, and one it mentions that is no longer asked
|
||||
is a claim about a procedure that no longer exists. The key is the shared
|
||||
identifier precisely because the surrounding prose is in two languages.
|
||||
bullet in `INSTALL.md` § "What the agent asks you" that tells the human
|
||||
about it carries the same marker. The two key sets must be equal: a
|
||||
question the human guide does not mention catches them unprepared, and one
|
||||
it mentions that is no longer asked is a claim about a procedure that no
|
||||
longer exists. The key is the shared identifier because the two texts word
|
||||
the same question for different readers, and neither wording is stable
|
||||
enough to match on.
|
||||
|
||||
Everything else in `INSTALL.md` is prose no check reads;
|
||||
`instructions/dev/doc-pull-through.md` names it as session work.
|
||||
@@ -37,6 +40,10 @@ from chemenu import blocks, config, prerequisites
|
||||
INSTALL_DOC = "INSTALL.md"
|
||||
SETUP_INSTRUCTION = "instructions/setup-instance.md"
|
||||
|
||||
# The heading in INSTALL.md whose bullets carry the setup-question markers -
|
||||
# named in check_setup_questions' finding, and held to the real file by a test.
|
||||
QUESTIONS_SECTION = "What the agent asks you"
|
||||
|
||||
REGION_PREFIX = "prerequisites"
|
||||
|
||||
QUESTION_RE = re.compile(r"<!-- setup-question: ([a-z][a-z0-9-]*) -->")
|
||||
@@ -101,7 +108,7 @@ def refresh(text: str, manifest: prerequisites.Manifest) -> tuple[str, list[str]
|
||||
|
||||
A region the manifest no longer has a platform for is left alone and
|
||||
reported by `check_prerequisite_regions`, not deleted here: the prose
|
||||
introducing it ("Unter Windows zusätzlich:") would otherwise be left
|
||||
introducing it ("On Windows, additionally ...") would otherwise be left
|
||||
standing over nothing.
|
||||
"""
|
||||
missing = []
|
||||
@@ -166,8 +173,8 @@ def check_setup_questions() -> list[str]:
|
||||
named = question_keys(install.read_text(encoding="utf-8"))
|
||||
|
||||
issues = [
|
||||
f"{SETUP_INSTRUCTION} asks the user `{key}`, but {INSTALL_DOC} § \"Was der Agent dich "
|
||||
f"fragt\" does not name it - add a bullet carrying `<!-- setup-question: {key} -->`"
|
||||
f"{SETUP_INSTRUCTION} asks the user `{key}`, but {INSTALL_DOC} § \"{QUESTIONS_SECTION}\" "
|
||||
f"does not name it - add a bullet carrying `<!-- setup-question: {key} -->`"
|
||||
for key in sorted(asked - named)
|
||||
]
|
||||
issues += [
|
||||
|
||||
@@ -16,22 +16,22 @@ MANIFEST = prerequisites.Manifest(
|
||||
|
||||
CURRENT = """# Installation
|
||||
|
||||
Vorher:
|
||||
You need:
|
||||
|
||||
<!-- wikitool:prerequisites -->
|
||||
- **Python** ≥ 3.11
|
||||
- **Git**
|
||||
<!-- /wikitool:prerequisites -->
|
||||
|
||||
Unter Windows zusätzlich:
|
||||
On Windows, additionally:
|
||||
|
||||
<!-- wikitool:prerequisites-windows -->
|
||||
- **PowerShell 7 (pwsh)** ≥ 7
|
||||
<!-- /wikitool:prerequisites-windows -->
|
||||
|
||||
## Was der Agent dich fragt
|
||||
## What the agent asks you
|
||||
|
||||
- <!-- setup-question: identity --> **Autor-Identität** - Name und E-Mail.
|
||||
- <!-- setup-question: identity --> **Author identity** - name and email.
|
||||
"""
|
||||
|
||||
SETUP = """# Set up
|
||||
@@ -57,6 +57,14 @@ def test_this_repos_install_doc_names_every_setup_question():
|
||||
assert install_doc.check_setup_questions() == []
|
||||
|
||||
|
||||
def test_this_repos_install_doc_has_the_section_the_finding_names():
|
||||
"""A missing question is reported as missing from a named section; that
|
||||
name is a constant, and a renamed heading would leave the finding pointing
|
||||
at nothing."""
|
||||
text = install_doc.install_doc_path().read_text(encoding="utf-8")
|
||||
assert f"\n## {install_doc.QUESTIONS_SECTION}\n" in text
|
||||
|
||||
|
||||
def test_this_repos_setup_instruction_marks_its_questions():
|
||||
"""The check compares two sets; an instruction that lost every marker would
|
||||
compare empty against empty and pass. Guard the real file's own count."""
|
||||
@@ -133,10 +141,11 @@ def test_a_question_the_install_doc_does_not_name_fails(tmp_path, monkeypatch):
|
||||
issues = install_doc.check_setup_questions()
|
||||
assert len(issues) == 1
|
||||
assert "`remote`" in issues[0] and "does not name it" in issues[0]
|
||||
assert f'§ "{install_doc.QUESTIONS_SECTION}"' in issues[0]
|
||||
|
||||
|
||||
def test_a_question_no_longer_asked_fails(tmp_path, monkeypatch):
|
||||
install = CURRENT + "- <!-- setup-question: telemetry --> **Telemetrie**\n"
|
||||
install = CURRENT + "- <!-- setup-question: telemetry --> **Telemetry**\n"
|
||||
_tree(tmp_path, monkeypatch, install=install)
|
||||
issues = install_doc.check_setup_questions()
|
||||
assert len(issues) == 1
|
||||
|
||||
Reference in new issue
Block a user