Files changed: - .gitea/workflows/ci.yml - .gitea/workflows/release.yml - AGENTS.md - CHANGES.md - DEVELOPMENT.md - EVALS.md - INSTALL.md - README.md - VERSION - docs/ownership-and-templates.md - instructions/CONTRACT.md - instructions/bootstrap.md - instructions/dev/dev-setup.md - instructions/dev/stack-dev/SKILL.md - instructions/gates.md - instructions/ingest-large-tree.md - instructions/kb-profiles.md - instructions/mcp-read-server.md - instructions/migrations/3.0.0-authoring-conventions.md - instructions/preflight.md - instructions/private-instance.md - instructions/session-setup.md - instructions/setup-instance.md - instructions/upgrade-instance.md - tools/CONTRACT.md - tools/README.md - tools/chemenu/cli.py - tools/chemenu/cli_contract.py - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/upstream_cmd.py - tools/chemenu/commands/work_cmd.py - tools/chemenu/config.py - tools/chemenu/ownership.py - tools/chemenu/tests/test_cli.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_instructions_shell.py - tools/chemenu/tests/test_preflight.py - tools/chemenu/tests/test_preflight_pwsh.py - tools/chemenu/tests/test_run_budget.py - tools/chemenu/tests/test_upstream_cmd.py - tools/chemenu/toc.py - tools/preflight.ps1 - tools/preflight.sh
176 lines
10 KiB
Markdown
176 lines
10 KiB
Markdown
# Entwicklung dieses Stacks
|
||
|
||
Dieses Dokument richtet sich an Menschen, die an `tools/wikitool`, dem Type-Schema oder der
|
||
Instruction-/Skill-Schicht selbst arbeiten - nicht an den Konsumenten einer Instanz. Für die
|
||
Gegenseite (eine Instanz installieren, aktualisieren, betreiben) siehe [INSTALL.md](INSTALL.md).
|
||
|
||
**Diese Datei wird nicht ausgeliefert.** Sie ist das menschliche Gegenstück zu
|
||
`instructions/dev/`, das `tools/wikitool dist export` vollständig ausschließt: eine
|
||
ausgelieferte Instanz hat keinen Release-Workflow, keine CI und kein Issue-Board, also braucht
|
||
sie auch keine Anleitung dafür. `dist_cmd.ROOT_FILES` listet sie deshalb bewusst nicht - der
|
||
Grund steht dort als Kommentar, damit eine spätere Sitzung die vermeintliche Lücke nicht
|
||
"repariert". Und weil sie nicht ausgeliefert wird, darf sie - anders als `README.md`,
|
||
`INSTALL.md` oder `EVALS.md`, die `instructions verify` auf genau diesen Punkt prüft - nach
|
||
`instructions/dev/` verlinken.
|
||
|
||
## Entwicklungsumgebung
|
||
|
||
Am Stack wird in einem Klon dieses Repos gearbeitet. Ein solcher Klon ist **keine Instanz** und
|
||
wird nie eine. Instanzen entstehen ausschließlich aus Releases, siehe [INSTALL.md](INSTALL.md).
|
||
|
||
```bash
|
||
git clone https://gitea.nehmer.net/torben/chemenu.git
|
||
cd chemenu
|
||
```
|
||
|
||
Danach den Agenten `instructions/bootstrap.md` ausführen lassen: Preflight, dann
|
||
`tools/wikitool instructions sync`. Die Agenten-Seite dazu - was hier anders ist als in einer
|
||
Instanz und wie `dist export` als Testwerkzeug läuft - steht in
|
||
[instructions/dev/dev-setup.md](instructions/dev/dev-setup.md).
|
||
|
||
Was ein Klon mitbringt und eine Instanz nicht:
|
||
|
||
- **Den Demo-Korpus.** Rund 170 Seiten, die den Stack selbst dokumentieren: Gates, Lint,
|
||
Versionierung, Suche, das Wiki-Muster. Er ist Testbett und begehbares Beispiel, keine
|
||
produktive Wissensbasis. Was an ihm geändert werden darf, regelt
|
||
[instructions/dev/corpus-policy.md](instructions/dev/corpus-policy.md).
|
||
- **Eine Demo-Persona** in `USER.md`/`SOUL.md`. `doctor` meldet beide als ausgefüllt. Sie
|
||
beschreiben den Demo-Betrieb, nicht dich.
|
||
- **Telemetrie an.** Ohne `.wikitool-release.json` ist der Klon die Messstation, mit der der
|
||
Stack sich selbst bewertet ([EVALS.md](EVALS.md) § „Whether it runs at all“).
|
||
- **`instructions/dev/`, `commonplace/`, `.gitea/` und diese Datei.** `dist export` liefert
|
||
davon nichts aus.
|
||
|
||
`ENVIRONMENT.md` fehlt nach jedem Klon, weil die Datei gitignored ist: Sie beschreibt einen
|
||
Checkout, nicht das Repo. Wer sie anlegt (Vorlage `ENVIRONMENT.md.template`, Schritt 5 in
|
||
`instructions/bootstrap.md`), erspart jeder Stack-Sitzung die Fragen nach Harness, `gitea-mcp`
|
||
und Remote.
|
||
|
||
### `dist export` als Build- und Testwerkzeug
|
||
|
||
`tools/wikitool dist export <leeres Verzeichnis>` schreibt genau den Baum, den ein Release
|
||
ausliefert: Maschinerie ohne Wiki-Inhalt, ohne Git-Historie, ohne `instructions/dev/`. Damit
|
||
prüft man vor einem Release, was ausgeliefert würde (`--dry-run` listet es nur). Und man spielt
|
||
den Installationsweg nach, ohne auf ein Release zu warten: Tarball daraus bauen wie
|
||
`.gitea/workflows/release.yml`, dann das Preflight-Skript in einem leeren Verzeichnis mit
|
||
`--archive <tarball>` starten. Der CI-Schritt „The distribution works as a fresh instance“ in
|
||
`.gitea/workflows/ci.yml` macht genau das.
|
||
|
||
Für eine echte Instanz ist ein solcher Export kein Weg. Ihm fehlen die Release-Herkunft im
|
||
Stamp, und `dist upgrade --latest` vergleicht später gegen einen Stand, den es nie als Release
|
||
gab.
|
||
|
||
### Ein Release-Feed in einem nicht öffentlichen Repo
|
||
|
||
Wer den Stack in einem eigenen, nicht öffentlichen Repo betreibt und Instanzen von dort
|
||
aktualisiert, lässt `WIKITOOL_UPDATE_URL` auf dessen Feed zeigen. Dabei gibt es eine Eigenheit:
|
||
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 falsch. Dagegen hilft ein Gitea-Token mit
|
||
Lesezugriff in `WIKITOOL_UPDATE_TOKEN`. Es geht nur an Downloads auf demselben Host wie der Feed.
|
||
|
||
## Der Release-Ablauf
|
||
|
||
Zwischen zwei Releases führt der Stack **einen** laufenden Versionskandidaten statt einer neuen
|
||
Nummer pro Bump. Das volle Modell - Zustandsort, Eskalationslogik, warum eine Nummer erst durch
|
||
ein Release verbraucht wird - steht in
|
||
[instructions/dev/version-parts.md](instructions/dev/version-parts.md) und
|
||
[docs/version-model.md](docs/version-model.md). Hier nur der Ablauf, in der Reihenfolge, in der
|
||
eine Sitzung ihn tatsächlich durchläuft:
|
||
|
||
1. **Bump eröffnet oder eskaliert den Kandidaten, gewichtet mit `--impact`.**
|
||
|
||
```bash
|
||
tools/wikitool version bump --minor --title "Was sich geändert hat" --impact medium
|
||
```
|
||
|
||
Schreibt `VERSION` als `X.Y.Z-beta.N` und öffnet (oder aktualisiert) den passenden
|
||
`CHANGES.md`-Eintrag. Mehrere Bumps für dieselbe Änderung sind normal - jeder aktualisiert
|
||
denselben Eintrag, statt einen neuen zu eröffnen. `--impact high|medium|low` (Default
|
||
`medium`) gruppiert den Eintrag; `tools/wikitool version regrade` korrigiert eine Note später,
|
||
wenn der Gesamteindruck des Kandidaten den Blick auf einen früheren Bump ändert.
|
||
|
||
2. **Der Eintrag bekommt seine Prosa - zweigeteilt.** `bump` schreibt nur das Skelett (Heading,
|
||
Datum, Autor, die maschinenverwaltete, gruppierte Bump-Titel-Liste, ggf.
|
||
Breaking-/Migration-Zeile). Darunter kommen zwei Autorenanteile: eine kurze Zusammenfassung
|
||
(ein paar Sätze, worum es in diesem Release geht) direkt unter der Liste, und darunter je Bump
|
||
ein eigener `### <Bump-Titel>`-Changeset-Absatz. Details dazu in
|
||
[instructions/dev/version-parts.md](instructions/dev/version-parts.md) § The candidate model.
|
||
|
||
3. **Verify laufen lassen, bevor irgendetwas gepublished wird:**
|
||
|
||
```bash
|
||
cd tools && .venv/bin/python -m pytest -q
|
||
tools/wikitool docs verify
|
||
tools/wikitool instructions verify
|
||
```
|
||
|
||
4. **`version release` fixiert den Kandidaten**, sobald er ausgeliefert werden soll:
|
||
|
||
```bash
|
||
tools/wikitool version release --title "Zusammenfassender Titel"
|
||
```
|
||
|
||
Streicht den `-beta.N`-Suffix aus `VERSION` und schließt den Changelog-Eintrag. `--title` ist
|
||
optional - ohne ihn bleibt der Titel des letzten Bumps stehen; mit ihm bekommt ein Kandidat,
|
||
der mehrere Bump-Titel gesammelt hat, eine zusammenfassende Überschrift. Verweigert, wenn der
|
||
Kandidat zwei oder mehr Bumps gesammelt hat und die Zusammenfassung aus Schritt 2 noch fehlt -
|
||
ein Kandidat mit genau einem Bump ist davon ausgenommen. Committet und pusht nichts
|
||
(Invariante 5 in [AGENTS.md](AGENTS.md)).
|
||
|
||
5. **Publish bewegt `VERSION` auf `main`.**
|
||
|
||
```bash
|
||
tools/wikitool publish --message "..."
|
||
```
|
||
|
||
Das Mass-Update-Gate und das Publish-Remote-Gate gelten wie bei jedem anderen Publish -
|
||
siehe [instructions/gates.md](instructions/gates.md).
|
||
|
||
6. **CI übernimmt den Rest.** `.gitea/workflows/release.yml` reagiert auf jeden Push, der
|
||
`VERSION` bewegt: Eine suffixbehaftete `VERSION` (ein Kandidat) lässt den Job sauber
|
||
überspringen, bevor er die Releases-API überhaupt anfragt - Betas werden nie veröffentlicht.
|
||
Eine suffixfreie `VERSION` baut die Distribution (`dist export`), erzeugt Tag und Release und
|
||
lädt Tarball und Prüfsumme hoch, dazu die beiden Preflight-Skripte und die Anleitungen
|
||
`setup-instance.md` und `preflight.md`, auf die der Installationssatz in `INSTALL.md` zeigt.
|
||
**CI setzt den Tag, nie eine Sitzung** - das hält Invariante 5 intakt.
|
||
|
||
Die drei Verify-Befehle stehen oben in Schritt 3; was jeder von ihnen prüft, steht in
|
||
[tools/CONTRACT.md](tools/CONTRACT.md) und wird dort von `docs verify` gegen die tatsächliche
|
||
CLI gehalten. Hier steht es bewusst **nicht** noch einmal: eine zweite Beschreibung derselben
|
||
Befehle ist genau die Kopie, die driftet (AGENTS.md Invariante 8), und dieses Dokument liegt
|
||
außerhalb der Dateien, die der Kommando-Datensatz-Check von `docs verify` abdeckt - hier fällt eine
|
||
Drift also niemandem auf. Was `pytest` an dieser Stelle vom Entwickler erwartet, steht in
|
||
[instructions/dev/testing-conventions.md](instructions/dev/testing-conventions.md).
|
||
|
||
## Die CI-Hälfte
|
||
|
||
`.gitea/workflows/ci.yml` läuft auf jeden Push/PR gegen `main` (Content-Pfade ausgenommen) und
|
||
führt Testsuite, `docs verify`, `instructions verify` sowie einen vollständigen
|
||
`setup-instance.md`-Replay aus: ein lokal gebauter Release-Tarball, das Preflight-Skript mit
|
||
`--archive` in einem leeren Verzeichnis, dann die Schritte der Anleitung - derselbe Pfad, den
|
||
ein neuer Nutzer tatsächlich geht, nur ohne Download. `.gitea/workflows/nightly.yml` ist der Drift-Check gegen die Zeit statt
|
||
gegen einen Commit. `.gitea/workflows/release.yml` ist Schritt 6 oben.
|
||
|
||
Drei weitere Workflows tragen die Live-Tests der Tracker-Adapter (Super Productivity, CalDAV):
|
||
`ci.yml` führt in einem eigenen Schritt die CalDAV-Hälfte gegen ein Radicale als Prozess aus,
|
||
`tracker-live.yml` läuft nachts und deckt beide Anbieter ab, und `sp-live-image.yml` baut täglich
|
||
(bei neuer Version) und monatlich (immer) das Image `chemenu-sp-live` mit der jeweils aktuellen
|
||
Super-Productivity-Version. Das Image folgt dem Update-Kanal der Desktop-Clients, nicht einer
|
||
festen Version. Einmalig nach dem allerersten Push muss das Paket von Hand dem Repo
|
||
`torben/chemenu` zugeordnet werden. Was die Suite schreibt, wie man sie gegen einen eigenen
|
||
Tracker laufen lässt und was ein roter Lauf bedeutet, steht in
|
||
[instructions/dev/tracker-testing.md](instructions/dev/tracker-testing.md).
|
||
|
||
## Stack-Entwicklung als eigener Sitzungstyp
|
||
|
||
Der `stack-dev`-Skill (`instructions/dev/`, nur in diesem Ursprungs-Repo vorhanden) fasst die
|
||
Regeln für eine Sitzung, die den Stack selbst statt Wiki-Inhalt bearbeitet: wann
|
||
Quellenbindung nicht gilt, wo Design endet und die mechanische Phase beginnt (mit dem
|
||
Modellwechsel-Hinweis), und endet mit dem Publish. Die Schlussphase - Issue-Body als Rewrite
|
||
statt Kommentar, `docs/`-Veralterung, die Modell-Handover-Zeile über die ganze Sitzung - liegt
|
||
seit `4.6.0` in einem eigenen Folge-Skill, `stack-close`, den `stack-dev` an dieser Stelle
|
||
übergibt statt sie als weiteren eigenen Schritt zu führen. Siehe
|
||
[instructions/dev/issue-tracking.md](instructions/dev/issue-tracking.md) für den
|
||
Issue-Tracker selbst.
|