--- type: issue id: "0104" status: done created: 2026-08-18 milestone: M1 priority: high area: infrastructure related: - "docs/issues/0031-stillstandspruefung-gitea-token-und-authentik.md" - "docs/issues/0053-historien-durchgang-nicht-kanonische-commits.md" gitlab_iid: "41" --- # Alle geplanten Prüfungen sind dauerhaft rot — damit meldet keine mehr etwas > Aufgefallen 2026-08-18 bei der Frage nach der Produktionsreife. Der auslösende > Einzelfall ist behoben; dieses Issue führt das Muster dahinter. ## Befund Die Plattform hat drei geplante Prüfungen, und ihr Alarmprinzip steht ausdrücklich in AGENTS.md: *„Seine rote Pipeline **ist** der Alarm — es gibt bewusst keinen zweiten Meldeweg."* Gemessen am 2026-08-18: | Prüfung | Zeitplan | Zustand | Grund | |---|---|---|---| | `canonize_rotation` (gitops) | täglich 05:17 | **war 9 Tage rot** (09.–18.08.) | liegengebliebener Rotationszweig, behoben `14cf931`/`ccf0460` | | `gruppenpruefung` (management) | täglich 00:42 | **rot, täglich** | 20 Befunde, davon 17 bewusst vertagt (#0053) | | `stillstandspruefung` (management) | täglich 00:42 | **rot, täglich** | `GITEA_TOKEN` fehlt → Abbruch (#0031) | Die management-Pipeline ist nachweislich seit mindestens dem 12.08. **jeden Tag** rot. Keine dieser Prüfungen kann derzeit etwas Neues melden: Rot ist ihr Normalzustand. ## Warum das die schwerste Klasse ist Der `canonize_rotation`-Fall ist der Beweis, nicht die Anekdote. Neun Tage lang scheiterte der Job an einem Merge-Konflikt, der ausgerechnet `coturn-secret.yaml`, `synapse-turn-secret.yaml` und `element-server-suite.yaml` betraf — und **niemand hat es bemerkt**, weil ein weiteres rotes Kreuz neben den anderen nicht auffällt. Gefunden wurde es nur, weil jemand aus einem anderen Anlass hinsah. Genau das ist die `mrtc`-Lehre, nur an anderer Stelle: Der Zustand war die ganze Zeit sichtbar und trotzdem unsichtbar. Ein Alarm, der immer schrillt, ist kein Alarm. Die Regel „rote Pipeline = Alarm" funktioniert nur, solange Grün der Normalfall ist — und das ist derzeit bei keiner der drei Prüfungen so. ## Zu entscheiden Die eigentliche Frage ist, **wie „bekannt und vertagt" von „neu" unterschieden wird**, ohne dass Vertagtes den Kanal verstopft: 1. **Bekannte Befunde quittieren.** Die Prüfungen bekommen eine gepflegte Liste akzeptierter Befunde (nach Muster von `sha_ausnahmen.tsv`); quittierte Befunde erscheinen weiterhin im Log, färben aber nicht rot. Rot wird, was **nicht** auf der Liste steht. Vorteil: Grün ist wieder erreichbar und bedeutet etwas. Risiko: eine Ausnahmeliste, die niemand aufräumt, ist die nächste Blindstelle — sie braucht ein Verfallsdatum je Eintrag. 2. **Vertagtes wegräumen statt quittieren.** #0053 abarbeiten und #0031 mit Tokens versorgen, dann sind beide Prüfungen von selbst grün. Ehrlicher, aber es macht die Alarmfähigkeit von Aufräumarbeit abhängig, die bewusst niedrige Priorität hat. 3. **Beides:** #0031 sofort (kleiner Aufwand, siehe dort), #0053 quittiert mit Verfallsdatum bis zum Historien-Durchgang. Empfehlung: **3.** Er stellt Grün kurzfristig her, ohne eine Entscheidung vorwegzunehmen, die zu #0053 gehört. ## Acceptance - Alle drei geplanten Prüfungen laufen an einem gewöhnlichen Tag **grün** durch. - Ein *neu* eingeführter Befund färbt nachweislich rot — an einem absichtlich erzeugten Beispiel gezeigt, nicht abgeleitet. - Quittierte Befunde bleiben im Log sichtbar und tragen einen Grund plus ein Datum, ab dem sie wieder rot färben. - In AGENTS.md steht neben „die rote Pipeline ist der Alarm" die Bedingung, unter der das gilt: dass Grün der Normalzustand ist. ## Bereits erledigt `canonize_rotation` ist grün (2026-08-18). Zwei Befunde dabei, beide behoben und hier festgehalten, weil sie dieselbe Klasse betreffen: - Ein überholter Rotationszweig ließ den Job konfliktieren statt ihn zu überspringen. Die Fehlermeldung riet zum Auflösen von Hand — was das TURN-Shared-Secret hätte zurückdrehen können, womit Synapse und coturn uneins und TURN tot gewesen wäre. - `git fetch` lief ohne `--prune`, der Runner recycelt seinen Workspace: Nach dem Löschen des Zweigs auf **beiden** Remotes meldete der Job ihn weiter. Löschen wäre also gar kein Ausweg aus dem Dauer-Rot gewesen — live beobachtet an Pipeline 492. ## Umsetzung 2026-08-18 — Quittierungsliste gebaut (Weg 3) Entscheidung sorb: Weg 3. Umgesetzt als `scripts/quittungen.py` plus `scripts/befund_quittungen.tsv`, eingehängt in **beide** geplanten Prüfungen. **Wirkung, gemessen:** gruppenpruefung von 20 offenen Befunden auf **0** (20 quittiert), stillstandspruefung von 5 auf **0**. `canonize_rotation` war bereits grün. **Die drei Regeln gegen die eigene Blindstelle** — der naheliegende Einwand gegen Quittierungslisten überhaupt: - Jede Zeile braucht eine **Frist**. Läuft sie ab, quittiert sie nicht mehr und meldet sich; der Befund zählt wieder. - **„Dauerhaft" ist nur als ADR-Verweis formulierbar.** Eine dauerhafte Ausnahme ohne Entscheidungs-Record ist laut AGENTS.md ohnehin ein Fehler — hier lässt sie sich nicht einmal hinschreiben. - Eine Zeile, auf die **kein Befund mehr passt**, meldet sich selbst zum Entfernen. **Die #0053-Befunde sind einzeln nach SHA quittiert**, nicht per Sammelmuster. Ein Muster wie `: Echtzeit-Stempel` wäre eine Zeile statt siebzehn gewesen und hätte jeden künftigen Verstoß mitverschluckt — genau die Blindstelle, gegen die das hier gebaut ist. Nebeneffekt: Nach dem Historien-Rewrite passen sie auf nichts mehr und melden sich. **Ein Konstruktionsfehler unterwegs**, hier notiert weil er sich wiederholen kann: Die erste Fassung hatte eine gemeinsame Liste ohne Geltungsbereich — jede Prüfung meldete daraufhin die Einträge der anderen als wirkungslos. Behoben durch die Spalte `pruefung`. ### Acceptance-Stand | Kriterium | Stand | |---|---| | Alle drei Prüfungen laufen grün durch | ✅ Pipeline 540 | | Ein *neu* eingeführter Befund färbt nachweislich rot | ✅ am Beispiel gezeigt, nicht abgeleitet | | Quittiertes bleibt sichtbar, mit Grund und Datum | ✅ | | Bedingung in AGENTS.md ergänzen | ✅ mit sorbs Zustimmung 2026-08-19; im Projektabschnitt, die neckbeard-Baseline bleibt byte-treu | | Prozessentscheidung als ADR festgehalten | ✅ [ADR-0020](../adr/0020-bekannte-befunde-quittieren.md) | Der letzte Punkt bleibt bewusst liegen: Änderungen an AGENTS.md werden nur mit sorb abgestimmt. Vorschlag für die Ergänzung neben „die rote Pipeline ist der Alarm": *„Das gilt nur, solange Grün der Normalzustand ist. Bekanntes wird quittiert (`scripts/befund_quittungen.tsv`), nicht toleriert — eine Prüfung, die dauerhaft rot steht, meldet nichts mehr."* ### Nachzug am selben Tag — zwei Befunde, die der erste Lauf zeigte **1. Ein Befundtext ändert sich, wenn man die Ursache anfasst.** Das Abschalten des `wiki`-Mirrors (#0105) verwandelte `Mirror wiki: Gegenseite nicht lesbar` in `wiki: kein aktiver Push-Mirror` — die Quittung greift über Teilzeichenketten und passte nicht mehr. Nachgetragen. Das ist kein Fehler des Verfahrens, sondern seine Kehrseite: Textbindung ist der Preis für eine Liste, die man ohne Spezialwissen lesen kann. Wer eine Ursache behebt oder verschiebt, muss die Quittung nachziehen — sonst färbt es zu Recht rot. **2. Ein flüchtiger Befund, der bewusst NICHT quittiert wird.** `Mirror management auseinander` erscheint bei jedem Lauf, der kurz nach einem Push startet, weil der Spiegel ein paar Minuten nachhinkt. Verlockend zu quittieren — und genau falsch: Dieselbe Meldung ist der einzige Hinweis, wenn ein Spiegel *wirklich* stehenbleibt (MIRROR-01, #0028). Sie bleibt scharf; ein Lauf unmittelbar nach einem Push ist eben kurz rot. ## Erledigt 2026-08-19 — alle drei Prüfungen grün | Prüfung | Stand | |---|---| | `canonize_rotation` (gitops) | ✅ grün seit dem 2026-08-18 | | `gruppenpruefung` (management) | ✅ 0 offene Befunde, 20 quittiert | | `stillstandspruefung` (management) | ✅ „Keine offenen Befunde", 6 quittiert | Pipeline 540, beide Jobs `success`. **Grün ist wieder der Normalzustand** — womit die Regel aus AGENTS.md („die rote Pipeline ist der Alarm") wieder trägt. **Der Weg dahin ging zweimal über die Ursache statt über eine Quittung**, und das ist der eigentliche Ertrag: - `gitops` hatte **keinen `workflow`-Block** und legte deshalb Pipelines auch dann an, wenn kein Job auf sie passte — rot ohne Fehler (Pipeline 518). Behoben in `1e65f5b`; `management` hatte dieselbe Lücke für API-Trigger und wurde in `cc3c430` vorbeugend mitgeschlossen. - Nur **eine** Sache ist quittiert, weil sie sich nicht beheben lässt: Pipeline 518 existiert in der Historie, und die Prüfung schaut acht Tage zurück. Frist **2026-08-28**, läuft also mit dem Prüffenster aus. Färbt es danach weiter rot, war der Fix unvollständig — und die Prüfung sagt es von selbst. Von 25 offenen Befunden am Morgen auf **null**, ohne dass ein einziger davon verschwiegen wurde: 26 stehen als Quittung mit Grund und Frist im Log. **Alle vier Abnahmekriterien erfüllt** (siehe Tabelle oben, plus ADR-0020 und der AGENTS.md-Zusatz).