Neuberechnung der Kette als eigene Gegenbuch-Alarmbedingung (R186 Frage b)
Der Tester fragte praezise: Loest cleanup -> rehash OHNE erneutes Siegeln, ueber NICHT versiegelten Inhalt, etwas Automatisches aus - oder nur die Prosa in verify, die ein Mensch lesen muss? Gemessen statt behauptet: Es loeste bereits aus, aber als Nebenwirkung. Ein Rehash aendert jeden Hash, also stimmt der beglaubigte Kettenkopf nicht mehr und der bestehende Vergleich schlug an. Das funktioniert, ist aber ein Zufallstreffer - verschoebe sich der Anker, waere der Melder lautlos weg. Und die Meldung hiess "Eintrag wurde veraendert" statt "die Kette wurde neu berechnet", also Wirkung statt Ursache. Jetzt haengt der Alarm an der Sache selbst: Das Gegenbuch fuehrt rehashCount/rehashLast im Buch mit und meldet jede neue Neuberechnung seit der letzten Beglaubigung mit exit 2, samt Zeitpunkt, Zeilenzahl und dem Befund, der unmittelbar davor galt. Dieselbe Lehre wie R184-01 (Gate am Ausloeser statt an der Wirkung) und R185-01 (Wurzelwechsel statt valid). Reihenfolge geaendert, und das war noetig: Der neue Melder steht VOR dem Kopf-Hash-Vergleich, sonst haette immer die unpraezisere Meldung gewonnen. Und der Kopf-Vergleich wird nach einer bestaetigten Neuberechnung uebersprungen - sonst waere die Bestaetigung wertlos, weil ein Rehash den Kopf zwangslaeufig aendert. Beim Bauen aufgefallen, nicht im Entwurf. NOTARY_REHASH_ACK wird mit der ID des Rehash-Eintrags bestaetigt, nicht mit true; IDs steigen streng, ein stehen gelassener Wert passt beim naechsten Vorgang nicht mehr. Ein fehlender beglaubigter Eintrag alarmiert weiterhin immer: bestaetigt wird die Neuberechnung, nicht das Verschwinden von Zeilen. Getestet mit echtem Gegenbuch gegen ein echtes CRM, SSH-signiertes lokales Buch: Waesche ohne Datenbankzugriff -> CRM meldet valid:true und chainGaps:[], Gegenbuch exit 2 mit der Neuberechnung als Ursache. Falsche Ack-ID weiter exit 2, richtige exit 0, Folgelauf ruhig. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -177,6 +177,58 @@ Im CRM selbst ist erneutes Siegeln zusätzlich gegatet: es verlangt
|
||||
`{"confirm":"RESEAL"}` statt `{"confirm":"SEAL"}` — ein Austausch der
|
||||
Beweisgrundlage soll nicht dasselbe Wort haben wie das Einrichten.
|
||||
|
||||
### Wenn die Kette neu berechnet wurde: ebenfalls Alarm
|
||||
|
||||
Ein **Rehash** verknüpft alle Einträge neu. Danach ist die Kette
|
||||
zwangsläufig stimmig — auch über Löschungen hinweg, die vorher als Lücken
|
||||
sichtbar gewesen wären. Die Reihenfolge `cleanup` → `rehash` macht aus einem
|
||||
beschnittenen Protokoll ein scheinbar makelloses, und die Prüfung im CRM meldet
|
||||
danach wieder „lückenlos verkettet". Beides braucht nur `audit:admin`, keinen
|
||||
Datenbankzugriff.
|
||||
|
||||
Genau das ist im Betrieb vorgekommen: Auf einer Testinstanz wurden 3.155
|
||||
Einträge gelöscht und anschließend neu berechnet. Die Prüfung war danach grün,
|
||||
die 656 Kettenlücken standen nur noch im Vorbefund des Rehash-Eintrags — den
|
||||
niemand liest. Das Gegenbuch war der einzige Zeuge.
|
||||
|
||||
Deshalb ist eine neue Neuberechnung seit der letzten Beglaubigung ein **Alarm**
|
||||
(exit 2). Er nennt Zeitpunkt, Zahl der betroffenen Zeilen und den Befund, der
|
||||
unmittelbar davor galt:
|
||||
|
||||
```
|
||||
ALARM: Die Hash-Kette wurde neu berechnet (1 neuer Vorgang seit der letzten Beglaubigung).
|
||||
zuletzt: 2026-08-26T16:28:25.467Z (Eintrag 13, 9 Zeilen)
|
||||
Befund unmittelbar davor: 1 beanstandet, 1 Lücken
|
||||
…
|
||||
NOTARY_REHASH_ACK=13
|
||||
```
|
||||
|
||||
**War die Neuberechnung gewollt**, bestätigst du sie mit der genannten ID:
|
||||
|
||||
```bash
|
||||
# in der .env
|
||||
PROD_REHASH_ACK=13
|
||||
docker compose up -d
|
||||
PROD_REHASH_ACK= # danach wieder leeren
|
||||
```
|
||||
|
||||
Auch hier wird nicht mit `true` bestätigt, sondern mit einem Wert, der zum
|
||||
Vorgang gehört. IDs steigen streng — ein stehen gelassener Wert passt bei der
|
||||
nächsten Neuberechnung nicht mehr.
|
||||
|
||||
**Warum ein eigener Melder, wo doch schon der Kettenkopf verglichen wird?**
|
||||
Eine Neuberechnung ändert jeden Hash, der beglaubigte Kopf stimmt also
|
||||
ohnehin nicht mehr — der Alarm käme auch so. Aber als *Nebenwirkung*, nicht als
|
||||
gebaute Warnung: Verschöbe sich der Anker irgendwann, wäre der Melder lautlos
|
||||
weg. Und die Meldung hieße „Eintrag wurde verändert" statt „die Kette wurde neu
|
||||
berechnet" — die Wirkung statt der Ursache. Deshalb hängt der Alarm an der
|
||||
Sache selbst und steht **vor** dem Kopf-Vergleich; nach einer bestätigten
|
||||
Neuberechnung wird dieser übersprungen, weil der veränderte Kopf dann die
|
||||
erwartete Folge ist.
|
||||
|
||||
Ein fehlender beglaubigter Eintrag bleibt davon unberührt und alarmiert immer:
|
||||
Bestätigt wird die Neuberechnung, nicht das Verschwinden von Zeilen.
|
||||
|
||||
### Zugang einrichten (das brauchst du vorher)
|
||||
|
||||
Das Gegenbuch braucht ein **eigenes Benutzerkonto** im CRM – kein Token. Der
|
||||
@@ -556,6 +608,7 @@ an, bis er geklärt ist.
|
||||
| Bestandssiegel-Blätter entfernt | beglaubigte Blattzahl auf null gefallen |
|
||||
| **Altzeile gelöscht und neu gesiegelt** (Wäsche) | **Wurzel des Bestandssiegels hat gewechselt – `valid` allein bleibt dabei `true`** |
|
||||
| Erstmals gesiegelt, ohne dass es jemand veranlasst hat | vorher keine Wurzel beglaubigt, jetzt eine |
|
||||
| **`cleanup` + `rehash` ohne erneutes Siegeln** (Wäsche ohne Datenbankzugriff) | **neue Neuberechnung seit der letzten Beglaubigung – `valid` und Kette sind danach makellos** |
|
||||
|
||||
Bei jedem dieser Fälle bricht das Skript mit **Exit-Code 2** ab und **hängt
|
||||
nichts an** – der manipulierte Zustand wird also nicht als neue Wahrheit
|
||||
|
||||
Reference in New Issue
Block a user