diff --git a/CLAUDE.md b/CLAUDE.md index 737476d..5a034ca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -85,26 +85,27 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein ## Aktiver Implementierungsstand -M1 bis M5 sind vollständig abgeschlossen. Der aktive Stand ergänzt den vollständigen -Erfolgspfad: korrekt benannte Zielkopie erzeugen und Enderfolg konsistent persistieren. +M1 bis M6 sind vollständig abgeschlossen. Der aktive Stand schließt die betriebliche +Lücke zwischen dem M6-Erfolgspfad und dem final robusten Endstand. -### Baseline aus M5 -- Externer Prompt-Bezug über konfigurierbare Prompt-Datei -- OpenAI-kompatibler HTTP-Adapter vollständig verdrahtet -- Validierte KI-Antwort mit `date`, `title`, `reasoning` -- Persistierter Benennungsvorschlag mit Status `PROPOSAL_READY` -- Versuchshistorie mit KI-Nachvollziehbarkeit (Modell, Prompt-ID, Zeichenzahl, Rohantwort, Reasoning, Datum, Datumsquelle) -- Idempotente Migration M4 → M5 - -### Ziel des aktiven Stands +### Baseline aus M6 - Technische Dateinamensbildung im Format `YYYY-MM-DD - Titel.pdf` - Dublettenbehandlung im Zielordner: `(1)`, `(2)`, … - Physische Zielkopie via temporäre Datei und finalem Move/Rename -- Schemaevolution auf den aktiven Stand (Zielpfad, Zieldateiname) +- Schemaevolution M5 → M6 (Zielpfad, Zieldateiname in Stammsatz und Versuchshistorie) - Statustransition `PROPOSAL_READY` → `SUCCESS` -- Zusätzliche Historisierung für Enderfolg und technische Fehler (Proposal-Versuch bleibt erhalten) +- Zusätzliche Historisierung für Enderfolg und technische Fehler - Startvalidierung für Zielordner-Konfiguration (`target.folder`) +### Ziel des aktiven Stands +- Vollständige laufübergreifende Retry-Logik für deterministische Inhaltsfehler und transiente technische Fehler +- Technischer Sofort-Wiederholversuch ausschließlich für Zielkopierfehler (genau ein zusätzlicher Versuch im selben Lauf) +- Finalisierung ausgeschöpfter Retry-Rahmen zu `FAILED_FINAL` +- Vollständige Skip-Semantik: `SUCCESS` und `FAILED_FINAL` werden historisiert übersprungen +- Logging-Mindestumfang des Endstands vollständig angebunden +- Sensibilitätsregel für KI-Inhalte im Logging +- Vervollständigte Startvalidierung und finale Exit-Code-Semantik + ## Statussemantik | Status | Bedeutung | @@ -131,45 +132,103 @@ Erfolgspfad: korrekt benannte Zielkopie erzeugen und Enderfolg konsistent persis - Proposal-Versuch mit fachlich unbrauchbarem Titel oder Datum = inkonsistenter Persistenzzustand = dokumentbezogener technischer Fehler. - Inkonsistente Proposal-Zustände werden **nicht stillschweigend geheilt**, sondern als technische Dokumentfehler behandelt. +## Retry-Semantik (aktiver Stand) + +### Deterministische Inhaltsfehler +Deterministische Inhaltsfehler sind insbesondere: +- kein brauchbarer Text +- Seitenlimit überschritten +- fachlich unbrauchbarer oder generischer Titel +- vorhandenes, aber unbrauchbares KI-Datum + +Regel: +- **erster** historisierter deterministischer Inhaltsfehler → `FAILED_RETRYABLE` +- **zweiter** historisierter deterministischer Inhaltsfehler → `FAILED_FINAL` + +### Transiente technische Fehler +- Transiente Fehler laufen über den Transientfehlerzähler im Dokument-Stammsatz. +- Sie bleiben retryable bis der konfigurierte Grenzwert `max.retries.transient` erreicht ist. +- Der Fehlversuch, der den Grenzwert **erreicht**, finalisiert den Dokumentstatus zu `FAILED_FINAL`. +- `max.retries.transient` = **Integer >= 1**; der Wert `0` ist ungültige Startkonfiguration. +- Beispiel: `max.retries.transient = 1` → erster transiente Fehlversuch finalisiert sofort. + +### Technischer Sofort-Wiederholversuch +- **Genau ein** zusätzlicher technischer Schreibversuch innerhalb desselben Dokumentlaufs. +- **Ausschließlich** für Fehler beim physischen Zielkopierpfad. +- Kein erneuter KI-Aufruf, keine erneute Fachableitung. +- Zählt **nicht** zum laufübergreifenden Transientfehlerzähler. +- Liefert genau ein dokumentbezogenes Ergebnis für Persistenz und Statusfortschreibung. + +### Skip-Semantik +- `SUCCESS` → in späteren Läufen `SKIPPED_ALREADY_PROCESSED` historisieren, keine Zähleränderung. +- `FAILED_FINAL` → in späteren Läufen `SKIPPED_FINAL_FAILURE` historisieren, keine Zähleränderung. +- `FAILED_RETRYABLE`, `READY_FOR_AI`, `PROPOSAL_READY` → verarbeitbar. + +## Logging-Mindestumfang (aktiver Stand) + +Folgende Informationen müssen nachvollziehbar geloggt werden: +- Laufstart mit Lauf-ID +- Laufende +- erkannte Quelldatei +- Überspringen bereits erfolgreicher Dateien +- Überspringen final fehlgeschlagener Dateien +- erzeugter Zielname +- Retry-Entscheidung +- Fehler mit Klassifikation + +### Korrelationsregel +- Vor erfolgreicher Fingerprint-Ermittlung: Korrelation über Lauf-ID und Kandidatenbezug. +- Nach erfolgreicher Fingerprint-Ermittlung: dokumentbezogene Logs enthalten den Fingerprint oder eine eindeutig ableitbare Referenz. +- Keine neue Persistenz-Wahrheit oder zusätzliche Tracking-Ebene. + +### Sensibilitätsregel für KI-Inhalte +- Vollständige KI-Rohantwort: standardmäßig **nicht** ins Log, bleibt in SQLite. +- Vollständiges KI-`reasoning`: standardmäßig **nicht** ins Log, bleibt in SQLite. +- Freischaltung nur über expliziten booleschen Konfigurationswert. +- Default: sicher / nicht loggen. + ## Verarbeitungsreihenfolge pro Dokument (aktiver Stand) 1. Fingerprint berechnen 2. Dokument-Stammsatz laden 3. Terminale Skip-Fälle entscheiden (`SUCCESS` → `SKIPPED_ALREADY_PROCESSED`, `FAILED_FINAL` → `SKIPPED_FINAL_FAILURE`) -4. Falls nötig: M5-Pfad bis `PROPOSAL_READY` durchlaufen +4. Falls nötig: Pfad bis `PROPOSAL_READY` durchlaufen (inkl. KI-Aufruf) 5. Führenden `PROPOSAL_READY`-Versuch laden 6. Finalen Basis-Dateinamen bilden 7. Dubletten-Suffix im Zielordner bestimmen -8. Zielkopie schreiben (temporäre Datei + finaler Move/Rename) -9. Neuen Versuch für Enderfolg oder technischen Fehler historisieren -10. Dokument-Stammsatz konsistent fortschreiben +8. Zielkopie schreiben (temporäre Datei + finaler Move/Rename; bei Fehler: genau ein Sofort-Wiederholversuch) +9. Retry-Entscheidung ableiten +10. Neuen Versuch historisieren, Stammsatz konsistent fortschreiben ## Zielkopie-Semantik - Kopie zunächst in temporäre Zieldatei im Zielkontext - Finaler Move/Rename auf den geplanten Zieldateinamen - Quelldatei bleibt **immer unverändert** -- Kein Sofort-Wiederholversuch im selben Lauf -- Bei Persistenzfehler nach erfolgreicher Zielkopie: kein `SUCCESS` setzen, best-effort Rückbau der Zielkopie vorsehen, Ergebnis bleibt dokumentbezogener technischer Fehler +- Bei technischem Schreibfehler: genau ein Sofort-Wiederholversuch (nur Zielkopierpfad) +- Bei Persistenzfehler nach erfolgreicher Zielkopie: kein `SUCCESS` setzen, best-effort Rückbau der Zielkopie, Ergebnis bleibt dokumentbezogener technischer Fehler ## Fehlersemantik (aktiver Stand) -Technische Fehler bei Proposal-Quelllesung, Zielpfadbildung, Dublettenauflösung, -Zielkopie oder aktiver Persistenz nach Fingerprint-Ermittlung: -- → dokumentbezogener technischer Fehler -- → `FAILED_RETRYABLE`, Transientfehlerzähler +1 -- → kein Abbruch des Batch-Laufs für andere Dokumente -- → keine neue finale Fehlerkategorie +- Technische Fehler → `FAILED_RETRYABLE`, Transientfehlerzähler +1 +- Bei Erreichen von `max.retries.transient` → `FAILED_FINAL` +- Kein Abbruch des Batch-Laufs für andere Dokumente +- Keine neue finale Fehlerkategorie +- Vor-Fingerprint-Fehler werden **nicht** als SQLite-Versuch historisiert -## Persistenzerweiterung (aktiver Stand) +## Persistenz (aktiver Stand) -**Dokument-Stammsatz** erhält zusätzlich: -- letzten Zielpfad -- letzten Zieldateinamen +Zwei-Ebenen-Modell bleibt unverändert – keine dritte Wahrheitsquelle. -**Versuchshistorie** erhält zusätzlich: +**Dokument-Stammsatz** enthält u.a.: +- letzten Zielpfad, letzten Zieldateinamen +- Inhaltsfehler- und Transientfehlerzähler +- Gesamtstatus + +**Versuchshistorie** enthält u.a.: - finalen Zieldateinamen +- Fehlerklasse, Fehlermeldung, Retryable-Flag **Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben. -Enderfolg und technische Fehler des aktiven Stands werden als **zusätzliche neue Versuche** historisiert. +Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag. ## Naming-Regel (verbindlich für alle Arbeitspakete) In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder @@ -236,10 +295,11 @@ Verbindlich zweckmäßige Parameter: - `api.baseUrl` – KI-Basis-URL - `api.model` – Modellname - `api.timeoutSeconds` – Timeout -- `max.retries.transient` – maximale transiente Wiederholversuche +- `max.retries.transient` – max. historisierte transiente Fehlversuche pro Fingerprint (**Integer >= 1**, `0` ist ungültig) - `max.pages` – Seitenlimit - `max.text.characters` – maximale Zeichenzahl für KI-Eingabe - `prompt.template.file` – externe Prompt-Datei +- `log.ai.sensitive` – sensible KI-Logausgabe freischalten (Boolean, Default: `false`) - `runtime.lock.file` – Lock-Datei (optional) - `log.directory` – Log-Verzeichnis (optional) - `api.key` – API-Key (Umgebungsvariable hat Vorrang) @@ -254,6 +314,7 @@ Verbindlich zweckmäßige Parameter: - keine Architekturbrüche - keine neuen Bibliotheken oder Frameworks ohne klare Notwendigkeit und Begründung - keine stillen Änderungen an Provider-Bindung oder Architekturprinzipien -- kein Sofort-Wiederholversuch der Zielkopie im selben Lauf -- kein Logging-Feinschliff des Endstands +- kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads - keine Reporting- oder Statistikfunktionen +- keine neue dritte Persistenz-Wahrheitsquelle für Retry-Entscheidungen +- kein M8-Gesamtfeinschliff oder großflächiges Refactoring