devAlice
← Alice Way

11. Release gates — die Linie, an der Fertigsein zur Tatsache wird

Was ein Release gate ist, warum Fertigsein ohne eines verrottet, die Auto/Manual-Gate-Aufteilung, das kumulative Gate-Muster und der Tag, an dem ein Track alle Checks bestand, aber 42 Lieferpunkte fehlten.

Teil 10 — PRD endete auf einer einzigen Zeile. Eine PRD beschreibt das Ziel.

Dieser Beitrag handelt davon, wie der Betreiber weiß, dass er angekommen ist.

Release gates. Die konkreten, atomaren, maschinenprüfbaren Bedingungen, die „fertig" von einem Gefühl in eine Tatsache verwandeln. Ohne sie ist die PRD ein Wunsch. Mit ihnen ist sie eine Straße mit Meilenmarkern, jeder davon durch etwas anderes als das Vertrauen des Betreibers verifizierbar.

0. Die Prämisse — „fertig" ist das teuerste Wort

Teil 7 — Verifikationsschleifen machte den Fall auf Code-Ebene. In dem Moment, in dem der Betreiber fühlt „das ist fertig", feuern Lint und Build und Tests automatisch, bevor der Bericht landen kann. Dieser Schritt verschiebt ein fragiles Wort — „fertig" — vom Gedächtnis des Betreibers zur System-Durchsetzung.

Ein Release gate ist derselbe Schritt, eine Ebene höher.

Auf Code-Ebene heißt „fertig" dieser Slice kompiliert und seine Tests bestehen. Auf Release-Ebene heißt „fertig" das System darf live sein. Die beiden sind nicht dasselbe Wort und können nicht durch denselben Mechanismus durchgesetzt werden.

Ein bestandener Test sagt einem nicht, dass die Privacy Policy existiert. Ein bestandener Build sagt einem nicht, dass die OAuth-Redirect-URIs auf der allow-list stehen. Ein sauberer Lint sagt einem nicht, dass der Klarname des Betreibers aus jeder Metadaten-Schicht entfernt wurde. Diese Fragen gehören zu einem anderen Gate.

1. Was ein Release gate tatsächlich ist

Ein Release gate ist eine Tabelle.

Jede Zeile der Tabelle ist eine atomare, extern verifizierbare Bedingung. Jede Zeile hat einen Status:

  • ✅ pass — verifiziert, diese Zeile hält derzeit
  • ⏳ in progress — wird bearbeitet, noch nicht haltend
  • 🔒 waiting on operator — blockiert durch einen rein menschlichen Schritt (ein Dashboard-Klick, eine Konto-Anmeldung, eine DNS-Änderung)
  • ❌ not started — bekannte Anforderung, keine Bewegung
  • nicht zutreffend — die Zeile wurde spekulativ hinzugefügt, und die Situation machte sie irrelevant

Die Tabelle ist Teil der PRD. Sie lebt nicht in einem separaten Dokument. Der Grund ist derselbe wie in Teil 10 §4 — die Form des Weges ist in das Ziel-Dokument eingebaut. Niemand muss fragen „was zählt als fertig?", weil das Dokument antwortet.

Die Gates sind kumulativ. Gate 1 setzt voraus, dass Gate 0 bestanden ist. Gate 9 setzt 0 bis 8 voraus. Die Reihenfolge ist keine Präferenz, sie ist Abhängigkeit — man kann Gate 2 (Infrastruktur) nicht vor Gate 1 (Compliance) bestehen, genauso wenig wie man einen Dienst starten kann, bevor man eine Domain hat.

Ein Release gate ist keine Checkliste. Es ist der Vertrag zwischen Absicht und Realität.

2. Auto-Gate vs. Manual-Gate

Nicht alle Gate-Zeilen sind die gleiche Art von Sache. Zwei Arten, und der Unterschied zählt.

Auto-Gate-Zeilen sind Bedingungen, die eine Maschine verifizieren kann. Beispiele:

  • pnpm build beendet mit 0
  • pnpm lint beendet mit 0
  • pnpm test beendet mit 0
  • grep -r "operator-real-name" . gibt nichts zurück
  • curl -I https://devalice.jaceclub.com gibt 200 zurück
  • verify:assets-Skript meldet 15/15 SHA-256-Treffer

Wenn die Zeile als Shell-Befehl ausgedrückt werden kann, der mit 0 oder ungleich Null beendet, gehört sie in die Auto-Gate-Menge. Das System kann sie bei jedem Commit, jedem Push, jedem nächtlichen Cron feuern — ohne dass der Betreiber wach ist.

