From 5e2c11b49fb18bbbaf2d31f041f9f1a7c6be7790 Mon Sep 17 00:00:00 2001 From: cschlaefke Date: Tue, 3 Nov 2026 20:45:30 +0100 Subject: [PATCH] docs: Review-Korrekturen an Release-Checkliste Refs #2 Refs #46 Co-Authored-By: Claude Sonnet 5.5 --- .claude/commands/release.md | 2 +- docs/katalog-pflege.md | 2 +- docs/release-checkliste.md | 51 ++++++++++++++++++++----------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/.claude/commands/release.md b/.claude/commands/release.md index ddf2a19..91dbd29 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -4,7 +4,7 @@ argument-hint: --- Bereite Release $ARGUMENTS vor: -0. Gehe `docs/release-checkliste.md` durch (Katalog/`checks.sql`, Zugang, Auth/SMTP, Runner) und melde offene Punkte an Chris. +0. `docs/release-checkliste.md` nur lesen und den Status erheben (was ist erledigt, was offen). Keine Prüfbefehle gegen Staging/Prod ohne Freigabe von Chris. Offene Release-Blocker (Abschnitte 2 bis 5) halten Schritt 1 nicht auf (Version und Changelog dürfen vorbereitet werden), verhindern aber den Tag-Vorschlag in Schritt 4; Chris entscheidet. 1. `devops`: prüft, dass `main` grün ist, setzt `version:` in `app/pubspec.yaml` (Build-Nummer +1) auf einem Branch `release/$ARGUMENTS` und erstellt einen PR. 2. `docs-writer`: ergänzt `CHANGELOG.md` aus den gemergten PRs seit dem letzten Tag und diff --git a/docs/katalog-pflege.md b/docs/katalog-pflege.md index aeb8cd1..48046fe 100644 --- a/docs/katalog-pflege.md +++ b/docs/katalog-pflege.md @@ -113,7 +113,7 @@ Je Regel eine Zeile (Soll, Ist, Status `ok`/`Verstoß`/`Information`). **Abnahme | Pfad ohne Treffer in `sql_paths` | Nur die Warnung `no files matched pattern: …`, **kein Fehler**, Exit-Code 0. Ein Tippfehler im Pfad überspringt die Datei also still; nach dem Reset `checks.sql` bzw. die Zeilenzahlen ansehen. | | Datei, die nur Kommentare enthält | läuft ohne Fehler | | psql-Metabefehle (`\i` …) in Seed-Dateien | nicht nutzbar (die Datei wird als SQL-Batch gesendet) | -| `supabase start` lädt Seeds nur beim ersten Start einer leeren Datenbank | **nicht geprüft** (hätte Chris' laufenden lokalen Stack stoppen müssen). Nicht darauf verlassen: nach Änderungen an Migrationen oder Seeds immer `supabase db reset`. Auf Staging/Prod nicht für Seeds nutzen, sondern per `psql` einspielen (2.5, [Release-Checkliste](release-checkliste.md) Abschnitt 2). | +| `supabase start` lädt Seeds nur beim ersten Start einer leeren Datenbank | **nicht geprüft** (hätte Chris' laufenden lokalen Stack stoppen müssen). Nicht darauf verlassen: nach Änderungen an Migrationen oder Seeds immer `supabase db reset`. Nur lokal relevant. `supabase db reset` niemals gegen Staging/Prod (löscht alle Daten); Seeds dort ausschließlich per `psql` (2.5, [Release-Checkliste](release-checkliste.md) Abschnitt 2). | ## 3. Spiel anlegen und bearbeiten diff --git a/docs/release-checkliste.md b/docs/release-checkliste.md index c68c389..f42f9bf 100644 --- a/docs/release-checkliste.md +++ b/docs/release-checkliste.md @@ -7,7 +7,7 @@ | Quellen | `docs/specs/2-katalog-daten.md` (§ 4.2, § 8.1 Aufgabe D1), `docs/auth-konfiguration.md` (§ 3, § 5), `docs/katalog-pflege.md` (§ 1, § 2), ADR-0002, ADR-0003, Issue #46 | | Bezug | Refs #2 (Katalog), Refs #1 (Auth), Refs #46 (SMTP-Timeouts), Refs #43 (CI-Runner) | -Diese Datei ist die zentrale Stelle. Die ausführliche Auth-Liste bleibt in `docs/auth-konfiguration.md` § 5; die Release-Blocker daraus stehen hier, damit nichts übersehen wird. +Diese Datei ist die zentrale Stelle. Die ausführliche Auth-Liste bleibt in `docs/auth-konfiguration.md` § 5; die Release-Blocker daraus stehen hier, damit nichts übersehen wird. **Auth § 5 und Abschnitt 3 dieser Datei beide pflegen.** **Grundregeln (CLAUDE.md, Rolle devops):** Kein Tag, kein Deployment, kein Store-Upload ohne ausdrückliche Freigabe von Chris. Infrastruktur (Server, DNS, Reverse Proxy, Firewall) richtet Chris ein bzw. gibt sie frei; devops liefert Anleitung und Prüfschritte. Secrets nie in Logs, Tickets oder dieser Datei. In den Prüfbefehlen stehen Platzhalter in `<…>`; echte Werte stehen nicht im Repo. @@ -22,22 +22,22 @@ Ergebnis je Punkt mit Datum und Umgebung (Staging/Prod) im Release-PR oder als K | ☐ | `main` ist grün (Format, Analyse, Tests, Web-Build, pgTAP, `e2e`, Deno-Schritte) | devops | Forgejo Actions, letzter Lauf auf `main` | | ☐ | Version in `app/pubspec.yaml` gesetzt (`x.y.z+build`), Changelog und Release Notes erstellt | devops, docs-writer | `.claude/commands/release.md` | | ☐ | Migrationen auf Staging eingespielt und geprüft; Produktion erst nach Freigabe | Chris | Verfahren **offen**, siehe 8 | -| ☐ | Backups laufen und Restore ist getestet (ADR-0002, Pflichtbaustein) | Chris | Nachweis des letzten Restore-Tests, **offen**, siehe 8 | +| ☐ | **ADR-0002-Pflichtbausteine vor dem ersten echten Nutzer (Go-live):** automatisierte Backups (DB + Storage) an getrenntem Ort, **getesteter** Restore, TLS und Reverse Proxy, Firewall (nur nötige Ports), Update-Routine, Monitoring und Alarm, Secrets nicht im Repo | Chris | je Baustein Nachweis (z. B. Restore-Test mit Datum); Umsetzung und Verfahren **offen**, siehe 8 | ## 2. Katalog und Startbestand (Spec #2, KAT-05) -Reihenfolge immer: Migrationen, `vocabulary.sql`, `startbestand.sql` (Runbook `docs/katalog-pflege.md` § 2.5). +Reihenfolge: Migrationen, `vocabulary.sql`, `startbestand.sql` (Runbook `docs/katalog-pflege.md` § 2.5). **`startbestand.sql` wird nur bis einschließlich Go-live eingespielt**; danach ist es eingefroren, weil es Korrekturen aus dem Studio überschreiben würde (Spec § 4.3, Spec-F6). Danach bei Bedarf nur noch `vocabulary.sql` (idempotent). | ☐ | Punkt | Wer | Prüfung | |---|---|---|---| -| ☐ | **C0:** Vokabular (`supabase/catalog/vocabulary.csv`, Genres und Mechaniken) von Chris freigegeben oder korrigiert; `vocabulary.sql` ist aus der freigegebenen CSV erzeugt | Chris | Freigabe als Kommentar in #2 oder im PR; CI-Schritt „erzeugte Dateien aktuell“ grün | +| ☐ | **C0:** Vokabular (`supabase/catalog/vocabulary.csv`, Genres und Mechaniken) von Chris freigegeben oder korrigiert; `vocabulary.sql` ist aus der freigegebenen CSV erzeugt | Chris | Freigabe als Kommentar in #2 oder im PR; CI-Schritt „Erzeugte Katalogdateien aktuell?“ grün | | ☐ | Startbestand in `startbestand.csv` gepflegt (mindestens 180, Ziel ca. 200), `startbestand.sql` und `startbestand-keys.csv` erzeugt und committet (C1) | Chris | Ablauf Runbook § 2.4; CI grün | | ☐ | Herkunft der Fakten (SB3) und der Kurztexte (SB4) bestätigt; **rechtliche Prüfung** vor dem Release | Chris | schriftliche Bestätigung in #2 | -| ☐ | Vokabular und Startbestand auf der Zielumgebung eingespielt (nur per Tunnel/VPN, siehe 4) | Chris | `psql "$DB_URL" -v ON_ERROR_STOP=1 --single-transaction -f supabase/catalog/vocabulary.sql -f supabase/catalog/startbestand.sql` | -| ☐ | **Seed-Verhalten:** Auf Staging/Prod nicht auf `supabase start`/`supabase db reset` für Seeds verlassen. Runbook § 2.7: Das Verhalten von `supabase start` (Seeds nur beim ersten Start einer leeren DB) ist **nicht geprüft**. Seeds ausdrücklich per `psql` (Zeile oben) einspielen und mit `checks.sql` bestätigen | Chris, devops | Zeile oben plus nächster Punkt | -| ☐ | **`checks.sql` (SB1):** mindestens 180 sichtbare Startbestandsspiele; SB2, SB4 und SB6 melden 0 Verstöße | Chris (Abnahme C1) | `psql "$DB_URL" -f supabase/catalog/checks.sql` oder Inhalt im Studio-SQL-Editor. Erwartung: Status `ok` bei SB1/SB2/SB4/SB6, SB1-Istwert >= 180. Lokal/CI ist SB1 nur Information; auf Produktion zählt der Wert | +| ☐ | Vokabular und Startbestand auf der Zielumgebung eingespielt (nur per Tunnel/VPN, siehe 4; `startbestand.sql` nur bis Go-live) | Chris | `psql "$DB_URL" -v ON_ERROR_STOP=1 --single-transaction -f supabase/catalog/vocabulary.sql -f supabase/catalog/startbestand.sql` | +| ☐ | **Seeds nur per `psql`:** `supabase db reset` niemals gegen Staging/Prod (löscht alle Daten); Seeds dort ausschließlich per `psql` (Runbook § 2.5). Das Verhalten von `supabase start` mit Seeds (nur beim ersten Start einer leeren DB) ist **nicht geprüft** (Runbook § 2.7) und nur lokal relevant | Chris, devops | Zeile oben plus nächster Punkt | +| ☐ | **`checks.sql` (SB1, Go-live-Kriterium):** mindestens 180 sichtbare Startbestandsspiele; SB2, SB4 und SB6 melden 0 Verstöße. `checks.sql` muss aus **demselben Commit** stammen wie das eingespielte `startbestand.sql` (die committete Fassung ohne Startbestand enthält eine leere ID-Liste `'[]'`, dann sind SB2/SB4/SB6 aussagelos). Zusätzlich SB0 (Istwert = Soll „alle N“) und die Informationszeile zu abweichenden Vokabular-IDs ansehen | Chris (Abnahme C1) | `psql "$DB_URL" -v ON_ERROR_STOP=1 -f supabase/catalog/checks.sql` oder Inhalt im Studio-SQL-Editor. Erwartung: Status `ok` bei SB0/SB1/SB2/SB4/SB6, SB1-Istwert >= 180. Bei < 180 zeigt `checks.sql` „Verstoß“; nur der CI-Schritt wertet SB1 lokal als Information | | ☐ | Das lokale Beispielspiel aus `seed.sql` ist auf Produktion nicht vorhanden (reiner Sicherheitsnetz-Check; `checks.sql` zählt es nicht mit) | devops | `select count(*) from public.games where title = 'Beispielspiel';` erwartet 0 | -| ☐ | **Go-live:** danach ist `startbestand.sql` eingefroren und wird nicht mehr eingespielt (Korrekturen nur im Studio, Spec-F6) | Chris | Hinweis im Release-PR | +| ☐ | **Go-live:** `startbestand.sql` ist ab jetzt eingefroren und wird nicht mehr eingespielt (Korrekturen nur im Studio, Spec-F6); dieser Schritt kommt **nach** dem Einspielen und der `checks.sql`-Abnahme | Chris | Hinweis im Release-PR | Issue #2 wird erst nach der Abnahme von `checks.sql` auf Produktion (C1) und nach Fertigstellung von #4 (KAT-02) geschlossen, und nur von Chris. @@ -48,28 +48,30 @@ Vollständige Liste mit AUTH-CFG-Verweisen: `docs/auth-konfiguration.md` § 5; G | ☐ | Punkt | Wer | Prüfung | |---|---|---|---| | ☐ | GoTrue-Image gepinnt auf `supabase/gotrue:v2.197.0` (oder bewusst aktualisiert, dann Spike-Punkte wiederholen); Env-Block aus Auth § 2 vollständig; `GOTRUE_PASSWORD_HIBP_ENABLED=false` | Chris, devops | Auth § 5, erste Punkte; Env-Werte prüfen, ohne Secrets zu posten | -| ☐ | `GOTRUE_SMS_AUTOCONFIRM=false` (die Self-Hosting-Vorlage setzt `true`): Enumerationsschutz | devops | Signup mit bereits bestätigter Adresse liefert 200 mit leeren `identities`, nicht 422 `user_already_exists` (AUTH-CFG-24) | -| ☐ | **Proxy vor GoTrue mit `GOTRUE_RATE_LIMIT_HEADER=X-Forwarded-For`** (AUTH-CFG-13): Proxy **überschreibt** den Header, GoTrue ist von außen nicht direkt erreichbar | Chris (Einrichtung), devops (Test) | 31 Fehllogins derselben IP gegen `https:///auth/v1/token?grant_type=password` mit einem Testkonto: Nr. 31 liefert 429 `over_request_rate_limit`. Zweiter Test mit gefälschtem Header `X-Forwarded-For: 203.0.113.7`: darf die Drosselung nicht umgehen. Direktzugriff auf den GoTrue-Port von außen muss scheitern | -| ☐ | **Gateway sperrt `POST /auth/v1/otp` und `POST /auth/v1/magiclink`** (AUTH-CFG-20; `/otp` legt sonst Konten an) | Chris (Einrichtung), devops (Test) | `curl -s -o /dev/null -w '%{http_code}\n' -X POST https:///auth/v1/otp -H 'Content-Type: application/json' -d '{}'`, ebenso für `/auth/v1/magiclink`: erwartet Ablehnung durch das Gateway (z. B. 403/404), keine GoTrue-Antwort | +| ☐ | `GOTRUE_SMS_AUTOCONFIRM=false` bzw. `ENABLE_PHONE_AUTOCONFIRM=false` (die Self-Hosting-Vorlage setzt `true`): Enumerationsschutz | devops | Signup mit bereits bestätigter Adresse liefert 200 mit leeren `identities`, nicht 422 `user_already_exists` (AUTH-CFG-24) | +| ☐ | **Proxy vor GoTrue mit `GOTRUE_RATE_LIMIT_HEADER=X-Forwarded-For`** (AUTH-CFG-13): Proxy **überschreibt** den Header, GoTrue ist von außen nicht direkt erreichbar | Chris (Einrichtung), devops (Test) | **Nur auf Staging testen** (der Test sperrt die eigene IP für ca. 5 Minuten). 31 Fehllogins derselben IP gegen `https:///auth/v1/token?grant_type=password` mit Header `-H "apikey: "` (Platzhalter; ohne Key antwortet das Gateway mit 401 und der Test sagt nichts) und einem Testkonto: Nr. 31 liefert 429 `over_request_rate_limit`. Zweiter Test mit gefälschtem Header `X-Forwarded-For: 203.0.113.7`: darf die Drosselung nicht umgehen. Direktzugriff auf den GoTrue-Port von außen muss scheitern | +| ☐ | **Gateway sperrt `POST /auth/v1/otp` und `POST /auth/v1/magiclink`** (AUTH-CFG-20; `/otp` legt sonst Konten an) | Chris (Einrichtung), devops (Test) | `curl -s -i -X POST https:///auth/v1/otp -H "apikey: " -H 'Content-Type: application/json' -d '{}'`, ebenso für `/auth/v1/magiclink` (der `apikey`-Header ist nötig, sonst kommt 401 und der Test ist wertlos). Erwartet: Ablehnung durch das Gateway (z. B. 403/404) **ohne** GoTrue-JSON (kein `code`/`error_code`/`msg` im Body); ein 400/422 mit GoTrue-Fehlerbody heißt: nicht gesperrt | | ☐ | **SPA-Rewrite:** `/auth/confirm` wird von der Web-App ausgeliefert (alle Pfade auf `index.html`) | Chris (Einrichtung), devops (Test) | `curl -s -o /dev/null -w '%{http_code}\n' 'https:///auth/confirm?token_hash=x&type=email'` erwartet 200 und HTML der App | -| ☐ | **Mailvorlagen-URL** erreichbar (GoTrue lädt Vorlagen per URL und fällt bei Fehlern **still** auf Englisch zurück, Risiko R5); URL im Health-Check | Chris, devops | URL aus dem Env-Block per `curl -I` vom Server aus. **Testmail de und en** (Bestätigung und Reset) auf Staging: Betreff und Text in der richtigen Sprache, Link `/auth/confirm?token_hash=…` | +| ☐ | **Mailvorlagen-URL** erreichbar (GoTrue lädt Vorlagen per URL und fällt bei Fehlern **still** auf Englisch zurück, Spec #1 Risiko R5); URL im Health-Check | Chris, devops | URL aus dem Env-Block per `curl -I` vom Server aus. **Testmail de und en** (Bestätigung und Reset) auf Staging: Betreff und Text in der richtigen Sprache, Link `/auth/confirm?token_hash=…` | | ☐ | SMTP-Anbieter mit AVV und Absender-Domain entschieden und eingerichtet (AUTH-CFG-22, F7, bisher **vertagt**) | Chris | echter Versand auf Staging | | ☐ | **Alarm auf SMTP-Fehler:** GoTrue-Logs mit `unexpected_failure`/HTTP 500 bei `/recover`, `/resend`, `/signup` lösen einen Alarm aus (die App zeigt bei SMTP-Ausfall bewusst die neutrale „Prüfe dein Postfach“-Seite, Nutzer merken nichts) | Chris (Einrichtung), devops (Test) | Alarm einmal auslösen (z. B. SMTP-Host auf Staging kurz falsch setzen) und Eingang bestätigen | -| ☐ | **#46 Timeouts und Monitoring:** Gateway-/Proxy-Timeout und GoTrue-SMTP-Timeout so gesetzt, dass bei hängendem SMTP ein 504 **mit Status** vor dem Client-Timeout kommt (Werte noch nicht festgelegt, Spike aus #46 offen); Monitoring umfasst zusätzlich **Gateway-5xx/504** für `/recover`, `/resend`, `/signup`, nicht nur `unexpected_failure`/500 | Chris, devops | Spike aus #46 auf Staging (`GOTRUE_SMTP_HOST=10.255.255.1`, nicht routbar): Status und Dauer für bekannte und unbekannte Adresse; Ergebnis in `docs/auth-konfiguration.md` eintragen. **Solange #46 offen ist, nicht abhakbar** | +| ☐ | **#46 Timeouts und Monitoring:** Gateway-/Proxy-Timeout und GoTrue-SMTP-Timeout so gesetzt, dass bei hängendem SMTP ein 504 **mit Status** vor dem Client-Timeout kommt (Werte noch nicht festgelegt, Spike aus #46 offen); Monitoring umfasst zusätzlich **Gateway-5xx/504** für `/recover`, `/resend`, `/signup`, nicht nur `unexpected_failure`/500 | Chris, devops | Spike aus #46 nur auf Staging und **nur mit Freigabe von Chris** (`GOTRUE_SMTP_HOST=10.255.255.1`, nicht routbar): Status und Dauer für bekannte und unbekannte Adresse; Ergebnis in `docs/auth-konfiguration.md` eintragen. **Solange #46 offen ist, nicht abhakbar** | | ☐ | `GOTRUE_RATE_LIMIT_EMAIL_SENT=30` und Monitoring auf 429 `over_email_send_rate_limit`; Mindestabstand 60 s (AUTH-CFG-08); Link-Gültigkeit 1 h (AUTH-CFG-07) | devops | Auth § 5 | | ☐ | Nach Passwortänderung geht keine Benachrichtigungs-Mail aus (AUTH-CFG-19) | devops | Testkonto auf Staging, Postfach prüfen | | ☐ | Rechtstexte-URLs und `TERMS_VERSION` final (R11); Bundle-/Application-ID final (R15) | Chris | vor dem Store-Release | -## 4. Zugang zu Studio, Datenbank, Pooler und `/pg/` (Spec #2 § 4.2, Risiko R1) +## 4. Zugang zu Studio, Datenbank, Pooler und `/pg/` (Spec #2 § 4.2, Spec #2 Risiko R1) + +**Herleitung:** Die Routen und Ports stammen aus der Supabase-Self-Hosting-Vorlage (`kong.yml`, `docker-compose.yml`); diese Dateien liegen nicht im Repo und wurden nicht gelesen. Die Prüfungen unten sind daraus abgeleitet und am echten Setup zu bestätigen. Studio läuft als Rolle `postgres` bzw. `supabase_admin` und **umgeht RLS**; im Self-Hosting gibt es in Studio keine Benutzerverwaltung. Wer Studio, 5432, den Pooler oder `/pg/` erreicht, kann alle Daten lesen und ändern. Gilt für **Staging und Produktion**. | ☐ | Punkt | Wer | Prüfung | |---|---|---|---| -| ☐ | Studio nicht öffentlich erreichbar, nur per SSH-Tunnel oder VPN | Chris (Einrichtung), devops (Prüfung) | Von einem Rechner **außerhalb** von Tunnel/VPN: `curl -s -o /dev/null -m 5 -w '%{http_code}\n' https:///` darf keine Studio-Seite liefern (Timeout, 403/404 oder Verbindungsfehler) | -| ☐ | Postgres-Port 5432 nicht öffentlich | Chris, devops | von außen: `nc -zv -w 5 5432` schlägt fehl | -| ☐ | Pooler (Supavisor, Standard 6543) nicht öffentlich | Chris, devops | von außen: `nc -zv -w 5 6543` schlägt fehl (tatsächlicher Port **offen**, siehe 8) | -| ☐ | Kong-Route `/pg/` (pg-meta) nicht öffentlich | Chris, devops | `curl -s -o /dev/null -w '%{http_code}\n' https:///pg/tables` erwartet 403/404, nicht 200 | +| ☐ | Studio nicht öffentlich erreichbar, nur per SSH-Tunnel oder VPN | Chris (Einrichtung), devops (Prüfung) | Von einem Rechner **außerhalb** von Tunnel/VPN: `curl -s -o /dev/null -m 5 -w '%{http_code}\n' https:///` darf keine Studio-Seite liefern (Timeout, 403/404 oder Verbindungsfehler). Auch **401 (Basic-Auth-Abfrage) von außen gilt als Verstoß**: Studio ist nur über Tunnel/VPN erreichbar, Basic-Auth ist nur die zweite Schicht | +| ☐ | Postgres-Port 5432 nicht öffentlich (IPv4 **und** IPv6) | Chris, devops | von außen: `nc -zv -w 5 5432` und `nc -6zv -w 5 5432` schlagen fehl. Zusätzlich allgemeiner Port-Scan der öffentlichen Adressen (z. B. `nmap -Pn -p- `, nur gegen eigene Server): nur die gewollten Ports (443, ggf. 80) offen | +| ☐ | Pooler (Supavisor, Standard 6543; auch 5432 kann der Pooler belegen) nicht öffentlich (IPv4 und IPv6) | Chris, devops | von außen: `nc -zv -w 5 6543` schlägt fehl; abgedeckt durch den Port-Scan oben (tatsächlicher Port **offen**, siehe 8) | +| ☐ | Kong-Route `/pg/` (pg-meta) von außen gar nicht erreichbar | Chris, devops | `curl -s -i https:///pg/tables -H "apikey: "` von außen: erwartet 403/404 oder Verbindungsfehler. **401 oder 200 gilt als Verstoß** (die Vorlage schützt `/pg/` per Key-Auth und Admin-ACL, das reicht hier nicht). Ohne `apikey` ist ein 401 wertlos | | ☐ | **Basic-Auth** des Gateways gesetzt (`DASHBOARD_USERNAME`/`DASHBOARD_PASSWORD`, starkes Passwort, Standardwerte der Vorlage ersetzt) als zweite Schicht | Chris | Dashboard (per Tunnel) ohne Zugangsdaten liefert 401. Passwort nie ins Repo oder in Logs | | ☐ | **Studio-Rolle bestätigt:** im Studio-SQL-Editor `select current_user;` ausführen; Ergebnis `postgres` oder `supabase_admin` (die Admin-Funktionen akzeptieren genau diese beiden Rollen, Spec § 4.2) | Chris | Ergebnis im Release-PR oder in #2 festhalten; bei anderer Rolle melden und Spec § 4.2 anpassen | | ☐ | Im Studio nie `set …` ohne `local`, immer in einer Transaktion (Runbook § 1) | Chris | Dauerregel, kein Prüfbefehl | @@ -78,13 +80,13 @@ Eingriffe an Firewall, Reverse Proxy und DNS führt Chris aus; devops liefert nu ## 5. CI-Runner (ADR-0003, Issue #43, manuelle Schritte) -ADR-0003 hat den Status „Vorgeschlagen“. Solange die Schritte offen sind, gilt `docker-host` als nicht für externe Beiträge geeignet; **vor dem ersten externen Beitrag, spätestens vor Release**, Schritt B umsetzen oder das Repo privat stellen. Issue #43 erst danach schließen. +ADR-0003 hat den Status „Vorgeschlagen“. Solange die Schritte offen sind, gilt `docker-host` als nicht für externe Beiträge geeignet; **vor dem ersten externen Beitrag, spätestens vor Release**, Schritt B umsetzen oder das Repo privat stellen (dann entfallen die B-Zeilen weitgehend). Issue #43 erst danach schließen. | ☐ | Punkt (ADR-0003, Abschnitt) | Wer | Prüfung | |---|---|---|---| -| ☐ | **A. Verhalten prüfen:** Test-Fork-PR mit manipulierter `ci.yml`: Lauf wartet auf Freigabe; zweiter Push läuft ohne erneute Freigabe; danach Testkonto und Fork löschen | Chris | Ergebnis in #43 notieren; startet der Lauf ohne Freigabe: Repo sofort privat stellen | -| ☐ | **B.1** Erreichbarkeit des dind aus `docker`-Jobs prüfen | Chris | `curl -s -m 3 http://:2375/version` im Job (Gateway wie in `ci.yml`) | -| ☐ | **B.2** Runner in Wegwerf-VM bzw. separaten Host ohne Host-Mounts, ohne LAN-Zugriff, ohne persönliche Daten verlagern | Chris | Beschreibung des Setups in #43 | +| ☐ | **A. Verhalten prüfen:** Test-Fork-PR mit manipulierter `ci.yml`: Lauf wartet auf Freigabe; zweiter Push läuft ohne erneute Freigabe; danach Testkonto und Fork löschen | Chris | Ergebnis in #43 notieren; startet der Lauf ohne Freigabe: Repo sofort privat stellen und Runner pausieren (B.3) | +| ☐ | **B.1** Erreichbarkeit des dind aus `docker`-Jobs prüfen | Chris | `curl -s -m 3 http://:2375/version` im Job (Gateway wie in `ci.yml`). Antwortet der dind, gilt die Warnung für alle Jobs des Runners | +| ☐ | **B.2** Runner in Wegwerf-VM bzw. separaten Host ohne Host-Mounts, ohne LAN-Zugriff, ohne Zugangsdaten und ohne persönliche Daten verlagern | Chris | Beschreibung des Setups in #43 | | ☐ | **B.3** Notbremse (Runner stoppen) bekannt und einmal geprobt | Chris | Weg laut ADR **unverifiziert** | | ☐ | **B.4 / C.1** Runner nur für dieses Repo registriert; Fork-PR-Läufe werden nicht freigegeben, solange nicht isoliert | Chris | Forgejo: Einstellungen, Actions, Runner | | ☐ | **C.5** Runner-Token rotiert (Vorschlag: alle 3 Monate, sofort bei Verdacht) | Chris | Datum der letzten Rotation notieren | @@ -98,7 +100,7 @@ Android-AAB und iOS-Build: Upload nur nach ausdrücklicher Freigabe von Chris. i | ☐ | Punkt | Wer | Prüfung | |---|---|---|---| | ☐ | Smoke-Test Web: Start, Registrierung, Bestätigungs-Link, Anmeldung, Katalog zeigt Spiele | Chris | manuell auf der Zielumgebung | -| ☐ | Tag `v` erst nach Freigabe; der Release-Workflow übernimmt | Chris | `.claude/commands/release.md`, Schritt 4 | +| ☐ | Tag `v` erst nach Freigabe. Ein Release-/Deploy-Workflow existiert noch nicht (`.forgejo/workflows/` enthält nur `ci.yml`), siehe 8 | Chris | `.claude/commands/release.md`, Schritt 4 | ## 8. Offene Punkte für Chris (fehlende Angaben, nichts davon wurde erfunden) @@ -112,7 +114,8 @@ Android-AAB und iOS-Build: Upload nur nach ausdrücklicher Freigabe von Chris. i 8. Ob Staging und Produktion auf demselben Server laufen (ADR-0002: getrennt, sobald echte Nutzer da sind). 9. Wie `DB_URL` für `psql` gebildet wird (Tunnel, Rolle); nicht ins Repo. 10. Entscheidung über ADR-0003 (Status „Vorgeschlagen“, Maßnahmen A/B/C). -11. Store-Release: Signierung, Bundle-/Application-ID (R15), Rechtstexte (R11). +11. Release-/Deploy-Workflow (Web-Deployment, Tag `v*`) existiert noch nicht; Ziel, Verfahren und Freigabe-Schritt sind festzulegen. +12. Store-Release: Signierung, Bundle-/Application-ID (R15), Rechtstexte (R11). ## 9. Nicht geprüft (Stand dieser Datei)