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>
97 lines
4.1 KiB
Bash
97 lines
4.1 KiB
Bash
# ============================================================
|
||
# Gegenbuch für OpenCRM
|
||
# ============================================================
|
||
# Diese Datei gehört auf den Gegenbuch-Rechner – NICHT auf den CRM-Server.
|
||
#
|
||
# Was hier passiert: Der Rechner holt regelmäßig einen kurzen Kontrollwert von
|
||
# OpenCRM ab und schreibt ihn in ein Buch, das nur hier liegt. Wird später im
|
||
# CRM etwas nachträglich verändert, widerspricht das dem Buch.
|
||
|
||
|
||
# ============================================================
|
||
# Welche Bücher sollen laufen?
|
||
# ============================================================
|
||
# Gültige Werte: prod | staging | prod,staging | (leer = keins)
|
||
# Genau so geschrieben – nicht "production" oder "test".
|
||
#
|
||
# Nur Staging testen: COMPOSE_PROFILES=staging
|
||
# Später Prod dazunehmen: COMPOSE_PROFILES=prod,staging
|
||
# Danach: docker compose up -d (der laufende Dienst bleibt unberührt)
|
||
COMPOSE_PROFILES=staging
|
||
|
||
# Steht in den Einträgen des Buchs. Beliebiger Text, nur Kosmetik.
|
||
NOTAR_EMAIL=gegenbuch@example.de
|
||
|
||
|
||
# ============================================================
|
||
# Produktion
|
||
# ============================================================
|
||
# Adresse der OpenCRM-Instanz, von der geholt wird.
|
||
# Gültig: vollständige URL mit https:// und OHNE Schrägstrich am Ende.
|
||
PROD_CRM_URL=https://crm.example.de
|
||
|
||
# Zugang: ein eigenes Benutzerkonto im CRM, das NUR das Recht "audit:read" hat.
|
||
# Wie man es anlegt, steht in der README unter "Zugang einrichten".
|
||
#
|
||
# Das Gegenbuch meldet sich damit bei jedem Durchlauf selbst an. Ein fest
|
||
# hinterlegtes Token gibt es bewusst nicht – Zugangstoken laufen nach
|
||
# 15 Minuten ab und wären beim nächsten Durchlauf längst ungültig.
|
||
PROD_CRM_EMAIL=gegenbuch@deine-domain.de
|
||
PROD_CRM_PASSWORD=
|
||
|
||
# Wie oft geprüft wird, in Sekunden.
|
||
# Gültig: ganze Zahl > 0. Üblich: 3600 (stündlich), 900 (viertelstündlich)
|
||
# Kürzer heißt: kleineres Zeitfenster, in dem eine Änderung unbemerkt bliebe.
|
||
PROD_INTERVAL=3600
|
||
|
||
# Beim ALLERERSTEN Start einmalig setzen, danach wieder leeren.
|
||
# Gültige Werte: true | (leer)
|
||
# Grund: Die erste Eintragung legt fest, was als Ausgangszustand gilt – das
|
||
# soll nicht versehentlich passieren.
|
||
PROD_GENESIS_ACK=
|
||
|
||
# Normalerweise leer lassen.
|
||
# Gültige Werte: true | (leer)
|
||
# Nur nötig, wenn das Datenverzeichnis verlorenging (z. B. gelöscht) UND du
|
||
# geklärt hast, warum. Siehe README, Abschnitt "Wenn das Gedächtnis fehlt".
|
||
PROD_ADOPT_ACK=
|
||
|
||
# Normalerweise leer lassen.
|
||
# Gültige Werte: die neue Siegelwurzel (mind. 16 Zeichen) | (leer)
|
||
# Das Gegenbuch schlägt Alarm, wenn sich die Wurzel des Bestandssiegels
|
||
# ändert – denn ein erneutes Siegeln ersetzt die Grundlage, gegen die
|
||
# Manipulation nachgewiesen wird. War der Wechsel gewollt, hier die Wurzel
|
||
# eintragen, die der Alarm nennt, einmal laufen lassen und wieder leeren.
|
||
# Bewusst KEIN "true": ein stehen gelassener Wert passt beim nächsten
|
||
# Wechsel nicht mehr und kann darum keinen weiteren stillschweigend
|
||
# durchwinken.
|
||
PROD_SEAL_ACK=
|
||
|
||
# Normalerweise leer lassen.
|
||
# Gültige Werte: die ID des Rehash-Eintrags | (leer)
|
||
# Das Gegenbuch schlägt Alarm, wenn die Hash-Kette neu berechnet wurde. Ein
|
||
# Rehash verknüpft alle Einträge neu – Lücken, die eine Löschung sichtbar
|
||
# gemacht hätten, verschwinden dabei aus der Kette, und die Prüfung im CRM
|
||
# meldet danach wieder „lückenlos". War die Neuberechnung geplant, hier die
|
||
# ID eintragen, die der Alarm nennt, einmal laufen lassen und wieder leeren.
|
||
PROD_REHASH_ACK=
|
||
|
||
# Wo das Buch liegt – relativ zu diesem Verzeichnis.
|
||
# DIESES VERZEICHNIS GEHÖRT INS BACKUP (enthält Buch und Signaturschlüssel).
|
||
PROD_DIR=./data/prod
|
||
|
||
|
||
# ============================================================
|
||
# Test / Staging
|
||
# ============================================================
|
||
# Gleiche Regeln wie oben, eigenes Konto und eigenes Verzeichnis.
|
||
STAGING_CRM_URL=https://staging.example.de
|
||
STAGING_CRM_EMAIL=gegenbuch@deine-domain.de
|
||
STAGING_CRM_PASSWORD=
|
||
STAGING_INTERVAL=3600
|
||
STAGING_GENESIS_ACK=
|
||
STAGING_ADOPT_ACK=
|
||
STAGING_SEAL_ACK=
|
||
STAGING_REHASH_ACK=
|
||
STAGING_DIR=./data/staging
|