Manual-Gate-Zeilen sind Bedingungen, die nur ein Mensch entscheiden kann. Beispiele:

  • „Die Privacy Policy liest sich in beiden Sprachen korrekt"
  • „Lead genehmigt die M2-Meilenstein-Definition"
  • „Das Seed-Content-Set deckt fünf unterschiedliche Nutzerschmerzen ab"
  • „OAuth-Scopes wirken für die Vertrauensstufe angemessen"
  • „Lighthouse-‚Best Practices'-Befunde sind akzeptable Trade-offs"

Diese Zeilen warten auf eine Person. Sie sind der Teil des Gates, der nicht automatisiert werden kann, und das Gegenteil zu tun ist die Quelle der meisten Release-Unfälle.

Die Disziplin ist:

DisziplinGrund
Jede Auto-Gate-Zeile hat ein Skript — und CI führt es ausSonst existiert die Zeile auf Papier, aber nicht in der Praxis
Jede Manual-Gate-Zeile nennt wer genehmigt — nicht nur „genehmigt"Sonst wird sie von niemandem genehmigt und als bestanden gezählt
Auto und Manual sind in der Tabelle visuell unterscheidbarDer Betreiber sollte sich nicht merken müssen, welches welches ist
Manuelle Genehmigungen hinterlassen eine Spur (Commit, Kommentar, PR-Review)Gedächtnis verrottet; Commits nicht

3. Das kumulative Muster in der Praxis

Eine realitätsnahe Gate-Tabelle aus einem echten Projekt — devalice — in abgekürzter Form:

Gate 0: M0 launch (temporary domain)
  - pnpm build passes        [Auto]  ✅
  - Vercel preview deploy    [Auto]  ✅
  - Category routes × 4      [Auto]  ✅
  - Seed guide × 4           [Manual] ✅ (lead reviewed 2026-05-10)
  - ESLint clean             [Auto]  ✅
  - Vercel env vars set      [Manual] 🔒 (operator)

Gate 1: Compliance
  - Privacy Policy (ko + en) [Manual] ✅
  - Content license (CC BY)  [Auto]  ✅ (file exists, header text matches)
  - Code license (MIT)       [Auto]  ✅
  - About page exists        [Auto]  ✅
  - Cookie notice (PIPA)     [Manual] ✅

Gate 2: Infrastructure
  - Custom domain bound      [Manual] 🔒
  - SSL active               [Auto]  — (depends on Gate 2 row 1)
  - Production env split     [Manual] 🔒

Gate 3: Security
  - No hardcoded secrets     [Auto]  ✅ (grep)
  - .env.example complete    [Auto]  ✅
  - RLS enabled              [Manual] 🔒 (waits on DB push)
  - OAuth redirect whitelist [Manual] 🔒
  - Input validation         [Auto]  ✅
  - Asset SHA-256 match      [Auto]  ✅ (verify:assets 15/15)

...

Drei Dinge tut diese Tabelle, die Prosa nicht kann.

Status ist auf einen Blick sichtbar. Spalte überfliegen. Die ✅ gegen die 🔒 zählen. Das Bild ist sofort da. Niemand muss drei Absätze lesen, um zu wissen „wo stehen wir".

Blocker zeigen sich selbst. Eine 🔒-Zeile in Gate 2 ist das Nächste, das passieren muss. Die Tabelle sagt dem Betreiber, dem Lead und der nächsten Sitzung, was zuerst anzuschauen ist.

Gates ordnen sich selbst. „Liefern wir aus?" reduziert sich auf „ist die letzte 🔒 von Gate N geräumt?" Der Streit ums Timing ist vorbei, bevor er beginnt.

4. Der Tag, an dem „fertig" eine Lüge war — die Kosten von Gates, die nicht in Code durchgesetzt sind

Das ist die Geschichte, auf die ich immer wieder zurückkomme, wenn jemand fragt, warum wir uns die Mühe machen.

In einem anderen Projekt — nennen wir es Track D — wurden über mehrere Wochen vier Sub-Phasen nacheinander ausgeliefert. D-0, D-1, D-2, D-3. Jede meldete am Ende „Erfolg". lint bestand. build bestand. cargo test bestand. Der Lighthouse-Score war in Ordnung. Der Team-Lead las die Berichte und ging weiter.

