Claude Code hat mein Ledger an einem Nachmittag in eine Datenbank umgezogen. Die Daten richtig zu halten, hat bis zum 2. Juli gedauert – bis die Regeln, die sie schützen, in die Datenbank selbst gewandert sind.
Am Nachmittag des 14. Juni habe ich eine Claude-Code-Sitzung gestartet, in deren Prompt es hieß: „Work phase by phase; do not skip ahead. Treat correctness of financial data as the top priority.“ Claude hatte ihn früher am selben Tag geschrieben, zusammen mit einem Bau-Runbook (einem Schritt-für-Schritt-Plan mit Prüfungen). Die erste Phase wurde um 15:45 committet, die letzte um 17:56. Am Abend lag mein Haushalts- und Geschäftsbuch, das Ledger, in PostgreSQL, einer relationalen Datenbank, und seine Tabelle war eingefroren.
Warum eine Datenbank
Die Tabelle konnte weder sagen, woher eine Zeile stammte, noch zwei Schreiber gleichzeitig sicher verkraften, und mein neuer Dateidienst bot Skripten keine Möglichkeit, sie zu bearbeiten.
Am 12. Juni hatte Claude das Ledger gegen die Bankdateien geprüft und rund 75 wiederkehrende Zahlungen als fehlend gemeldet. Mein Journal hält fest, dass ich widersprochen habe: Die Zahlungen standen jeden Monat in den Bankdateien. Claudes eigenes Skript hatte Duplikate über die Referenz entfernt, die die Bank jeder monatlichen Abbuchung eines Dauerauftrags gibt. So verschwanden rund 101 echte Bankzeilen, und Claude zog die Befunde noch am selben Tag zurück.
An einem Nachmittag gebaut
Das Runbook hatte neun Phasen und vier Haltepunkte, an denen Claude Code einen Nachweis zeigen und warten musste: ein Backup, in eine Testdatenbank zurückgespielt; die 2.679 übernommenen Zeilen, gegen die Tabelle geprüft; die ersten neuen Zeilen; der Plan vor der Umstellung. Es hat an jedem gehalten.
Siebzehn Tage stiller Rückfälle
Dann gingen die Daten von selbst wieder kaputt, ganz leise. Am 2. Juli hat Claude die Zeit vom 15. Juni bis 1. Juli aus Audit-Log, git und Sitzungsprotokollen rekonstruiert. Der Belegverweis einer Zeile war von mindestens sechs Schreibern zehnmal umgeschrieben worden. Allein am 1. Juli haben 32 Schreiber – Skripte, Jobs und Claude-Sitzungen, mehrere gleichzeitig – 6.634 Änderungen gemacht. Eine Sitzung löschte einen Verweis, den eine andere gerade repariert hatte; 3.249 Audit-Einträge trugen keinen Namen.
Die Rekonstruktion fand sechs Ursachen, darunter mehrfach gespeicherte Angaben, Massenbereinigungen auf Basis vager Annahmen und Korrekturen, die committet, aber nicht ausgerollt waren. Am 1. Juli hatten der Bankimport und die Belegablage für denselben Kauf je eine Zeile angelegt.
Die Regeln ziehen in die Datenbank
Am 1. Juli habe ich entschieden, dass nur der Bankimport eine Zeile anlegen darf; Belege hängen sich an eine Bankzeile oder warten. Am 2. Juli kam der Rest in die Datenbank und in den einen Schreibweg, den jeder Schreiber nimmt. Die Datenbank lehnt einen Schreibvorgang ohne Namen des Schreibers ab und sperrt bestätigte Felder für automatische Änderungen; der Schreibweg vergibt eine befristete Schreiberlaubnis (Lease) an jeweils einen Schreiber und weist einen veralteten Tabellenexport zurück. Dazu kam eine tägliche Integritätsprüfung; schon ihr erster Lauf fand echte Fehler, die noch am selben Tag behoben wurden.
Ganz eingefroren war die alte Tabelle nicht. Am 13. Juli fiel eine Sitzung, der die Datenbank-Einstellung fehlte, stillschweigend auf sie zurück und fügte neun Zeilen hinzu. Sie bemerkte das selbst; die Voreinstellung wurde am selben Tag geändert. Seit dem 2. September weist ein Guard-Hook in Claude Code jeden Schreibversuch auf die alte Tabelle ab.
Das kannte ich schon
Am 19. April hatte Claude geplant, meine Aufgaben aus Dashboard-Tabellen in einzelne Notizen umzuziehen, und ich habe entschieden: alles auf einmal, heute Nacht. Der Nachtlauf meldete Erfolg, doch der neu geschriebene Aufgabenscanner existierte nur in der Kopie der Skripte im Notizordner (englisch „Vault“). Die ausgerollte Kopie las weiter die alten Tabellen, und meine Aufgabenliste blieb bis zum 30. April leer.
Das Muster
Ein führendes System (System of Record) für jede Art von Daten, und die Regeln, die es schützen, liegen in der Datenbank. Die erste Hälfte kam am Bautag in mein Entscheidungsprotokoll; die zweite hat bis zum 2. Juli gedauert. Eine Regel in einem Prompt gilt nur, solange jede Sitzung sie liest; eine Regel in der Datenbank gilt für jeden Schreiber. Wenn zwei Automationen dieselbe Aufgabe erledigen können, bekommt eine das alleinige Recht, anzulegen. Eine Migration ist fertig, wenn jedes System, das die Daten nutzt, umgezogen ist – nicht schon, wenn die Daten es sind.
Nicht gelöst ist: Nur das Ledger weist einen falschen Schreibvorgang schon an der Tür ab; meine Aufgaben und Notizen sind Dateien und werden erst hinterher geprüft.
Teil 5 von zwölf in der Serie darüber, wie ich mein AI OS gebaut habe. Der Anfang: das Vorwort.
Als Nächstes: der grüne Haken über nichts – Prüfungen, die Erfolg meldeten, während nichts geprüft wurde.
Anhang – für alle, die selbst bauen
- Schreib den Bau als Runbook mit Haltepunkten. Lass den Agenten die Routinephasen durchlaufen, aber an den unumkehrbaren Stellen anhalten und einen Nachweis zeigen – zuerst ein Backup, das vor dem ersten Schreibvorgang in eine Testdatenbank zurückgespielt wird.
- Friere den alten Speicher im Code ein, nicht mit einem Banner. Lass jede Voreinstellung auf den neuen Speicher zeigen und brich ab, wenn die Einstellung fehlt; am 13. Juli hat ein Banner kein Skript aufgehalten.
- Lass jeden Schreibvorgang einen Namen tragen und sperre, was ein Mensch bestätigt hat, erzwungen von der Datenbank; lass nur einen Schreiber auf einmal herein. Was man nicht zuordnen kann, kann man nicht rekonstruieren.
- Plane eine regelmäßige Integritätsprüfung ein, mit ein paar „Kanarienvogel“-Zeilen (schon einmal kaputte Zeilen mit festgeschriebenem Sollzustand), die laut anschlagen.
- Prüfe das Prüfwerkzeug. Ein Schlüssel zum Entfernen von Duplikaten ist eine Behauptung über deine Daten; gleich ihn mit der Quelle ab, bevor du handelst.
- Was ich stattdessen erwogen habe: die Tabellendateien zu behalten und ihre Kopien abzugleichen; eine direkte Verbindung von der Office-Suite zur Datenbank (zurückgestellt, solange eine erzeugte Tabelle reicht, deren Änderungen ich zurückspiele); auch Gesundheits- und Gebäudedaten in die Datenbank zu holen (zurückgestellt). Eine Datenbank nur für das Ledger habe ich gewählt, weil Ledger, Konten, Vermögenswerte und Budgets zusammenhängen und weil eine Datenbank einen falschen Schreibvorgang ablehnen kann.