# CLAUDE.md ## Zweck Dieses Repository implementiert einen lokal gestarteten **PDF-Umbenenner mit KI**. Das Programm liest bereits OCR-verarbeitete, durchsuchbare PDF-Dateien aus einem Quellordner, ermittelt daraus einen normierten Dateinamen und legt **eine Kopie** der Datei im Zielordner ab. Die Quelldatei bleibt unverändert. ## Autoritative Dokumente @docs/specs/technik-und-architektur.md @docs/specs/fachliche-anforderungen.md @docs/specs/meilensteine.md Für die Umsetzung ist zusätzlich immer das aktuell aktive Arbeitspaket unter `docs/workpackages/` maßgeblich. Nicht raten, wenn Dokumente fehlen, unklar sind oder sich widersprechen. ## Priorisierung der Regeln Die Dokumente haben folgende feste Bedeutung: - `docs/specs/technik-und-architektur.md` = verbindliche technische Zielarchitektur - `docs/specs/fachliche-anforderungen.md` = verbindliche fachliche Regeln - `docs/specs/meilensteine.md` = zulässiger Funktionsumfang pro Meilenstein - `docs/workpackages/...` = verbindlicher Scope, Reihenfolge und Inhalt des aktuell bearbeiteten Arbeitspakets Bei Konflikten gilt folgende Priorität: 1. **Technik- und Architektur-Dokument** Verbindliche technische Zielarchitektur. Architekturbrüche sind unzulässig. 2. **Fachliche Anforderungen** Verbindliche fachliche Regeln und fachliches Zielverhalten. 3. **Meilensteine** Begrenzen den zulässigen Funktionsumfang auf den aktuellen Entwicklungsstand. 4. **Arbeitspakete** Definieren den konkret erlaubten Umsetzungsumfang des aktuellen Schritts. Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und keine stillen Annahmen treffen. ## Unverrückbare Technikvorgaben - Java 21 - Maven Multi-Module - ausführbares Standalone-JAR - Start über Windows Task Scheduler - kein Webserver - kein Applikationsserver - keine Dauerlauf-Anwendung - kein interner Scheduler - Log4j2 für Logging - SQLite als lokaler Persistenzspeicher - OpenAI-kompatible HTTP-Schnittstelle für KI-Zugriff - API-Provider, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung ## Verbindliche Modulstruktur - `pdf-umbenenner-domain` - `pdf-umbenenner-application` - `pdf-umbenenner-adapter-in-cli` - `pdf-umbenenner-adapter-out` - `pdf-umbenenner-bootstrap` ## Architekturregeln - Strikte **hexagonale Architektur / Ports and Adapters** - Abhängigkeiten zeigen immer **nach innen** - Domain kennt **keine** Infrastruktur, keine Datenbank, kein Dateisystem und keine HTTP-Kommunikation - Application orchestriert Use Cases und enthält keine technischen Implementierungsdetails - Externe Zugriffe erfolgen ausschließlich über **Ports** - Konkrete technische Implementierungen sind **Adapter** - Adapter dürfen nicht direkt voneinander abhängen - Keine Vermischung von Dateisystem, PDF-Auslese, SQLite, KI-HTTP, Konfiguration, Logging, Benennungslogik und Retry-Entscheidungen - Logging ist technische Infrastruktur, kein fachlicher Port - Port-Verträge enthalten weder `Path`/`File` noch NIO- oder JDBC-Typen ## Globale fachliche Leitplanken - Zielformat: `YYYY-MM-DD - Titel.pdf` - Bei Namenskollisionen: `YYYY-MM-DD - Titel(1).pdf`, `YYYY-MM-DD - Titel(2).pdf`, ... - Die **20 Zeichen** gelten nur für den **Basistitel**; das Dubletten-Suffix zählt nicht mit - Das Dubletten-Suffix wird unmittelbar vor `.pdf` angehängt - Titel sind **deutsch**, verständlich, eindeutig und enthalten keine Sonderzeichen außer Leerzeichen - Eigennamen bleiben unverändert - Datumsermittlung mit Priorität aus den fachlichen Anforderungen; wenn kein belastbares Datum eindeutig ableitbar ist, ist das **aktuelle Datum** als Fallback erlaubt - Mehrdeutige Dokumente liefern **kein** unsicheres Ergebnis, sondern einen Fehler - Erfolgreich verarbeitete Dateien werden nicht erneut verarbeitet - Retryable fehlgeschlagene Dateien dürfen in späteren Läufen erneut verarbeitet werden - Final fehlgeschlagene Dateien werden in späteren Läufen übersprungen - Identifikation erfolgt **nicht** über Dateinamen - Quelldateien werden **nie** überschrieben, verändert, verschoben oder gelöscht ## Aktiver Implementierungsstand M1 bis M7 sind vollständig abgeschlossen. Der aktive Stand ist der **Abschlussmeilenstein**: Qualitätssicherung, Feinschliff und vollständige Entwicklungsfreigabe des Gesamtstands. ### Baseline aus M7 - Vollständige laufübergreifende Retry-Logik (deterministisch + transient) - Technischer Sofort-Wiederholversuch für Zielkopierfehler - Finalisierung ausgeschöpfter Retry-Rahmen zu `FAILED_FINAL` - Vollständige Skip-Semantik (`SUCCESS`, `FAILED_FINAL`) - Logging-Mindestumfang vollständig angebunden - Sensibilitätsregel für KI-Inhalte im Logging - Finale Exit-Code-Semantik und vervollständigte Startvalidierung ### Ziel des aktiven Stands M8 schließt **ausschließlich nachweisbare Restlücken** des aus M1–M7 entstandenen Gesamtstands: - Architekturgrenzen und code-nahe Dokumentation finalisieren - Status-, Persistenz- und Zielzustandskonsistenz bereinigen - Betreiberrelevante Logging-, Fehlertext- und Startvalidierungsrückmeldungen schärfen - Konfigurationsbeispiele, Prompt-Bezug und Betriebsdokumentation konsolidieren - Deterministische End-to-End-Testbasis bereitstellen - Regressionstests für Kernregeln vervollständigen - Kritische Coverage- und Mutationslücken schließen - Integrierte Gesamtprüfung mit Befundliste durchführen - Nachgewiesene Release-Blocker gezielt beheben - Finale Gesamtprüfung und Freigabedokumentation erstellen ## Statussemantik | Status | Bedeutung | |---|---| | `READY_FOR_AI` | Verarbeitbar, KI-Pfad noch nicht durchlaufen | | `FAILED_RETRYABLE` | Verarbeitbar, transient fehlgeschlagen | | `PROPOSAL_READY` | Eingangszustand für Dateinamensbildung und Zielkopie | | `SUCCESS` | Terminaler Enderfolg – nur nach Zielkopie und konsistenter Persistenz zulässig | | `FAILED_FINAL` | Terminal, wird nicht erneut fachlich verarbeitet | | `SKIPPED_ALREADY_PROCESSED` | Historisierter Skip für SUCCESS-Dokumente | | `SKIPPED_FINAL_FAILURE` | Historisierter Skip für FAILED_FINAL-Dokumente | ### SUCCESS-Bedingung (verbindlich) `SUCCESS` darf erst gesetzt werden, wenn: 1. die Zielkopie erfolgreich geschrieben wurde, 2. der finale Zieldateiname bestimmt ist, 3. die Persistenz konsistent fortgeschrieben wurde. ### Führende Quelle des Benennungsvorschlags (verbindlich) - Die führende Quelle für Datum, Datumsquelle, validierten Titel und Reasoning ist der **neueste Versuchshistorieneintrag mit Status `PROPOSAL_READY`**. - Kein Rekonstruieren aus dem Dokument-Stammsatz. - Kein neuer KI-Aufruf, wenn bereits ein nutzbarer `PROPOSAL_READY`-Versuch vorliegt. - Status `PROPOSAL_READY` ohne lesbaren konsistenten Proposal-Versuch = dokumentbezogener technischer Fehler. - 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: 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; 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** - 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 → `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 ## Persistenz (aktiver Stand) Zwei-Ebenen-Modell bleibt unverändert – keine dritte Wahrheitsquelle. **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. 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 Arbeitspaket-Bezeichner erscheinen: - Verboten: `M1`, `M2`, `M3`, `M4`, `M5`, `M6`, `M7`, `M8` - Verboten: `AP-001`, `AP-002`, … `AP-00x` Stattdessen werden **zeitlose technische Bezeichnungen** verwendet. Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen berührt werden, sind zu ersetzen. ## Arbeitsweise - Arbeite immer nur im **explizit aktiven Meilenstein** und im **explizit aktiven Arbeitspaket** - **Kein Vorgriff** auf spätere Meilensteine oder Arbeitspakete - Änderungen klein, fokussiert und architekturtreu halten - Keine unnötigen Umbenennungen, keine großflächigen Refactorings ohne Not - Vor Änderungen zuerst die betroffenen Dateien und Abhängigkeiten verstehen - **Keine Annahmen über Dateipfade.** Typen und Klassen werden per Suche nach Typname gefunden, nicht über vermutete Pfade. - Keine Vermutungen: Bei echter Unklarheit oder Dokumentkonflikten knapp nachfragen oder den Konflikt benennen ## Definition of Done pro Arbeitspaket Ein Arbeitspaket ist erst fertig, wenn: - der Zielumfang des aktuellen Arbeitspakets vollständig umgesetzt ist - der Stand konsistent, fehlerfrei und buildbar ist - Implementierung, Konfiguration, JavaDoc und Tests ergänzt sind, **soweit für den Stand sinnvoll** - keine Inhalte späterer Meilensteine vorweggenommen wurden - der Zwischenstand in sich geschlossen und übergabefähig ist ## Pflicht-Output-Format nach jedem Arbeitspaket ``` - Scope erfüllt: ja/nein - Geänderte Dateien: - - ... - Build-Kommando: - Build-Status: ERFOLGREICH / FEHLGESCHLAGEN - Offene Punkte: keine / - Risiken: keine / ``` ## Qualitäts- und Prüfreihenfolge - Nur den für das aktuelle Arbeitspaket nötigen Scope ändern - Nach Änderungen den kleinsten sinnvollen Build-/Test-Umfang ausführen - Build-Validierung vom Parent-Root: `.\mvnw.cmd clean verify -pl pdf-umbenenner-domain,pdf-umbenenner-application,pdf-umbenenner-adapter-out,pdf-umbenenner-adapter-in-cli,pdf-umbenenner-bootstrap --also-make` - M8 hat 10 Arbeitspakete (AP-001 bis AP-010) – Start mit `-EndAp 10` - Schlägt der Build fehl: Fehler beheben, erneut bauen, erst dann weiter - Vor Abschluss sicherstellen, dass der relevante Maven-Reactor-Stand fehlerfrei ist - Fehler nicht kaschieren; Ursachen sauber beheben oder offen benennen ## Wichtige Betriebsregeln - Ungültige Startkonfiguration verhindert den Verarbeitungslauf und führt zu Exit-Code `1` - Run-Lock verhindert parallele Instanzen; wenn bereits eine Instanz läuft, beendet sich die neue Instanz sofort - Exit-Code `0`: Lauf technisch ordnungsgemäß ausgeführt, auch wenn einzelne Dateien fachlich oder transient fehlgeschlagen sind - Exit-Code `1`: harter Start-/Bootstrap-Fehler - Umgebungsvariable hat Vorrang vor Properties beim API-Key - Dokumentbezogene Fehler führen **nicht** zu Exit-Code `1` ## Konfigurationsparameter Verbindlich zweckmäßige Parameter: - `source.folder` – Quellordner - `target.folder` – Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich) - `sqlite.file` – SQLite-Datenbankdatei - `api.baseUrl` – KI-Basis-URL - `api.model` – Modellname - `api.timeoutSeconds` – Timeout - `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) ## Nicht-Ziele / Verbote - kein Web-UI - keine REST-API zur Bedienung - keine OCR innerhalb der Java-Anwendung - keine DMS-Funktionalität - kein menschlicher Review-Workflow in der Anwendung - keine interne Scheduler-Logik - 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 außerhalb des Zielkopierpfads - keine Reporting- oder Statistikfunktionen - keine neue dritte Persistenz-Wahrheitsquelle für Retry-Entscheidungen - keine neue Fachfunktionalität jenseits des definierten Zielbilds - kein großflächiges Refactoring ohne nachweisbaren M8-Defektbezug - keine Metrik-Kosmetik (willkürliche Ausschlüsse, nicht belastbare Testumgehungen) - keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug - kein gleichzeitiger unbeschränkter Review und unbegrenzte Behebung in einem AP ## M8-spezifische Arbeitsregeln **Review vor Behebung:** Gesamtprüfung (AP-008), Blockerbehebung (AP-009) und Freigabe (AP-010) sind getrennte Arbeitsschritte. Ein AP darf nicht gleichzeitig alles prüfen und alles beheben. **Nur nachweisbare Restlücken:** Änderungen müssen auf konkrete, belegbare Befunde aus dem realen Projektstand zurückführbar sein. **Rückwärtsverträglichkeit:** M4–M7-Datenbestände müssen weiterhin lesbar, fortschreibbar und korrekt interpretierbar bleiben. **Befunddatei im Repository:** AP-008 erzeugt eine im Repository verbleibende Befundliste mit Klassifizierung in Release-Blocker und nicht blockierende Punkte. **Freigabenachweis:** AP-010 erzeugt eine nachvollziehbare Entwicklungsfreigabe-Dokumentation im Repository, gestützt auf tatsächlich ausgeführte Prüfungen.