Mehrere Wochen später, bei einem Routine-Audit, fanden wir, dass den tatsächlichen Liefergegenständen über die vier Sub-Phasen hinweg 42 Punkte fehlten. Keine Bugs — fehlende strukturelle Verpflichtungen. Vier UI-Primitive, die laut Spec existieren sollten, waren noch nicht verdrahtet. Acht Queue-Zustände, die laut Spec zerlegt sein sollten, waren es nicht. Sieben Dateien, die laut Spec gelöscht sein sollten, waren noch im Baum. Neun Legacy-Backend-Handler, die laut Spec entfernt sein sollten, wurden noch angesprochen.

Wie ist das passiert? Jeder Bericht war ehrlich. Der Liefergegenstand kompilierte tatsächlich. Tests bestanden tatsächlich. Der Berichterstatter — ein delegierter Agent in diesem Fall — hatte kein Signal, dass irgendetwas nicht stimmte.

Der Grund war einfach. Die Versprechen in der Spec waren Prosa. Sie waren nicht in Code durchgesetzt. Nichts feuerte eine Prüfung, die sagte „die Spec nannte vier UI-Primitive — existieren vier UI-Primitive im Baum?" Nichts feuerte eine Prüfung, die sagte „die Spec sagte, Datei X ist gelöscht — ist Datei X weg?" Die Verifikations-Harness prüfte Kompilation, nicht Verpflichtungen.

Die Behebung war eine Sub-Phase, die niemand machen wollte: D-Catchup. Zurückgehen. Jedes Versprechen gegen den Baum verifizieren. Verdrahten, was fehlte. Löschen, was weg sein sollte. Dann — und das ist die dauerhafte Änderung — bei jeder zukünftigen Delegation ein verify:d-N-Skript hinzufügen und es auf das Merge-Gate setzen, damit die nächsten vier Sub-Phasen uns nicht belügen könnten, selbst wenn sie wollten.

Das ist die Lektion:

„Ein Versprechen ist kein Release gate. Ein in Code durchgesetztes Versprechen schon."

Nach D-Catchup bekommt jede Delegation in diesem Projekt drei Dinge im selben PR:

  1. Den Delegations-Brief — was, warum, wie
  2. Ein verify:phase-N.mjs-Skript, das jedes Versprechen durchgeht und bei einem Treffer ungleich Null beendet
  3. Eine CI-Regel, die den Merge blockiert, wenn nicht pnpm run verify:phase-N mit 0 beendet

Das ist ein Release gate auf Delegations-Skala. Dieselbe Form wie die M0–M10 Gates in der PRD, nur auf eine kleinere Einheit angewandt.

5. Die Form eines verify-Skripts

Ein verify-Skript ist absichtlich klein und dumm. Es ist kein Test-Framework. Es ist ein wörtlicher Begeher.

Für jede Zeile der Spec, ein Block:

// Row D-1.3 — Queue must be decomposed into 8 states
const queueStates = readQueueStates();
if (queueStates.length !== 8) {
  fail("Queue has " + queueStates.length + " states, expected 8");
}

Drei Eigenschaften zählen.

1:1 mit der Spec. Zeile 3 der Spec bekommt Prüfung 3 des Skripts. Wenn eine Zeile zur Spec hinzukommt, besteht das Skript nicht, bis eine Prüfung hinzugefügt wird. Die beiden Dokumente bewegen sich im Gleichschritt.

Output ist die Quittung. Der Berichterstatter sagt nicht „verifiziert". Er fügt den rohen stdout ein. verify:d-1 passed 18 / 18. Wenn die Zeile nicht im Bericht ist, wird der Bericht nicht akzeptiert.

Fehler sind laut und spezifisch. „Queue has 5 states, expected 8" schlägt „verify failed". Der Betreiber sollte wissen, was fehlt, ohne das Skript zu öffnen.

Das Skript ist handgeschrieben. Nicht generiert. Nicht Framework-getrieben. Es ist das Lesen der Spec durch den Betreiber, in Code ausgedrückt, auf dem Merge-Gate sitzend.

6. Manual-Gate-Zeilen — wie sie ehrlich gehalten werden

Auto-Gate-Zeilen sind leicht ehrlich zu halten. CI führt die Prüfung aus und besteht oder fällt durch. Manual-Gate-Zeilen sind, wo sich die Disziplin zeigt.

Die Muster, die ich verwende:

Jede manuelle Zeile nennt den Genehmiger. Nicht „vom Team genehmigt" — Rolle und Datum nennen. Manual ✅ lead, 2026-05-10. Wenn der Genehmiger wechselt, geht die Zeile zurück auf ⏳, bis der neue Genehmiger neu genehmigt.

