# Betrieb

Diese Seite ist für die Person, die die Registry betreibt. Sie braucht
`git`, `gh` und Zugriff auf das Repo.

## Wo läuft was

| Teil | Ort | Auslöser |
|---|---|---|
| CI-Gate | `.github/workflows/ci.yml` | jeder Push auf `main`, jeder Pull Request |
| Deploy | `.github/workflows/deploy.yml` | nach jedem CI-Lauf auf `main`, nächtlich 00:00 UTC, von Hand |
| BMAD-Pin | `.github/workflows/bump-bmad.yml` | montags 03:30 UTC, von Hand |
| Registry | Branch `gh-pages`, Pages "legacy" | vom Deploy geschrieben |

## Routine

**Deploy von Hand starten:** `gh workflow run deploy.yml`. Erwartete
Ausgabe: ein grüner Lauf unter `gh run list --workflow "Nightly Build & Deploy" --limit 1`.

**Nachtlauf reaktivieren:** GitHub schaltet Zeitpläne nach 60 Tagen ohne
Commit ab. Ein beliebiger Commit auf `main` oder `gh workflow enable deploy.yml`
schaltet ihn wieder ein.

**Webdienst:** Der Workflow `Service Image` baut nach jedem grünen
CI-Lauf auf `main` das Image `ghcr.io/deltatree/bestaiconfig`. Beim Bau
läuft der BMAD-Installer einmal im Container. Danach stößt der Workflow
den Stack auf dtadmin per Webhook an. Prüfen:
`curl -fsS https://bestaiconfig.apps.dtcloud.de/healthz` liefert `ok`.
Von Hand bauen: `gh workflow run service.yml`. Lokal testen:
`docker build -f service/Dockerfile -t bestaiconfig . && docker run -p 8080:8080 bestaiconfig`.
Rückweg bei einem kaputten Image: den Stack auf dtadmin auf den Tag der
Vorversion stellen (`ghcr.io/deltatree/bestaiconfig:<version>`). Fällt
der Dienst ganz aus, installiert der Installer weiter von GitHub Pages,
nur ohne BMAD.

**BMAD-Pin heben:** Der Workflow öffnet einen Pull Request. Er prüft den
Installer (`bmad-method` auf npm) und die Modul-Pins `cis` und `tea`
(Git-Tags auf GitHub). Mergen, wenn die CI grün ist. Von Hand: Version
oder `--pin code=tag` in `targets.json` ändern, Suite laufen lassen, Pull
Request. Bei einer neuen Hauptversion zuerst die Release-Notes auf
Breaking Changes lesen.

**Weiteres BMAD-Modul aufnehmen:** Modulcode und Tag an den Install-Befehl
in `targets.json` hängen (`--modules bmm,cis,tea,bmb --pin bmb=v2.2.2`).
Vorher das Roster messen: jede Skill-Beschreibung sitzt in jedem Turn im
Kontext. Das Budget steht in `roster_budget`; der Install warnt, wenn die
installierten Beschreibungen es überschreiten. Achtung: Der Befehl läuft
mit `--action update` und fester Modulliste. Der nächste Lauf
überschreibt die BMAD-Konfiguration; ein Modul, das jemand von Hand dazu
installiert hat, fehlt danach im BMAD-Manifest. Geprüft am
2026-09-04 mit bmb, bmad-loop und gds. Wer mehr Module will, ruft den
BMAD-Installer selbst mit der vollen Liste auf. Den Bootstrap startet er
dann mit `--skip-tools`.

**Version veröffentlichen:** `version` in `pyproject.toml` erhöhen, den
Pin in `tests/test_scaffold.py` nachziehen, Release-Record unter
`docs/releases/` anlegen. Der Deploy legt `versions/<v>/` an.

## Störungen

**Ein Install meldet "another bootstrap run appears to be active":**
Ein Lock ohne lebenden Prozess wird seit 1.3.0 selbst zurückgeholt. Bleibt
die Meldung, `rm -rf .bootstrap.lock` im Projekt ausführen.

**Ein Install endet mit Exit-Code 2:** Die Base-URL ist der Platzhalter.
`--base-url https://deltatree.github.io/BestAiConfig` mitgeben.

**Ein Install meldet 404 auf ein Artefakt:** Prüfen, ob der Pfad ein
`.github`-Segment trägt. GitHub Pages liefert solche Pfade nicht aus; das
Feld `publish_rewrites` in `targets.json` muss das Segment umbenennen.

**Der Deploy ist rot:** `gh run view <id> --log-failed`. Das Test-Gate
nennt die Datei. Pages behält den letzten grünen Stand.

**Rollback der Registry:** Rezept im jeweiligen Release-Record unter
`docs/releases/`. Kurzform: Branch anlegen, alten Baum mit
`git diff --binary main <alter-commit> | git apply` wiederherstellen,
committen, Pull Request, mergen. Der Deploy folgt von selbst.

**Rollback in einem Projekt:** `bootstrap.sh --version <v>` installiert
eine archivierte Version. `--uninstall` entfernt alles, was die Registry
installiert hat; Seeds bleiben.

## Messen

`sh .claude/skills/skill-router/measure-discipline.sh` zählt Router-
Aufrufe in den Claude-Code-Transkripten. `--otel <datei>` liest einen
OpenTelemetry-Export. Beides sind untere Schranken; keines misst
Gehorsam.

## Kontakt

Sicherheitsmeldungen: privates Security Advisory, siehe
[SECURITY.md](../SECURITY.md). Alles andere: GitHub Issues.
