diff --git a/decisions/0009-commit-konventionen-und-historien-anonymisierung.md b/decisions/0009-commit-konventionen-und-historien-anonymisierung.md new file mode 100644 index 0000000..42d1729 --- /dev/null +++ b/decisions/0009-commit-konventionen-und-historien-anonymisierung.md @@ -0,0 +1,92 @@ +# 0009 — Commit-Konventionen und rückwirkende Anonymisierung der Historie + +**Status:** akzeptiert · **Datum:** 2026-08-07 (Regel) / 2026-08-09 (Durchführung) · **Entscheider:** sorb + +> Nachgetragen am 2026-08-09 in der [Retro](../verfahren/retro/2026-08-09.md). Die +> Entscheidung war getroffen und ausgeführt, bevor sie als ADR vorlag — das ist +> genau der Fehler, den die ADR-Pflicht verhindern soll, und wird hier benannt +> statt geglättet. + +## Kontext + +Commit-Zeitstempel geben Arbeitszeiten preis. Bei einem Ein-Personen-Projekt mit +öffentlichem Gitea-Spiegel heißt das: Jeder, der die Repos liest, kann ablesen, an +welchen Abenden und bis wann gearbeitet wurde. Vor der Umstellung standen die +Commits eines Tages typischerweise zwischen 17:00 und 23:00 — ein Muster, das +nichts mit der Software zu tun hat. + +Dazu kam eine uneinheitliche Sprache in den Commit-Nachrichten (Deutsch und +Englisch gemischt) und drei Autoren-Identitäten für dieselbe Person. + +## Entscheidung + +**Regel ab 2026-08-07**, gültig für alle Repos der Gruppe `axion1337.chat` und die +ThreadNet-Dienste: + +- Nachrichten auf **Englisch**, Conventional-Commit-Stil +- Autor- **und** Committer-Datum auf **12:00:00 UTC des laufenden Tages** + +**Rückwirkend angewandt am 2026-08-09** auf **251 Commits** — alles aus dieser +Zusammenarbeit, nicht die davor liegende Historie: + +| Repo | umgeschrieben | Grenze | +|---|---|---| +| gitops | 117 von 264 | ab 2026-07-27 | +| management | 78 von 78 | vollständig | +| ThreadNet-Web | 47 von 50 | ab 2026-07-28 | +| threadnet-call | 9 von 9 | vollständig | + +Dabei wurden 17 Tags mit umgezogen und die Autoren-Identitäten vereinheitlicht — +**mit Ausnahme des `turn-secret-rotation`-Bots**, dessen Commits maschinell +entstehen und deren Zuschreibung an einen Menschen falsch wäre. + +Zeitstempel wurden auf **12:00 UTC des jeweils eigenen Tages** gesetzt, nicht auf +ein einheitliches Datum: Der Tag bleibt damit als Information erhalten, die +Uhrzeit verschwindet. + +## Konsequenzen + +- **Der Inhalt ist unverändert.** Alle Trees sind bitgleich, Nachrichten und + Merge-Struktur erhalten — geprüft über alle 251 Paare. +- **Alle SHAs im Bereich sind neu.** Verweise in Issues, Doku und Commit-Texten + zeigen ins Leere. Die Doku wurde nachgezogen (12 Stellen); für alles andere gibt + es die dauerhafte Zuordnungstabelle + [`shared/commit-zuordnung-2026-08-07.md`](../shared/commit-zuordnung-2026-08-07.md). +- **Issue-Kommentare wurden bewusst NICHT umgeschrieben.** Eine Tabelle + nachzuschlagen ist zumutbar; nachträglich zu ändern, was jemand geschrieben hat, + beschädigt dieselbe Nachvollziehbarkeit ein zweites Mal. +- **Container-Images verweisen auf Commits, die es nicht mehr gibt.** Sie laufen + unverändert; ihre Herkunft ist nur über die Tabelle auflösbar. +- **Branch- und Tag-Schutz mussten vorübergehend gelockert werden.** Beide sind + wieder aktiv. + +⚠️ **Der Nutzen ist begrenzt, und das gehört zur Entscheidung.** Geschützt ist +allein die Git-Historie. Push-Zeiten, Issue- und Kommentar-Zeitstempel, +Pipeline-Läufe und Paket-Veröffentlichungen tragen weiterhin die echte Uhrzeit, +liegen im selben GitLab und teilweise auf dem öffentlichen Spiegel — und sind +**feiner** als Commit-Zeiten, weil es mehr davon gibt. Wer wirklich kein Muster +ableitbar haben will, muss dort ansetzen. Diese ADR löst das nicht. + +## Was dabei fast schiefging + +Das Force-Push der umgezogenen Tags hat in ThreadNet-Web **drei Release-Pipelines +neu gestartet**. Ohne Sperre hätte `docker_web` das veröffentlichte Image +`v0.4.0` aus altem Quellcode gegen heutige Basis-Images neu gebaut und +überschrieben. Verhindert hat es allein, dass die geschützten Registry-Variablen +in diesem Fenster nicht verfügbar waren — **Zufall, nicht Planung**. Behoben in +ThreadNet-Web#14; die Sperre ist seit `3cb43f5` scharf. + +## Verworfene Alternativen + +- **Nur vorwärts, Historie unangetastet.** War die Empfehlung: kein Risiko, keine + toten Verweise, und der Nutzen des Rewrites ist durch die Plattform-Zeitstempel + ohnehin begrenzt. sorb hat sich bewusst dagegen entschieden — die Git-Historie + ist der Teil, der geklont und weitergegeben wird. +- **Alles umschreiben, auch die Vor-Historie.** Hätte fremde Autorenschaft + angefasst (`Scrublord@Mac.Bad`, 135 Commits aus der Zeit vor dieser + Zusammenarbeit) und den Nutzen nicht erhöht. +- **Ein einheitliches Datum für alle Commits.** Hätte die zeitliche Reihenfolge + unlesbar gemacht, ohne mehr zu schützen als der Tagesstempel. +- **Auch die Commit-Nachrichten rückwirkend übersetzen.** 251 Nachrichten neu zu + formulieren hieße, die darin festgehaltenen Begründungen umzuschreiben — + Inhaltsverlust für einen Stilgewinn, den nur die Vergangenheit hätte. diff --git a/verfahren/refinement.md b/verfahren/refinement.md index 488f7de..9c857a2 100644 --- a/verfahren/refinement.md +++ b/verfahren/refinement.md @@ -48,6 +48,9 @@ Drei Fragen, mehr nicht: Grundlage sind die AARs des Monats — sie sind die Retro-Vorbereitung, nicht ihr Ersatz. +Ergebnisse werden unter [`retro/`](retro/) abgelegt, eine Datei je Termin. Die +erste: [2026-08-09](retro/2026-08-09.md). + ## AAR (anlassbezogen) Nach jedem Deploy mit Übergabe und nach jedem Incident, Vorlage in diff --git a/verfahren/retro/2026-08-09.md b/verfahren/retro/2026-08-09.md new file mode 100644 index 0000000..2fb945c --- /dev/null +++ b/verfahren/retro/2026-08-09.md @@ -0,0 +1,126 @@ +# Retro light — 2026-08-09 + +Erste Retro des Frameworks, angehängt an das Refinement vom selben Tag +([Verfahren](../refinement.md)). Grundlage sind die vier AARs des Monats und 38 +im August geschlossene Issues. + +--- + +## 1. Welche Verfahren haben getragen, welche haben gestört? + +### Getragen + +**„Alles Offene wird ein Issue."** Das ist das Verfahren, das diesen Monat am +meisten eingebracht hat. Sämtliche stillen Fehler unten wurden nur deshalb nicht +vergessen, weil sie im Moment des Findens ein Issue bekamen — auch die, für die +gerade keine Zeit war. + +**Die AAR-Pflicht.** Die vier AARs waren die einzige belastbare Vorbereitung für +diese Retro. Ohne sie wäre sie eine Erinnerungsübung geworden. + +**Die Board-Pflege-Tabelle** (2026-08-06). Sie hat gehalten: `status:next` und +Meilenstein-Zuordnung blieben sorbs Entscheidung, auch als es unbequem war. +management#15 und #20 lagen drei Tage ohne Spalte — das ist der beabsichtigte +Preis, nicht ein Fehler. + +### Gestört + +**Der Status-Label-Satz ist in der Oberfläche nicht vollständig ablesbar.** +`status:next`, `status:doing`, `status:wartet` — und „ohne Label = Backlog". Die +vierte Spalte ist damit die einzige, die man nicht *sieht*, sondern erschließen +muss. Genau deshalb hat eine Session am 2026-08-06 ein `status:offen` erfunden und +in vier Projekten angelegt; aufgefallen ist es erst zwei Tage später. + +Die Regel bleibt richtig — ein Label für „nichts Besonderes" wäre Rauschen. Aber +der Reiz, es zu erfinden, ist real und wird wiederkommen. **Festgehalten statt +geändert.** + +--- + +## 2. Welche ADRs sind durch die Realität überholt? + +**Keine überholt — aber eine Lücke.** + +⚠️ **Die Commit-Konventionen und die Anonymisierung der Historie hätten eine ADR +gebraucht.** Am 2026-08-07 wurde eine dauerhafte Prozessregel eingeführt (englische +Conventional Commits, Zeitstempel auf 12:00 UTC) und am 2026-08-09 rückwirkend auf +251 Commits angewandt — eine **irreversible** Änderung an vier Repos, mit +Force-Push durch einen Mirror, von dem Flux liest. + +Nach unserer eigenen Regel („ADR-Pflicht bei Architektur-/Prozessentscheidungen") +ist das ein Lehrbuchfall. Stattdessen steht die Regel nur in der `CLAUDE.md` und +die Durchführung in einer Zuordnungstabelle. Nachzuholen als **ADR-0009**. + +**Beobachtung zu ADR-0005:** Das Kanban-Framework wurde diese Woche zweimal +erweitert (Titel ohne Priorität, Meilenstein-Pflicht) — beides in der `CLAUDE.md`, +nicht in der ADR. Das ist vertretbar, solange die ADR die *Entscheidung* hält und +die `CLAUDE.md` die *Regel*. Es ist aber genau die Zwei-Orte-Konstruktion, die wir +bei den Titel-Präfixen gerade aufgelöst haben. **Im Auge behalten.** + +--- + +## 3. Fasert etwas aus? + +**Nein — aber es gibt ein Muster, und das ist der eigentliche Befund des Monats.** + +### Sechs stille Fehler in neun Tagen + +| Was | Wie es aussah | Wie es wirklich stand | +|---|---|---| +| `build_embedded` (threadnet-call) | grün, seit jeher | lud **nie** ein Artefakt hoch, falscher Pfad | +| npm-Paket `0.19.2-threadnet.6` | veröffentlicht | 12,5 KB statt 12,8 MB, **ohne `dist/`** | +| Blueprint `matrix-recovery-flow` | Flux grün, ConfigMap aktuell | seit Tagen bei **jedem** Lauf verworfen | +| gitops-Arbeitskopie | „normal" | `main` trackte **Gitea** — ein `git push` wäre in die verbotene Richtung gegangen | +| Leere Pipelines | rot | **nichts kaputt** — der umgekehrte Fall, Rauschen, das rot abtrainiert | +| Release-Pipeline auf `v0.4.0` | lief nach Tag-Push an | hätte ein veröffentlichtes Image überschrieben | + +Gefunden wurde **keiner** davon durch eine Überwachung. Vier durch Zufall beim +Suchen nach etwas anderem, zwei durch gezieltes Nachprüfen einer Behauptung. + +### Das gemeinsame Merkmal + +Alle sechs betreffen Vorgänge, die **erfolgreich aussehen, ohne es zu sein** — oder +die genau umgekehrt Alarm auslösen, wo nichts ist. Der Verbund hat für keinen +dieser Fälle eine Antwort auf die Frage: *Wer merkt es, wenn etwas leise aufhört zu +funktionieren?* + +Es gibt Issues für Einzelfälle — gitops#50 (Configs greifen nicht ohne Neustart), +management#28 (Mirror-Ausfall unbemerkt), ThreadNet-Web#14 (Release überschreibbar, +behoben). Was fehlt, ist die Klammer. + +⚠️ **Der letzte Fall ist der unangenehmste.** Dass `v0.4.0` nicht überschrieben +wurde, lag daran, dass die geschützten Registry-Variablen in genau diesem Fenster +nicht verfügbar waren — **Glück, nicht Absicht.** Eine Schutzmaßnahme, die +zufällig griff, ist kein Schutz. + +### Vorschlag + +Eine **Stillstandsprüfung**: ein geplanter Job, der die Invarianten prüft, die wir +diesen Monat einzeln und mühsam gelernt haben — Blueprint-Status ≠ error, Mirror +synchron, Pipeline ohne Jobs, Artefakt vorhanden, Paketgröße plausibel. Kein +weiterer Agent, der Meldungen erzeugt, sondern **eine** Prüfung mit einem Ergebnis. + +Das ist die Verallgemeinerung von management#28, das am 2026-08-06 bewusst nach +hinten gestellt wurde. Die Rückstufung war zu dem Zeitpunkt vertretbar; sechs +Fälle später sieht der Einzelfall aus wie ein Symptom. **Zur Entscheidung +vorgelegt, nicht eigenmächtig umgestuft.** + +--- + +## Beschlüsse dieses Refinements + +- `status:next`: management#15 und #20 (fällig 31.08.) — Zusage von sorb +- `status:wartet` entfernt bei threadnet-call#4 und ThreadNet-Web#11: der im Issue + benannte Grund war weggefallen +- **M5 — Härtung** angelegt, 14 Issues aus M1 verschoben. Trennlinie: *Ist etwas + Vorhandenes kaputt (M1) oder fehlt etwas, das wir noch nie hatten (M5)?* + Verteilung danach: M1 18 · M2 21 · M3 4 · M4 13 · M5 14 + +⚠️ Die beiden letzten Punkte sind einer Session **allein** untersagt +([Board-Pflege](../refinement.md)). Sie fanden im Refinement mit sorb statt. Die +Regel ist damit nicht aufgeweicht. + +## Offen aus dieser Retro + +1. **ADR-0009** zu Commit-Konventionen und Historien-Anonymisierung nachziehen +2. **Stillstandsprüfung** — Entscheidung von sorb