# Release-Record 1.11.0 — Installation per Webdienst

Datum: 2026-09-28. Version `1.11.0` in `pyproject.toml`. Commit-Hash:
siehe Merge-Commit des Pull Requests. Ausgeliefert nach dem Merge durch
`deploy.yml` (GitHub Pages) und `service.yml` (Image in GHCR, Stack auf
dtadmin).

## Was sich ändert

Die Spec steht unter
`_bmad-output/specs/spec-webdienst-installation/SPEC.md`.

| Bereich | Änderung | Wirkung für Nutzer |
|---|---|---|
| Installer | Holt alles als ein Paket `bundle.tar.gz` vom Webdienst. Rückfall: Datei für Datei von GitHub Pages | 7 statt 25 bis 46 Sekunden (Messung 2026-09-28) |
| Installer | Ruft nie einen Paketmanager auf. BMAD kommt fertig aus dem Paket. `uv` und `rtk` nennt er nur als Hinweis | Kein Node.js, kein npm, kein Homebrew nötig |
| Installer | Prüft das Paket vor dem Entpacken: nur Dateien und Ordner unter `registry/` und `tools/`, keine Links, kein `..`, kein `.git` | Ein manipuliertes Paket schreibt nichts |
| Installer | `_bmad/custom/` schreibt er nur, wenn es fehlt | Eigene BMAD-Anpassungen überleben jedes Update |
| Registry | `targets.json`: `bundle_url`, `payload`, `payload_keep`. Manifest: `install.bundle`, `install.tool_payloads`, `install.tool_payload_keep` | Alles bleibt Daten; der Installer kennt kein Tool beim Namen |
| Dienst neu | `service/Dockerfile`: BMAD läuft beim Image-Bau, nginx liefert statisch aus (ohne Root, Port 8080, `/healthz`) | Ein Dienst ohne eigenen Servercode |
| Workflow neu | `service.yml`: nach grünem CI auf `main` Image nach `ghcr.io/deltatree/bestaiconfig`, dann Webhook an dtadmin. Im Pull Request nur Probebau | Das Image ist immer auf dem Stand von `main` |
| BMAD | `--user-name Developer`; Projektname `project` | Kein `Root` mehr als Anrede. Eigener Name in `_bmad/custom/config.user.toml` |
| Doku | README, `docs/technik.md`, `docs/operations.md`, `SECURITY.md`, `docs/registry-schema.md`, `docs/erweiterungen.md` | Der neue Weg in einfachen Worten |

## Entscheidungen

- **Statisches nginx statt eigenem Servercode.** Das Paket entsteht beim
  Image-Bau. Weniger Teile, nichts zu patchen.
- **Ein Paket für alle.** 4 MB gepackt. Eine Auswahl pro Anfrage spart
  wenig und braucht Code auf dem Server.
- **Kein BMAD per Docker beim Nutzer.** Der Dienst ersetzt das.
- **Rückfall ohne BMAD.** Ist der Dienst weg, läuft die Installation
  trotzdem. Nur BMAD fehlt bis zum nächsten Lauf. Kein lokales npm als
  Ersatz, auf Wunsch des Owners.

## Nachweise

- Lokal: `docker build -f service/Dockerfile .` grün; Container liefert
  `/healthz` 200 und ein Paket mit 3,8 MB.
- Lokal: Installation gegen den Container in 7,4 s, ohne `npm` und
  `brew` im `PATH`. Die Skills sind byte-gleich zur npm-Installation.
- Lokal: eigene Datei in `_bmad/custom/` überlebt eine zweite Installation.
- Suite: siehe Pull Request.

## Abhängigkeiten (gepinnt)

`bmad-method@6.12.0`, `cis=v0.3.2`, `tea=v1.24.0` (unverändert).
Neu im Image: `node:22-bookworm-slim`, `python:3.12-slim`,
`nginxinc/nginx-unprivileged:1.29-alpine`. Neue Actions per Commit-SHA:
`docker/setup-buildx-action` v4.4.1, `docker/login-action` v4.6.0,
`docker/build-push-action` v7.4.0.

## Offen beim Owner

1. Stack auf dtadmin einmal anlegen: `dtcli deploy -f service/dtcloud.yaml`.
2. Das GHCR-Paket `bestaiconfig` öffentlich stellen oder dtadmin
   Lesezugriff geben. Aus einem privaten Repo ist es zuerst privat.
3. Prüfen: `curl -fsS https://bestaiconfig.apps.dtcloud.de/healthz`.

Bis dahin meldet der Installer `bundle unavailable` und installiert ohne
BMAD.

## Rollback

Schneller Weg für einen Nutzer: `RULES_BUNDLE_URL=off`. Das holt die
Dateien einzeln; BMAD fehlt dann.

Voller Rollback, Dauer etwa 20 Minuten (davon 15 Minuten CI und Deploy):

1. Branch anlegen und den Stand 1.10.0 anwenden:
   ```sh
   git checkout -b rollback-1.11.0 main
   git diff --binary main c082ff5 | git apply
   git add -A && git commit -m "rollback: Stand c082ff5 (v1.10.0)"
   git push -u origin rollback-1.11.0
   ```
   Erwartete Ausgabe: `git diff --stat c082ff5 HEAD` ist leer.
2. Pull Request öffnen und mergen. Erwartete Ausgabe: das CI-Gate ist grün.
3. Der Deploy startet nach dem Merge von selbst. Den Stack auf dtadmin
   anhalten, wenn der Dienst nicht mehr gebraucht wird.