Manuelle Zeilen hinterlassen eine Commit-Spur. Der Commit, der eine Zeile von ⏳ auf ✅ umlegt, enthält den Namen des Genehmigers in der Nachricht und eine einzeilige Notiz, was geprüft wurde. [devAlice] chore(gate-1): privacy policy ko/en — lead approved. Sechs Monate später, wenn jemand fragt „Moment, wer hat entschieden, dass das in Ordnung ist?", antwortet das git log.

Manuelle Zeilen haben einen expliziten Re-Review-Rhythmus. Eine in M0 genehmigte Privacy Policy ist nicht für immer genehmigt. Die PRD nennt einen Re-Review-Trigger — re-review on M2 launch oder re-review every two quarters. Wenn der Trigger feuert, geht die Zeile zurück auf ⏳ bis zur erneuten Bestätigung.

Keine manuelle Zeile verwendet „komme ich noch dazu" als Status. Entweder gibt es einen Eigentümer und eine Frist, oder es ist ❌.

7. Die Fallen

Release gates scheitern auf vorhersagbare Weise.

7.1 Gates, die wachsen, aber nie schließen

Eine Gate-3-Tabelle sammelt zwei Quartale lang Zeilen an und hat nie einen Moment, in dem jede Zeile ✅ ist. Das ist kein Gate, das ist eine Wunschliste. Aufteilen. Die nicht-blockierenden Zeilen werden zu „Gate 3 Teil B" oder werden zu „Post-Launch-Tracking" degradiert. Der Zweck eines Gates ist zu schließen.

7.2 Gates, die ohne Prüfung bestehen

Eine Zeile liest Auto ✅, aber es gibt nirgends ein Skript, das sie ausübt. Zwei Wochen später besteht sie überhaupt nicht und niemand wusste es. Jede Auto-Zeile braucht eine ausführbare Prüfung, in der Zeile benannt. Wenn die Prüfung nicht existiert, ist die Zeile ❌, nicht ✅.

7.3 Versprechen, die nie zu Gates werden

Das ist das D-Catchup-Muster. Die Spec sagt, X wird wahr sein. Nichts prüft, dass X wahr ist. Der Berichterstatter ist ehrlich darüber, was er verifiziert hat — den Build, die Tests, den Lint. Das Ding, das niemand verifiziert hat, ist das Ding, das bricht. Alles, was in einer Spec wert ist, versprochen zu werden, ist wert, durch ein Gate gesichert zu werden.

7.4 Manuelle Genehmigungen, die „mündlich passiert sind"

Eine Zeile liest Manual ✅, weil ein Lead vor drei Wochen in einer Sitzung „sieht gut aus" sagte. Nichts in git hält es fest. Das nächste Mal, wenn jemand fragt, warum sie besteht, ist die Spur weg. Jede manuelle Genehmigung hinterlässt einen Commit oder ein PR-Review. Wenn es nicht im Repo ist, ist es nicht passiert.

7.5 Das „testen wir auf Produktion"-Gate

Eine Zeile liest pending — will verify after launch. Das ist kein Release gate, das ist eine wartende Post-Mortem. Entweder ist es vor dem Launch verifizierbar (auf ⏳ verschieben und verifizieren), oder es ist kein Launch-Kriterium (in einen separaten „Post-Launch-Tracking"-Abschnitt verschieben).

8. Ein Prinzip

Die ganze Form von Release gates kollabiert auf eine Zeile.

„Alles, was die Absicht des Betreibers als ‚fertig' behandeln würde, lass das System zuerst prüfen. Alles, was das System nicht prüfen kann, nenne den Menschen, der es getan hat."

Release gates sind die Schicht, in der die PRD aufhört, ein Wunsch zu sein, und zu einem Vertrag wird. Auto-Gate-Zeilen sind der durch eine Maschine durchgesetzte Vertrag. Manual-Gate-Zeilen sind der Vertrag, der durch einen benannten Menschen durchgesetzt wird, der eine Spur hinterlässt. Die Kombination ist das, was der Betreiber meint, wenn er sagt, ein Slice sei live.

Und sobald die Gates real sind — sobald jede Zeile entweder ein Skript ist, das mit 0 beendet, oder eine in git aufgezeichnete menschliche Genehmigung — braucht der Großteil der täglichen Arbeit den Betreiber nicht mehr an der Tastatur. Darum geht es in Teil 12 — Ralph loop. Eine PRD sagt, was zu bauen ist. Ein Gate sagt, wann es gebaut ist. Ein Loop geht den Weg von einem zum anderen, selbstständig, 24/7, während der Betreiber schläft.