1
0

Vorbereitungen zu V1.1

This commit is contained in:
2026-04-08 22:21:32 +02:00
parent 559b051ab3
commit 9c2a205137
3 changed files with 556 additions and 146 deletions

148
CLAUDE.md
View File

@@ -6,7 +6,6 @@ Dieses Repository implementiert einen lokal gestarteten **PDF-Umbenenner mit KI*
## Autoritative Dokumente ## Autoritative Dokumente
@docs/specs/technik-und-architektur.md @docs/specs/technik-und-architektur.md
@docs/specs/fachliche-anforderungen.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. 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. Nicht raten, wenn Dokumente fehlen, unklar sind oder sich widersprechen.
@@ -16,7 +15,6 @@ Die Dokumente haben folgende feste Bedeutung:
- `docs/specs/technik-und-architektur.md` = verbindliche technische Zielarchitektur - `docs/specs/technik-und-architektur.md` = verbindliche technische Zielarchitektur
- `docs/specs/fachliche-anforderungen.md` = verbindliche fachliche Regeln - `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 - `docs/workpackages/...` = verbindlicher Scope, Reihenfolge und Inhalt des aktuell bearbeiteten Arbeitspakets
Bei Konflikten gilt folgende Priorität: Bei Konflikten gilt folgende Priorität:
@@ -27,10 +25,7 @@ Bei Konflikten gilt folgende Priorität:
2. **Fachliche Anforderungen** 2. **Fachliche Anforderungen**
Verbindliche fachliche Regeln und fachliches Zielverhalten. Verbindliche fachliche Regeln und fachliches Zielverhalten.
3. **Meilensteine** 3. **Arbeitspakete**
Begrenzen den zulässigen Funktionsumfang auf den aktuellen Entwicklungsstand.
4. **Arbeitspakete**
Definieren den konkret erlaubten Umsetzungsumfang des aktuellen Schritts. Definieren den konkret erlaubten Umsetzungsumfang des aktuellen Schritts.
Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und keine stillen Annahmen treffen. Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und keine stillen Annahmen treffen.
@@ -46,8 +41,11 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
- kein interner Scheduler - kein interner Scheduler
- Log4j2 für Logging - Log4j2 für Logging
- SQLite als lokaler Persistenzspeicher - SQLite als lokaler Persistenzspeicher
- OpenAI-kompatible HTTP-Schnittstelle für KI-Zugriff - KI-Anbindung über genau **eine** der beiden unterstützten Provider-Familien:
- API-Provider, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung - **OpenAI-kompatible HTTP-Schnittstelle** (Chat-Completions-Stil)
- **native Anthropic Messages API** (Claude-Modelle)
- Pro Lauf ist genau ein Provider aktiv. Kein Fallback, keine Parallelnutzung.
- Konkrete Provider-Familie, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung.
## Verbindliche Modulstruktur ## Verbindliche Modulstruktur
- `pdf-umbenenner-domain` - `pdf-umbenenner-domain`
@@ -67,6 +65,9 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
- Keine Vermischung von Dateisystem, PDF-Auslese, SQLite, KI-HTTP, Konfiguration, Logging, Benennungslogik und Retry-Entscheidungen - Keine Vermischung von Dateisystem, PDF-Auslese, SQLite, KI-HTTP, Konfiguration, Logging, Benennungslogik und Retry-Entscheidungen
- Logging ist technische Infrastruktur, kein fachlicher Port - Logging ist technische Infrastruktur, kein fachlicher Port
- Port-Verträge enthalten weder `Path`/`File` noch NIO- oder JDBC-Typen - Port-Verträge enthalten weder `Path`/`File` noch NIO- oder JDBC-Typen
- Der `AiNamingPort` bleibt provider-neutral; provider-spezifische Typen, Header, URLs und Antwortstrukturen leben ausschließlich in der jeweiligen Adapter-Out-Implementierung
- Es gibt keine gemeinsame „abstrakte KI-Adapter"-Zwischenschicht zwischen Port und konkreten Adaptern
- Die Bootstrap-Schicht wählt die **eine** aktive `AiNamingPort`-Implementierung anhand der Konfiguration aus
## Globale fachliche Leitplanken ## Globale fachliche Leitplanken
- Zielformat: `YYYY-MM-DD - Titel.pdf` - Zielformat: `YYYY-MM-DD - Titel.pdf`
@@ -85,30 +86,18 @@ Wenn Dokumente fehlen, unklar sind oder sich widersprechen, nicht raten und kein
## Aktiver Implementierungsstand ## Aktiver Implementierungsstand
M1 bis M7 sind vollständig abgeschlossen. Der aktive Stand ist der **Abschlussmeilenstein**: Die fachliche und technische Basis ist vollständig umgesetzt, dokumentiert, getestet (inkl. PIT-Mutationstests, Smoke-Tests, End-to-End-Tests) und freigegeben.
Qualitätssicherung, Feinschliff und vollständige Entwicklungsfreigabe des Gesamtstands.
### Baseline aus M7 Der aktive Stand ist die Erweiterung **„Zusätzlicher KI-Provider Anthropic Claude über die native Messages API"**. Sie ist eine bewusst minimale Erweiterung des freigegebenen Basisstands.
- 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 ### Ziel der aktiven Erweiterung
M8 schließt **ausschließlich nachweisbare Restlücken** des aus M1M7 entstandenen Gesamtstands: - Der bestehende OpenAI-kompatible KI-Weg bleibt unverändert nutzbar.
- Architekturgrenzen und code-nahe Dokumentation finalisieren - Zusätzlich wird die **native Anthropic Messages API** als zweite, gleichwertig unterstützte Provider-Familie integriert.
- Status-, Persistenz- und Zielzustandskonsistenz bereinigen - Genau **ein** Provider ist pro Lauf aktiv ausschließlich über Konfiguration ausgewählt.
- Betreiberrelevante Logging-, Fehlertext- und Startvalidierungsrückmeldungen schärfen - **Kein** automatischer Fallback, **keine** Parallelnutzung, **keine** Profilverwaltung.
- Konfigurationsbeispiele, Prompt-Bezug und Betriebsdokumentation konsolidieren - Der fachliche KI-Vertrag (`NamingProposal` aus Application-/Domain-Sicht) bleibt unverändert.
- Deterministische End-to-End-Testbasis bereitstellen - Bestehende Properties-Dateien aus dem Vorgängerstand werden beim ersten Start kontrolliert in das neue Schema migriert; vorher wird automatisch eine `.bak`-Sicherung angelegt.
- Regressionstests für Kernregeln vervollständigen - Architekturgrenzen, Persistenzmodell, Statussemantik, Retry-Semantik, Exit-Code-Verhalten und Logging-Mindestumfang bleiben unverändert; sie werden ausschließlich um den Provider-Identifikator und die Provider-Auswahl ergänzt.
- 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 ## Statussemantik
@@ -136,7 +125,7 @@ M8 schließt **ausschließlich nachweisbare Restlücken** des aus M1M7 entsta
- Proposal-Versuch mit fachlich unbrauchbarem Titel oder Datum = inkonsistenter Persistenzzustand = 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. - Inkonsistente Proposal-Zustände werden **nicht stillschweigend geheilt**, sondern als technische Dokumentfehler behandelt.
## Retry-Semantik (aktiver Stand) ## Retry-Semantik
### Deterministische Inhaltsfehler ### Deterministische Inhaltsfehler
Deterministische Inhaltsfehler sind insbesondere: Deterministische Inhaltsfehler sind insbesondere:
@@ -154,7 +143,7 @@ Regel:
- Sie bleiben retryable bis der konfigurierte Grenzwert `max.retries.transient` erreicht ist. - Sie bleiben retryable bis der konfigurierte Grenzwert `max.retries.transient` erreicht ist.
- Der Fehlversuch, der den Grenzwert **erreicht**, finalisiert den Dokumentstatus zu `FAILED_FINAL`. - Der Fehlversuch, der den Grenzwert **erreicht**, finalisiert den Dokumentstatus zu `FAILED_FINAL`.
- `max.retries.transient` = **Integer >= 1**; der Wert `0` ist ungültige Startkonfiguration. - `max.retries.transient` = **Integer >= 1**; der Wert `0` ist ungültige Startkonfiguration.
- Beispiel: `max.retries.transient = 1` → erster transiente Fehlversuch finalisiert sofort. - Die Klassifikation gilt provider-unabhängig: Technische Fehler aus dem aktiven KI-Provider werden in dieselbe transiente Kategorie eingeordnet wie bisher. Der inaktive Provider wird in keiner Fehlersituation als Backup verwendet.
### Technischer Sofort-Wiederholversuch ### Technischer Sofort-Wiederholversuch
- **Genau ein** zusätzlicher technischer Schreibversuch innerhalb desselben Dokumentlaufs. - **Genau ein** zusätzlicher technischer Schreibversuch innerhalb desselben Dokumentlaufs.
@@ -168,10 +157,11 @@ Regel:
- `FAILED_FINAL` → in späteren Läufen `SKIPPED_FINAL_FAILURE` 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. - `FAILED_RETRYABLE`, `READY_FOR_AI`, `PROPOSAL_READY` → verarbeitbar.
## Logging-Mindestumfang (aktiver Stand) ## Logging-Mindestumfang
Folgende Informationen müssen nachvollziehbar geloggt werden: Folgende Informationen müssen nachvollziehbar geloggt werden:
- Laufstart mit Lauf-ID - Laufstart mit Lauf-ID
- aktiver KI-Provider für den Lauf
- Laufende - Laufende
- erkannte Quelldatei - erkannte Quelldatei
- Überspringen bereits erfolgreicher Dateien - Überspringen bereits erfolgreicher Dateien
@@ -190,13 +180,14 @@ Folgende Informationen müssen nachvollziehbar geloggt werden:
- Vollständiges KI-`reasoning`: 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. - Freischaltung nur über expliziten booleschen Konfigurationswert.
- Default: sicher / nicht loggen. - Default: sicher / nicht loggen.
- Die Sensibilitätsregel gilt provider-unabhängig.
## Verarbeitungsreihenfolge pro Dokument (aktiver Stand) ## Verarbeitungsreihenfolge pro Dokument
1. Fingerprint berechnen 1. Fingerprint berechnen
2. Dokument-Stammsatz laden 2. Dokument-Stammsatz laden
3. Terminale Skip-Fälle entscheiden (`SUCCESS``SKIPPED_ALREADY_PROCESSED`, `FAILED_FINAL``SKIPPED_FINAL_FAILURE`) 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) 4. Falls nötig: Pfad bis `PROPOSAL_READY` durchlaufen (inkl. KI-Aufruf über den aktiven Provider)
5. Führenden `PROPOSAL_READY`-Versuch laden 5. Führenden `PROPOSAL_READY`-Versuch laden
6. Finalen Basis-Dateinamen bilden 6. Finalen Basis-Dateinamen bilden
7. Dubletten-Suffix im Zielordner bestimmen 7. Dubletten-Suffix im Zielordner bestimmen
@@ -211,14 +202,15 @@ Folgende Informationen müssen nachvollziehbar geloggt werden:
- Bei technischem Schreibfehler: genau ein Sofort-Wiederholversuch (nur Zielkopierpfad) - 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 - Bei Persistenzfehler nach erfolgreicher Zielkopie: kein `SUCCESS` setzen, best-effort Rückbau der Zielkopie, Ergebnis bleibt dokumentbezogener technischer Fehler
## Fehlersemantik (aktiver Stand) ## Fehlersemantik
- Technische Fehler → `FAILED_RETRYABLE`, Transientfehlerzähler +1 - Technische Fehler → `FAILED_RETRYABLE`, Transientfehlerzähler +1
- Bei Erreichen von `max.retries.transient``FAILED_FINAL` - Bei Erreichen von `max.retries.transient``FAILED_FINAL`
- Kein Abbruch des Batch-Laufs für andere Dokumente - Kein Abbruch des Batch-Laufs für andere Dokumente
- Keine neue finale Fehlerkategorie - Keine neue finale Fehlerkategorie
- Vor-Fingerprint-Fehler werden **nicht** als SQLite-Versuch historisiert - Vor-Fingerprint-Fehler werden **nicht** als SQLite-Versuch historisiert
- Provider-spezifische Fehlerausprägungen (HTTP-Fehler, Auth-Fehler, Antwort-Schema-Fehler) werden im jeweiligen Adapter klassifiziert und auf die bestehenden Fehlerkategorien abgebildet. Es entstehen keine neuen Fehlerklassen.
## Persistenz (aktiver Stand) ## Persistenz
Zwei-Ebenen-Modell bleibt unverändert keine dritte Wahrheitsquelle. Zwei-Ebenen-Modell bleibt unverändert keine dritte Wahrheitsquelle.
@@ -230,35 +222,40 @@ Zwei-Ebenen-Modell bleibt unverändert keine dritte Wahrheitsquelle.
**Versuchshistorie** enthält u.a.: **Versuchshistorie** enthält u.a.:
- finalen Zieldateinamen - finalen Zieldateinamen
- Fehlerklasse, Fehlermeldung, Retryable-Flag - Fehlerklasse, Fehlermeldung, Retryable-Flag
- **Provider-Identifikator des aktiven KI-Providers für den Versuch**
**Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben. **Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben.
Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag. Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag.
**Rückwärtsverträglichkeit:** Bestehende Datenbestände bleiben lesbar, fortschreibbar und korrekt interpretierbar. Schema-Erweiterungen sind additiv mit definierten Defaultwerten für historische Versuche ohne Provider-Identifikator.
## Naming-Regel (verbindlich für alle Arbeitspakete) ## Naming-Regel (verbindlich für alle Arbeitspakete)
In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder
Arbeitspaket-Bezeichner erscheinen: Arbeitspaket-Bezeichner erscheinen:
- Verboten: `M1`, `M2`, `M3`, `M4`, `M5`, `M6`, `M7`, `M8` - Verboten: `M1`, `M2`, , `M8`
- Verboten: `AP-001`, `AP-002`, … `AP-00x` - Verboten: `AP-001`, `AP-002`, … `AP-00x`
- Verboten: Versionsbezeichner wie `V1.0`, `V1.1` in Code/JavaDoc
Stattdessen werden **zeitlose technische Bezeichnungen** verwendet. Stattdessen werden **zeitlose technische Bezeichnungen** verwendet.
Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen berührt werden, sind zu ersetzen. Bestehende Kommentare mit solchen Bezeichnern, die durch eigene Änderungen berührt werden, sind zu ersetzen.
## Arbeitsweise ## Arbeitsweise
- Arbeite immer nur im **explizit aktiven Meilenstein** und im **explizit aktiven Arbeitspaket** - Arbeite immer nur im **explizit aktiven Arbeitspaket**
- **Kein Vorgriff** auf spätere Meilensteine oder Arbeitspakete - **Kein Vorgriff** auf spätere Arbeitspakete
- Änderungen klein, fokussiert und architekturtreu halten - Änderungen klein, fokussiert und architekturtreu halten
- Keine unnötigen Umbenennungen, keine großflächigen Refactorings ohne Not - Keine unnötigen Umbenennungen, keine großflächigen Refactorings ohne Not
- Vor Änderungen zuerst die betroffenen Dateien und Abhängigkeiten verstehen - 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 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 - Keine Vermutungen: Bei echter Unklarheit oder Dokumentkonflikten knapp nachfragen oder den Konflikt benennen
- Keine stillen Änderungen am bestehenden OpenAI-kompatiblen KI-Weg
## Definition of Done pro Arbeitspaket ## Definition of Done pro Arbeitspaket
Ein Arbeitspaket ist erst fertig, wenn: Ein Arbeitspaket ist erst fertig, wenn:
- der Zielumfang des aktuellen Arbeitspakets vollständig umgesetzt ist - der Zielumfang des aktuellen Arbeitspakets vollständig umgesetzt ist
- der Stand konsistent, fehlerfrei und buildbar ist - der Stand konsistent, fehlerfrei und buildbar ist
- Implementierung, Konfiguration, JavaDoc und Tests ergänzt sind, **soweit für den Stand sinnvoll** - Implementierung, Konfiguration, JavaDoc und Tests ergänzt sind, **soweit für den Stand sinnvoll**
- keine Inhalte späterer Meilensteine vorweggenommen wurden - keine Inhalte späterer Arbeitspakete vorweggenommen wurden
- der Zwischenstand in sich geschlossen und übergabefähig ist - der Zwischenstand in sich geschlossen und übergabefähig ist
## Pflicht-Output-Format nach jedem Arbeitspaket ## Pflicht-Output-Format nach jedem Arbeitspaket
@@ -279,17 +276,17 @@ Ein Arbeitspaket ist erst fertig, wenn:
- Nach Änderungen den kleinsten sinnvollen Build-/Test-Umfang ausführen - Nach Änderungen den kleinsten sinnvollen Build-/Test-Umfang ausführen
- Build-Validierung vom Parent-Root: - 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` `.\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 - Schlägt der Build fehl: Fehler beheben, erneut bauen, erst dann weiter
- Vor Abschluss sicherstellen, dass der relevante Maven-Reactor-Stand fehlerfrei ist - Vor Abschluss sicherstellen, dass der relevante Maven-Reactor-Stand fehlerfrei ist
- Fehler nicht kaschieren; Ursachen sauber beheben oder offen benennen - Fehler nicht kaschieren; Ursachen sauber beheben oder offen benennen
## Wichtige Betriebsregeln ## Wichtige Betriebsregeln
- Ungültige Startkonfiguration verhindert den Verarbeitungslauf und führt zu Exit-Code `1` - Ungültige Startkonfiguration verhindert den Verarbeitungslauf und führt zu Exit-Code `1`
- Eine ungültige oder fehlende Provider-Auswahl ist eine ungültige Startkonfiguration
- Run-Lock verhindert parallele Instanzen; wenn bereits eine Instanz läuft, beendet sich die neue Instanz sofort - 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 `0`: Lauf technisch ordnungsgemäß ausgeführt, auch wenn einzelne Dateien fachlich oder transient fehlgeschlagen sind
- Exit-Code `1`: harter Start-/Bootstrap-Fehler - Exit-Code `1`: harter Start-/Bootstrap-Fehler
- Umgebungsvariable hat Vorrang vor Properties beim API-Key - API-Schlüssel: pro Provider eine eigene Umgebungsvariable, Vorrang vor Properties derselben Provider-Familie. Schlüssel verschiedener Provider werden niemals vermischt.
- Dokumentbezogene Fehler führen **nicht** zu Exit-Code `1` - Dokumentbezogene Fehler führen **nicht** zu Exit-Code `1`
## Konfigurationsparameter ## Konfigurationsparameter
@@ -297,9 +294,7 @@ Verbindlich zweckmäßige Parameter:
- `source.folder` Quellordner - `source.folder` Quellordner
- `target.folder` Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich) - `target.folder` Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich)
- `sqlite.file` SQLite-Datenbankdatei - `sqlite.file` SQLite-Datenbankdatei
- `api.baseUrl` KI-Basis-URL - `ai.provider.active` aktiver KI-Provider (Pflicht; zulässige Werte sind die Bezeichner der unterstützten Provider-Familien)
- `api.model` Modellname
- `api.timeoutSeconds` Timeout
- `max.retries.transient` max. historisierte transiente Fehlversuche pro Fingerprint (**Integer >= 1**, `0` ist ungültig) - `max.retries.transient` max. historisierte transiente Fehlversuche pro Fingerprint (**Integer >= 1**, `0` ist ungültig)
- `max.pages` Seitenlimit - `max.pages` Seitenlimit
- `max.text.characters` maximale Zeichenzahl für KI-Eingabe - `max.text.characters` maximale Zeichenzahl für KI-Eingabe
@@ -307,7 +302,43 @@ Verbindlich zweckmäßige Parameter:
- `log.ai.sensitive` sensible KI-Logausgabe freischalten (Boolean, Default: `false`) - `log.ai.sensitive` sensible KI-Logausgabe freischalten (Boolean, Default: `false`)
- `runtime.lock.file` Lock-Datei (optional) - `runtime.lock.file` Lock-Datei (optional)
- `log.directory` Log-Verzeichnis (optional) - `log.directory` Log-Verzeichnis (optional)
- `api.key` API-Key (Umgebungsvariable hat Vorrang)
Pro Provider-Familie existiert ein eigener Parameter-Namensraum mit zweckmäßig:
- Modellname
- API-Schlüssel (Umgebungsvariable hat Vorrang)
- Timeout
- Basis-URL (optional, wo betrieblich sinnvoll)
Konkretes Schema (zweckmäßig):
```properties
ai.provider.active=openai-compatible
ai.provider.openai-compatible.baseUrl=...
ai.provider.openai-compatible.model=...
ai.provider.openai-compatible.timeoutSeconds=...
ai.provider.openai-compatible.apiKey=...
ai.provider.claude.baseUrl=...
ai.provider.claude.model=...
ai.provider.claude.timeoutSeconds=...
ai.provider.claude.apiKey=...
```
### Migration historischer Konfiguration
Bestehende Properties-Dateien des Vorgängerstands (mit flachen Schlüsseln wie `api.baseUrl`, `api.model`, `api.timeoutSeconds`, `api.key`) werden beim ersten Start erkannt und kontrolliert in das neue Schema überführt.
Verbindlicher Ablauf:
1. Legacy-Form erkennen
2. **`.bak`-Sicherung** der Originaldatei anlegen
3. Inhalt in das neue Schema überführen
- Legacy-Werte landen im Namensraum **`openai-compatible`**
- `ai.provider.active` wird auf `openai-compatible` gesetzt
4. Datei in-place schreiben
5. Datei erneut laden und validieren
6. Erst danach den normalen Lauf fortsetzen
Alte und neue Struktur sind **kein** dauerhaft gleichrangiges Endformat.
## Nicht-Ziele / Verbote ## Nicht-Ziele / Verbote
- kein Web-UI - kein Web-UI
@@ -318,24 +349,15 @@ Verbindlich zweckmäßige Parameter:
- keine interne Scheduler-Logik - keine interne Scheduler-Logik
- keine Architekturbrüche - keine Architekturbrüche
- keine neuen Bibliotheken oder Frameworks ohne klare Notwendigkeit und Begründung - keine neuen Bibliotheken oder Frameworks ohne klare Notwendigkeit und Begründung
- keine stillen Änderungen an Provider-Bindung oder Architekturprinzipien - **keine** automatische Fallback-Umschaltung zwischen KI-Providern
- **keine** parallele Nutzung mehrerer KI-Provider in einem Lauf
- **keine** Profilverwaltung mit mehreren Konfigurationen je Provider-Familie
- **keine** Provider-Familien jenseits der explizit unterstützten (OpenAI-kompatibel, Anthropic Messages API)
- keine stillen Änderungen am bestehenden OpenAI-kompatiblen KI-Weg
- kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads - kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads
- keine Reporting- oder Statistikfunktionen - keine Reporting- oder Statistikfunktionen
- keine neue dritte Persistenz-Wahrheitsquelle für Retry-Entscheidungen - keine neue dritte Persistenz-Wahrheitsquelle für Retry-Entscheidungen
- keine neue Fachfunktionalität jenseits des definierten Zielbilds - keine neue Fachfunktionalität jenseits des definierten Zielbilds
- kein großflächiges Refactoring ohne nachweisbaren M8-Defektbezug - kein großflächiges Refactoring ohne nachweisbaren Defektbezug
- keine Metrik-Kosmetik (willkürliche Ausschlüsse, nicht belastbare Testumgehungen)
- keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug - keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug
- kein gleichzeitiger unbeschränkter Review und unbegrenzte Behebung in einem AP - keine Vermischung von API-Schlüsseln verschiedener Provider-Familien
## 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:** M4M7-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.

View File

@@ -1,5 +1,11 @@
# Technik und Architektur PDF-Umbenenner mit KI # Technik und Architektur PDF-Umbenenner mit KI
> **Versionshinweis v2**
> Diese Fassung erweitert die KI-Anbindung um einen zweiten, gleichwertig unterstützten Provider.
> Geändert wurden ausschließlich die Abschnitte, die für die Mehrprovider-Fähigkeit erforderlich sind:
> Technologiestack (Abschnitt 5), KI-Integration (Abschnitt 11), Konfiguration (Abschnitt 14) sowie die Abschlussbewertung (Abschnitt 19).
> Alle übrigen Abschnitte bleiben inhaltlich unverändert.
## 1. Ziel und Geltungsbereich ## 1. Ziel und Geltungsbereich
Dieses Dokument beschreibt die verbindliche technische Zielarchitektur für den **PDF-Umbenenner**. Dieses Dokument beschreibt die verbindliche technische Zielarchitektur für den **PDF-Umbenenner**.
@@ -130,7 +136,7 @@ Enthält technische Implementierungen der Outbound-Ports, insbesondere:
- Dateisystem - Dateisystem
- PDFBox - PDFBox
- SQLite - SQLite
- OpenAI-kompatibler HTTP-Client - KI-HTTP-Clients (eine Implementierung je unterstütztem Provider, siehe Abschnitt 11)
- Properties-/Umgebungs-Konfiguration - Properties-/Umgebungs-Konfiguration
- Run-Lock - Run-Lock
- Clock - Clock
@@ -139,7 +145,8 @@ Enthält technische Implementierungen der Outbound-Ports, insbesondere:
Verantwortlich für: Verantwortlich für:
- Laden und Validieren der Konfiguration - Laden und Validieren der Konfiguration
- Erzeugen des Objektgraphen - Erzeugen des Objektgraphen
- Verdrahtung aller Adapter und Ports - Auswahl und Verdrahtung der **einen** aktiven KI-Provider-Implementierung
- Verdrahtung aller übrigen Adapter und Ports
- Start des CLI-Adapters - Start des CLI-Adapters
- Setzen des Exit-Codes - Setzen des Exit-Codes
@@ -162,13 +169,18 @@ Verbindlich eingesetzt werden:
- **SQLite** als lokaler Persistenzspeicher - **SQLite** als lokaler Persistenzspeicher
- **SQLite JDBC-Treiber** - **SQLite JDBC-Treiber**
- **Log4j2** für Logging - **Log4j2** für Logging
- **OpenAI-kompatible HTTP-API** für KI-Zugriff
- **Java HTTP Client** oder technisch gleichwertige Standard-HTTP-Komponente - **Java HTTP Client** oder technisch gleichwertige Standard-HTTP-Komponente
- **JSON-Bibliothek** für robuste JSON-Serialisierung und -Validierung - **JSON-Bibliothek** für robuste JSON-Serialisierung und -Validierung
Für die KI-Anbindung werden **zwei gleichwertig unterstützte Provider-Familien** technisch zugelassen:
- **OpenAI-kompatible HTTP-Schnittstelle** (Chat-Completions-Stil)
- **native Anthropic Messages API** für Claude-Modelle
Pro Lauf ist genau **eine** dieser Provider-Implementierungen aktiv. Die Auswahl erfolgt ausschließlich über Konfiguration (siehe Abschnitt 14).
Nicht verbindlich festgelegt sind: Nicht verbindlich festgelegt sind:
- konkreter KI-Provider - konkreter KI-Provider innerhalb einer Provider-Familie
- konkrete KI-Basis-URL - konkrete Basis-URL
- konkreter Modellname - konkreter Modellname
Diese drei Punkte sind **reine Konfiguration** und ausdrücklich **keine Architekturentscheidung**. Diese drei Punkte sind **reine Konfiguration** und ausdrücklich **keine Architekturentscheidung**.
@@ -196,6 +208,8 @@ Verbindlich zweckmäßige Outbound-Ports:
- `RunLockPort` - `RunLockPort`
- `ClockPort` - `ClockPort`
Der `AiNamingPort` bleibt **provider-neutral**. Er kennt weder OpenAI- noch Anthropic-spezifische Typen, Header, URLs oder Antwortformate. Provider-spezifische Details (Endpunkt, Authentifizierung, Request-/Response-Format) leben ausschließlich in den jeweiligen Adapter-Out-Implementierungen.
### 6.3 Logging ### 6.3 Logging
Logging ist **kein fachlicher Port**. Logging ist technische Infrastruktur. Logging ist **kein fachlicher Port**. Logging ist technische Infrastruktur.
@@ -234,6 +248,8 @@ Die Verarbeitung einer einzelnen Datei erfolgt in dieser Reihenfolge:
16. temporäre Zieldatei final verschieben/umbenennen 16. temporäre Zieldatei final verschieben/umbenennen
17. Erfolg und Versuchshistorie persistent speichern 17. Erfolg und Versuchshistorie persistent speichern
Die Verarbeitungsschritte sind **provider-unabhängig**. Welcher konkrete KI-Adapter Schritt 9 ausführt, ist außerhalb der Application nicht sichtbar.
### 7.3 Erfolgskriterium ### 7.3 Erfolgskriterium
Ein Dokument gilt genau dann als erfolgreich verarbeitet, wenn: Ein Dokument gilt genau dann als erfolgreich verarbeitet, wenn:
1. brauchbarer PDF-Text vorliegt, 1. brauchbarer PDF-Text vorliegt,
@@ -288,63 +304,15 @@ Beispiele:
- `2026-03-31 - Stromabrechnung(1).pdf` - `2026-03-31 - Stromabrechnung(1).pdf`
- `2026-03-31 - Stromabrechnung(2).pdf` - `2026-03-31 - Stromabrechnung(2).pdf`
### 8.6 Windows-Kompatibilität ---
Die Anwendung stellt zusätzlich sicher, dass der Zielname für Windows zulässig ist.
Unzulässige Zeichen sind technisch zu entfernen oder kontrolliert zu ersetzen. ## 9. Retry- und Fehlersemantik
> Inhaltlich unverändert gegenüber der Vorgängerfassung. Nur die Erkenntnis, dass technische KI-Fehler unabhängig vom konkreten Provider als transient klassifiziert werden, gilt jetzt für **beide** Provider-Familien gleichermaßen.
--- ---
## 9. Fehlerklassifikation und Retry-Regeln ## 10. Identifikation und Reproduzierbarkeit
### 9.1 Grundsatz
Nur **retryable** Fehler dürfen in späteren Läufen erneut verarbeitet werden.
**Finale** Fehler werden in späteren Läufen übersprungen.
### 9.2 Deterministische Inhaltsfehler
Deterministische Inhaltsfehler sind insbesondere:
- kein brauchbarer PDF-Text
- Seitenlimit überschritten
- Dokument inhaltlich mehrdeutig
- kein brauchbarer Titel
- generischer oder unzulässiger Titel
- von der KI gelieferter Datumswert ist vorhanden, aber unbrauchbar oder nicht interpretierbar
Regel:
- genau **1 Retry** in einem späteren Scheduler-Lauf
- danach **finaler Fehler**
### 9.3 Transiente technische Fehler
Transiente technische Fehler sind insbesondere:
- KI nicht erreichbar
- HTTP-Timeout
- temporäre IO-Fehler
- temporäre SQLite-Sperre
- ungültiges oder nicht parsebares KI-JSON
- sonstige vorübergehende technische Infrastrukturfehler
Regel:
- Retry in späteren Läufen bis zum konfigurierten Maximalwert
### 9.4 Technischer Sofort-Wiederholversuch
Zusätzlich zulässig ist genau **ein technischer Sofort-Wiederholversuch** innerhalb desselben Laufs für den Zielkopiervorgang, wenn das Schreiben der Zieldatei fehlschlägt.
Dieser Mechanismus ist **kein fachlicher Retry** und wird getrennt vom laufübergreifenden Retry-Modell behandelt.
### 9.5 Statusmodell
Verbindlich zweckmäßige Statuswerte:
- `SUCCESS`
- `FAILED_RETRYABLE`
- `FAILED_FINAL`
- `SKIPPED_ALREADY_PROCESSED`
- `SKIPPED_FINAL_FAILURE`
Ein technischer Zwischenstatus `PROCESSING` ist zusätzlich zulässig und sinnvoll.
---
## 10. Idempotenz und Identifikation
### 10.1 Identifikation ### 10.1 Identifikation
Die Identifikation eines Dokuments erfolgt **nicht** über den Dateinamen. Die Identifikation eines Dokuments erfolgt **nicht** über den Dateinamen.
@@ -362,35 +330,63 @@ Daraus folgt:
Reproduzierbarkeit bedeutet technisch: Reproduzierbarkeit bedeutet technisch:
- nach einem erfolgreichen Lauf bleibt das gespeicherte Ergebnis stabil - nach einem erfolgreichen Lauf bleibt das gespeicherte Ergebnis stabil
- erfolgreiche Dateien werden nicht erneut KI-basiert bewertet - erfolgreiche Dateien werden nicht erneut KI-basiert bewertet
- KI-Aufrufe werden, soweit die API es zulässt, mit möglichst geringer Varianz konfiguriert - KI-Aufrufe werden, soweit die jeweilige API es zulässt, mit möglichst geringer Varianz konfiguriert
- Prompt-Version und Modellname werden persistiert - Prompt-Version, Modellname **und der Name des aktiven Providers** werden persistiert
--- ---
## 11. KI-Integration ## 11. KI-Integration
### 11.1 Schnittstelle ### 11.1 Unterstützte Provider-Familien
Die KI wird ausschließlich über eine **OpenAI-kompatible HTTP-Schnittstelle** angebunden. Die KI wird über genau **eine** der folgenden Provider-Familien angebunden:
Basis-URL, Modellname und API-Key sind reine Konfiguration. 1. **OpenAI-kompatible HTTP-Schnittstelle**
Chat-Completions-Stil. Geeignet für OpenAI selbst und für jeden API-kompatiblen Drittanbieter.
2. **Native Anthropic Messages API**
Die offizielle Anthropic-Schnittstelle zur Nutzung von Claude-Modellen.
### 11.2 Prompt Pro Lauf ist genau **ein** Provider aktiv. Es gibt:
- **keine** automatische Fallback-Umschaltung
- **keine** parallele Nutzung mehrerer Provider in einem Lauf
- **keine** Profilverwaltung mit mehreren Konfigurationen je Provider-Familie
Die Auswahl erfolgt ausschließlich über Konfiguration. Ein Fehler des aktiven Providers ist und bleibt ein Fehler dieses einen Pfads und folgt der bestehenden Retry- und Fehlersemantik.
### 11.2 Architekturelle Einbettung
- Pro Provider-Familie existiert **genau eine** Implementierung des `AiNamingPort` im Modul `pdf-umbenenner-adapter-out`.
- Provider-spezifische Endpunkte, Header, Authentifizierungsverfahren, Request- und Response-Strukturen leben ausschließlich in der jeweiligen Adapter-Implementierung.
- Application und Domain bleiben provider-neutral. Sie kennen weder den Begriff „OpenAI" noch „Claude".
- Das **Bootstrap-Modul** wählt anhand der Konfiguration die eine aktive Implementierung aus und verdrahtet sie als `AiNamingPort`.
- Adapter dürfen nicht voneinander abhängen. Es gibt keinen gemeinsamen „abstrakten KI-Adapter" als Infrastrukturschicht zwischen Port und konkreten Adaptern.
### 11.3 Einheitlicher fachlicher Vertrag
Unabhängig vom aktiven Provider gilt derselbe fachliche Vertrag:
- gleicher fachlicher Input (Prompt, Textausschnitt, Modellbezug)
- gleicher fachlicher Output (Domain-Typ `NamingProposal`)
- gleiche Validierungs- und Folgeprozesse in der Application
- keine provider-spezifische Verzweigung im fachlichen Kern
Jede provider-spezifische Antwort wird im Adapter auf denselben Domain-Typ abgebildet. Eine Sonderbehandlung im Use-Case oder in der Domain ist unzulässig.
### 11.4 Prompt
Der Prompt wird **nicht** im Code fest verdrahtet. Der Prompt wird **nicht** im Code fest verdrahtet.
Verbindlich: Verbindlich:
- externe Prompt-Datei - externe Prompt-Datei
- Prompt-Version oder Prompt-Dateiname wird mitpersistiert - Prompt-Version oder Prompt-Dateiname wird mitpersistiert
- der Prompt darf die KI zur Ausgabe eines deutschen Titels anweisen - der Prompt darf die KI zur Ausgabe eines deutschen Titels anweisen
- derselbe Prompt wird providerübergreifend verwendet; provider-spezifische Anpassungen finden ausschließlich in der Adapter-Implementierung statt
### 11.3 Textmenge ### 11.5 Textmenge
Es wird nicht zwingend der komplette extrahierte PDF-Text an die KI gesendet. Es wird nicht zwingend der komplette extrahierte PDF-Text an die KI gesendet.
Verbindlich: Verbindlich:
- die maximale Zeichenzahl ist konfigurierbar - die maximale Zeichenzahl ist konfigurierbar
- die Begrenzung muss vor dem KI-Aufruf technisch angewendet werden - die Begrenzung muss vor dem KI-Aufruf technisch angewendet werden
- die Begrenzung gilt providerunabhängig
### 11.4 Antwortformat ### 11.6 Antwortformat
Die KI muss genau ein parsebares JSON-Objekt liefern. Die KI muss unabhängig vom aktiven Provider fachlich genau ein parsebares JSON-Objekt liefern.
Zweckmäßiges Schema: Zweckmäßiges Schema:
@@ -408,7 +404,9 @@ Regeln:
- `date` ist optional, wenn kein belastbares Datum ableitbar ist - `date` ist optional, wenn kein belastbares Datum ableitbar ist
- liefert die KI kein `date`, setzt die Anwendung das aktuelle Datum als Fallback - liefert die KI kein `date`, setzt die Anwendung das aktuelle Datum als Fallback
### 11.5 Antwortvalidierung Wie der Adapter dieses Schema aus der jeweiligen Provider-Antwort extrahiert (z. B. aus `choices[].message.content` bei OpenAI-kompatiblen Schnittstellen oder aus dem Content-Block-Array der Anthropic Messages API), ist eine reine Adapter-Implementierungsfrage.
### 11.7 Antwortvalidierung
Die Antwort gilt nur dann als technisch brauchbar, wenn: Die Antwort gilt nur dann als technisch brauchbar, wenn:
- JSON parsebar ist - JSON parsebar ist
- `title` vorhanden ist - `title` vorhanden ist
@@ -418,6 +416,11 @@ Zusätzlich gilt fachlich:
- `title` muss validierbar und brauchbar sein - `title` muss validierbar und brauchbar sein
- ein vorhandenes `date` muss im Format `YYYY-MM-DD` interpretierbar sein - ein vorhandenes `date` muss im Format `YYYY-MM-DD` interpretierbar sein
Diese Validierung ist provider-unabhängig und liegt in Application/Domain.
### 11.8 Fehlerklassifikation
Technische Fehler des aktiven Providers (HTTP-Fehler, Timeouts, ungültige Antwortstrukturen, Authentifizierungsfehler) werden im Adapter erkannt und auf die bestehende technische Fehlersemantik des Projekts abgebildet (transient vs. deterministisch). Es entsteht keine neue Fehlerkategorie. Der inaktive Provider wird in keiner Fehlersituation als Backup verwendet.
--- ---
## 12. PDF-Verarbeitung ## 12. PDF-Verarbeitung
@@ -457,6 +460,8 @@ Die Persistenz wird zweckmäßig in **zwei Ebenen** geführt:
1. **Dokument-Stammsatz** pro Fingerprint 1. **Dokument-Stammsatz** pro Fingerprint
2. **Versuchshistorie** mit einem Datensatz pro Verarbeitungsversuch 2. **Versuchshistorie** mit einem Datensatz pro Verarbeitungsversuch
Das bestehende Schema bleibt erhalten. Es wird ausschließlich um die Information erweitert, **welcher Provider** den jeweiligen Versuch erzeugt hat (siehe 13.4). Eine neue Wahrheitsquelle entsteht nicht.
### 13.3 Dokument-Stammsatz ### 13.3 Dokument-Stammsatz
Mindestens zweckmäßig zu speichern: Mindestens zweckmäßig zu speichern:
- interne ID - interne ID
@@ -485,6 +490,7 @@ Für **jeden Versuch separat** zu speichern:
- Fehlerklasse - Fehlerklasse
- Fehlermeldung - Fehlermeldung
- Retryable-Flag - Retryable-Flag
- **Provider-Identifikator des aktiven KI-Providers für diesen Versuch**
- Modellname - Modellname
- Prompt-Identifikator - Prompt-Identifikator
- verarbeitete Seitenzahl - verarbeitete Seitenzahl
@@ -496,11 +502,16 @@ Für **jeden Versuch separat** zu speichern:
- finaler Titel - finaler Titel
- finaler Zieldateiname - finaler Zieldateiname
Der Provider-Identifikator macht jeden Versuch eindeutig nachvollziehbar einer Provider-Familie zuordenbar, ohne den fachlichen Vertrag zu verändern.
### 13.5 Sensible Inhalte ### 13.5 Sensible Inhalte
Die vollständige KI-Rohantwort wird in SQLite gespeichert. Die vollständige KI-Rohantwort wird in SQLite gespeichert.
Sie soll **standardmäßig nicht vollständig in Logdateien** geschrieben werden. Sie soll **standardmäßig nicht vollständig in Logdateien** geschrieben werden.
### 13.6 Rückwärtsverträglichkeit
Bestehende Datenbestände aus dem Stand vor v2 müssen weiterhin lesbar, fortschreibbar und korrekt interpretierbar bleiben. Schema-Erweiterungen erfolgen additiv und mit definierten Defaultwerten für historische Versuche ohne Provider-Identifikator.
--- ---
## 14. Konfiguration ## 14. Konfiguration
@@ -508,33 +519,77 @@ Sie soll **standardmäßig nicht vollständig in Logdateien** geschrieben werden
### 14.1 Format ### 14.1 Format
Die technische Konfiguration erfolgt über `.properties`. Die technische Konfiguration erfolgt über `.properties`.
### 14.2 Mindestparameter ### 14.2 Provider-Auswahl
Genau ein Provider ist aktiv. Die Auswahl erfolgt über einen einzigen Pflichtparameter, der den aktiven Provider benennt. Zulässige Werte sind die Bezeichner der unterstützten Provider-Familien aus Abschnitt 11.1.
### 14.3 Mindestparameter
Verbindlich zweckmäßige Parameter: Verbindlich zweckmäßige Parameter:
- `source.folder` - `source.folder`
- `target.folder` - `target.folder`
- `sqlite.file` - `sqlite.file`
- `api.baseUrl` - **`ai.provider.active`** Auswahl des aktiven Providers (Pflicht)
- `api.model`
- `api.timeoutSeconds`
- `max.retries.transient` - `max.retries.transient`
- `max.pages` - `max.pages`
- `max.text.characters` - `max.text.characters`
- `prompt.template.file` - `prompt.template.file`
Pro unterstützter Provider-Familie existiert ein eigener Parameter-Namensraum mit zweckmäßig mindestens:
- Modellname
- API-Schlüssel
- Timeout
- Basis-URL (optional, wo betrieblich sinnvoll)
Konkretes Schema (zweckmäßig, frei wählbare Bezeichner):
```properties
ai.provider.active=openai-compatible
ai.provider.openai-compatible.baseUrl=...
ai.provider.openai-compatible.model=...
ai.provider.openai-compatible.timeoutSeconds=...
ai.provider.openai-compatible.apiKey=...
ai.provider.claude.baseUrl=...
ai.provider.claude.model=...
ai.provider.claude.timeoutSeconds=...
ai.provider.claude.apiKey=...
```
Zusätzlich zweckmäßig: Zusätzlich zweckmäßig:
- `runtime.lock.file` - `runtime.lock.file`
- `log.directory` - `log.directory`
- `log.level` - `log.level`
- `api.key` - `log.ai.sensitive`
### 14.3 API-Key ### 14.4 API-Schlüssel
Der API-Key darf über Umgebungsvariable oder Properties geliefert werden. API-Schlüssel dürfen über Umgebungsvariable oder Properties geliefert werden.
Verbindlich: Verbindlich:
- Umgebungsvariable hat Vorrang - pro Provider-Familie existiert eine **eigene definierte Umgebungsvariable**
- die Umgebungsvariable hat **Vorrang** vor dem Properties-Wert derselben Provider-Familie
- Schlüssel verschiedener Provider-Familien werden niemals vermischt
### 14.4 Konfigurationsvalidierung ### 14.5 Migration historischer Konfigurationen
Beim Start müssen alle Pflichtparameter validiert werden. Bestehende Properties-Dateien aus dem Stand vor v2 (mit flachen Schlüsseln wie `api.baseUrl`, `api.model`, `api.timeoutSeconds`, `api.key`) sind eine eindeutig erkennbare Legacy-Form.
Beim ersten Start mit erkannter Legacy-Form gilt verbindlich:
1. Legacy-Form erkennen
2. **`.bak`-Sicherung** der Originaldatei anlegen
3. Inhalt in das neue Schema überführen
- die Legacy-Werte werden in den Namensraum der Provider-Familie **`openai-compatible`** überführt
- `ai.provider.active` wird auf `openai-compatible` gesetzt
4. neue Datei schreiben (In-Place-Update)
5. Datei erneut laden und validieren
6. erst danach den normalen Lauf fortsetzen
Es ist **kein** Ziel, alte und neue Struktur dauerhaft gleichrangig als Endformat zu pflegen.
### 14.6 Konfigurationsvalidierung
Beim Start müssen alle Pflichtparameter validiert werden, insbesondere:
- `ai.provider.active` ist gesetzt und benennt einen unterstützten Provider
- für den aktiven Provider sind alle Pflichtwerte vorhanden und technisch konsistent
- für den **inaktiven** Provider werden keine Pflichtwerte erzwungen
Bei ungültiger Startkonfiguration: Bei ungültiger Startkonfiguration:
- beginnt kein Verarbeitungslauf - beginnt kein Verarbeitungslauf
@@ -553,6 +608,7 @@ Das Logging muss mindestens enthalten:
- Laufstart - Laufstart
- Laufende - Laufende
- Lauf-ID - Lauf-ID
- **aktiver KI-Provider für den Lauf**
- erkannte Quelldatei - erkannte Quelldatei
- Überspringen bereits erfolgreicher Dateien - Überspringen bereits erfolgreicher Dateien
- Überspringen final fehlgeschlagener Dateien - Überspringen final fehlgeschlagener Dateien
@@ -566,6 +622,7 @@ Standardmäßig gilt:
- vollständige KI-Rohantwort **in SQLite** - vollständige KI-Rohantwort **in SQLite**
- `reasoning` darf geloggt werden, sofern dies betrieblich gewünscht ist - `reasoning` darf geloggt werden, sofern dies betrieblich gewünscht ist
- die Ausgabe sensibler Inhalte muss konfigurierbar sein - die Ausgabe sensibler Inhalte muss konfigurierbar sein
- die Sensibilitätsregel gilt provider-unabhängig
### 15.4 Speicherort ### 15.4 Speicherort
Das Log-Verzeichnis ist konfigurierbar. Ohne explizite Konfiguration ist ein lokales `logs/`-Verzeichnis im Programmkontext zweckmäßig. Das Log-Verzeichnis ist konfigurierbar. Ohne explizite Konfiguration ist ein lokales `logs/`-Verzeichnis im Programmkontext zweckmäßig.
@@ -598,7 +655,7 @@ Verbindliche Interpretation:
- `1`: Lauf konnte wegen hartem Start-/Bootstrap-Fehler nicht ordnungsgemäß beginnen oder fortgesetzt werden - `1`: Lauf konnte wegen hartem Start-/Bootstrap-Fehler nicht ordnungsgemäß beginnen oder fortgesetzt werden
Typische `1`-Fälle: Typische `1`-Fälle:
- ungültige Konfiguration - ungültige Konfiguration (einschließlich fehlender oder unbekannter `ai.provider.active`)
- Run-Lock nicht erwerbbar - Run-Lock nicht erwerbbar
- essentielle Ressourcen beim Start nicht verfügbar - essentielle Ressourcen beim Start nicht verfügbar
@@ -616,23 +673,30 @@ Nicht Bestandteil dieser Architektur sind:
- menschlicher Review-Workflow - menschlicher Review-Workflow
- interne Scheduler-Logik - interne Scheduler-Logik
- fachliche Identifikation über Dateinamen - fachliche Identifikation über Dateinamen
- automatische Fallback-Umschaltung zwischen KI-Providern
- parallele Nutzung mehrerer KI-Provider in einem Lauf
- mehrere konkurrierende Konfigurationen je Provider-Familie (Profilverwaltung)
- Provider-Familien jenseits der in Abschnitt 11.1 explizit genannten
--- ---
## 19. Abschlussbewertung ## 19. Abschlussbewertung
Der technische Zielstand ist mit den hier festgelegten Regeln: Der technische Zielstand ist mit den in dieser Fassung festgelegten Regeln:
- konsistent - konsistent
- widerspruchsfrei - widerspruchsfrei
- hexagonal sauber geschnitten - hexagonal sauber geschnitten
- für einen minimalen produktiven PDF-Umbenenner zweckmäßig - für einen minimalen produktiven PDF-Umbenenner zweckmäßig
- offen für genau zwei gleichwertig unterstützte KI-Provider-Familien, ohne den fachlichen Kern zu verändern
Besonders verbindlich geklärt sind jetzt: Besonders verbindlich geklärt sind:
- Dateinamensformat mit `YYYY-MM-DD - Titel.pdf` - Dateinamensformat mit `YYYY-MM-DD - Titel.pdf`
- Dublettenregel mit `(1)`, `(2)`, ... - Dublettenregel mit `(1)`, `(2)`, ...
- Trennung zwischen finalen und retrybaren Fehlern - Trennung zwischen finalen und retrybaren Fehlern
- Fallback-Datum durch die Anwendung - Fallback-Datum durch die Anwendung
- Zwei-Ebenen-Persistenz mit Versuchshistorie - Zwei-Ebenen-Persistenz mit Versuchshistorie inkl. Provider-Identifikator
- Exit-Code-Regel für harte Startfehler - Exit-Code-Regel für harte Startfehler
- OpenAI-kompatible Schnittstelle ohne fest verdrahteten Provider - Unterstützung von OpenAI-kompatibler Schnittstelle **und** nativer Anthropic Messages API
- genau **ein** aktiver Provider pro Lauf, ohne Fallback
- Verlagerung technischer Persistenzobjekte aus der Domain heraus - Verlagerung technischer Persistenzobjekte aus der Domain heraus
- Migration historischer flacher Properties-Konfiguration mit `.bak`-Sicherung

View File

@@ -0,0 +1,324 @@
# Arbeitspakete Erweiterung um native Anthropic Claude-Anbindung
## Geltungsbereich
Dieses Dokument beschreibt ausschließlich die Arbeitspakete für die Erweiterung **„Zusätzliche KI-Provider-Familie Anthropic Claude über die native Messages API"**.
Der Basisstand des Projekts ist vollständig umgesetzt, dokumentiert, getestet und freigegeben. Diese Erweiterung ist eine **bewusst minimale Ergänzung** dieses Basisstands.
Das einzige Ziel dieser Erweiterung ist:
- den bestehenden, OpenAI-kompatiblen KI-Weg unverändert nutzbar zu halten,
- zusätzlich die **native Anthropic Messages API** als zweiten, gleichwertig unterstützten KI-Provider anzubinden,
- und zwischen beiden Providern über die Konfiguration genau **einen aktiven Provider** auszuwählen.
Die Arbeitspakete sind so geschnitten, dass:
- **KI 1** daraus je Arbeitspaket einen klaren Einzel-Prompt ableiten kann,
- **KI 2** genau dieses eine Arbeitspaket in **einem Durchgang** vollständig umsetzen kann,
- nach **jedem** Arbeitspaket wieder ein **fehlerfreier, buildbarer Stand** vorliegt.
Die Reihenfolge der Arbeitspakete ist verbindlich.
## Schnittregeln für die KI-Bearbeitung
- Pro Arbeitspaket nur die **minimal notwendigen Querschnitte** durch Domain, Application, Adapter, Bootstrap, Konfiguration, Dokumentation und Tests ändern.
- Keine Annahmen treffen, die nicht durch die verbindlichen Spezifikationen, dieses Dokument oder den tatsächlich vorliegenden Code gedeckt sind.
- Änderungen strikt nach dem Prinzip: **so wenig wie möglich, so viel wie nötig**.
- Keine allgemeine Provider-Plattform und keine Abstraktion für hypothetische weitere Provider.
- Kein Umbau des bestehenden fachlichen Ablaufs ohne direkten Bezug zur Provider-Erweiterung.
- Das bestehende fachliche Verhalten des Basisstands bleibt unverändert, soweit dieses Dokument nichts anderes ausdrücklich erweitert.
- Jeder positive Zwischenstand muss bereits **vollständig buildbar, testbar und dokumentiert** sein.
- Zu jedem Arbeitspaket gehören die unmittelbar betroffenen:
- Implementierungen,
- Tests (inkl. ggf. Mutationstests in den unmittelbar betroffenen Modulen),
- JavaDoc / `package-info`,
- Konfigurationsbeispiele,
- sowie sonstige Repository-Dokumente mit direktem Bezug.
## Explizit nicht Bestandteil dieser Erweiterung
- Provider-Familien jenseits der zwei explizit unterstützten (OpenAI-kompatibel, Anthropic Messages API)
- mehrere Konfigurationen je Provider-Familie (Profilverwaltung)
- automatische Fallback-Umschaltung zwischen Providern
- parallele Nutzung mehrerer Provider in einem Lauf
- Änderung des fachlichen Ergebnisvertrags der KI
- Änderung der Dateinamensregeln
- Änderung der Retry-Regeln
- Änderung des Batch-Betriebsmodells
- Änderung der bestehenden fachlichen Kernlogik außerhalb der für die Claude-Integration nötigen Anbindung
- Persistenz- oder Schemaänderungen ohne zwingenden Bedarf für die Provider-Erweiterung (additive Provider-Identifikator-Spalte ist explizit zwingend, mehr nicht)
## Verbindliche Regeln für **alle** Arbeitspakete
### 1. Minimale Erweiterung des Basisstands
Die Erweiterung darf den bestehenden fachlichen Ablauf **nicht stillschweigend verändern**.
Ziel ist ausschließlich:
- den bestehenden OpenAI-kompatiblen KI-Weg weiter nutzbar zu halten,
- zusätzlich einen nativen Anthropic-Messages-API-Adapter zu integrieren,
- und zwischen beiden Wegen über die Konfiguration genau **einen aktiven Provider** auszuwählen.
### 2. Einheitlicher fachlicher KI-Vertrag
Unabhängig vom Provider gilt weiterhin derselbe fachliche Vertrag:
- gleicher fachlicher Input
- gleicher fachlicher Output (`NamingProposal`)
- gleicher Validierungs- und Folgeprozess in der Anwendung
- keine provider-spezifische Verzweigung im fachlichen Kern
- der bestehende strukturierte Ergebnisvertrag bleibt unverändert; es entsteht **kein** provider-spezifischer Sonderweg
### 3. Genau ein aktiver Provider
Es werden gespeichert:
- **genau eine** Konfiguration für die OpenAI-kompatible Provider-Familie
- **genau eine** Konfiguration für die Anthropic-Provider-Familie
- **genau ein** aktiver Provider
Es gibt:
- keine Profilverwaltung
- keine Prioritätenliste
- keinen Mehrfach-Fallback
- keine automatische Umschaltung bei Fehlern
### 4. Properties-Datei bleibt führend
Die Konfiguration bleibt in der `.properties`-Datei geführt.
Die Struktur darf weiterentwickelt werden, muss aber:
- bestehende Properties-Dateien des Vorgängerstands **weiterhin akzeptieren**,
- diese **beim ersten Start** kontrolliert in die neue Struktur überführen,
- **vor** der Migration immer eine `.bak`-Sicherung anlegen.
### 5. Migration bestehender Properties beim ersten Start
Wird eine Legacy-Form erkannt, gilt verbindlich:
1. Legacy-Form erkennen
2. `.bak`-Sicherung anlegen
3. Datei in die neue Struktur migrieren (Legacy-Werte → Namensraum `openai-compatible`, `ai.provider.active=openai-compatible`)
4. Datei erneut laden und validieren
5. Erst danach den normalen Lauf fortsetzen
Alte und neue Struktur sind **kein** dauerhaft gleichrangiges Endformat.
### 6. OpenAI-kompatibler Weg bleibt funktional unverändert
Der bestehende OpenAI-kompatible Adapter bleibt funktional unverändert nutzbar.
Daraus folgt:
- kein fachlicher Regressionsumbau des bisherigen Provider-Verhaltens
- bestehende Konfigurationen müssen nach der Migration weiterhin funktional anschlussfähig sein
- die Erweiterung darf den bestehenden Weg nicht beschädigen
### 7. Claude wird über die native Messages API angebunden
Anthropic Claude wird über einen **eigenen nativen Adapter** im Adapter-Out-Modul angebunden.
Daraus folgt:
- Endpunkt, Authentifizierungsschema, Request- und Response-Format der Anthropic Messages API leben **ausschließlich** im Adapter
- Domain und Application bleiben provider-neutral
- die provider-spezifische Request-/Response-Abbildung darf den fachlichen Vertrag nicht verändern
- Adapter dürfen nicht voneinander abhängen; es gibt keine gemeinsame Zwischenschicht
### 8. Provider-Auswahl ist strikt und ohne Fallback
Der aktive Provider wird ausschließlich aus der Konfiguration bestimmt.
Daraus folgt:
- nur der aktive Provider wird verwendet
- der inaktive Provider wird in keiner Fehlersituation als Backup verwendet
- Fehler des aktiven Providers bleiben Fehler dieses einen Pfads und folgen der bestehenden Retry- und Fehlersemantik
### 9. Keine Zusatzänderungen ohne direkten Provider-Bezug
Es werden nur solche Änderungen eingeführt, die für die zusätzliche Claude-Integration und die dafür nötige Provider-Auswahl tatsächlich erforderlich sind.
Daraus folgt:
- keine zusätzlichen Komfortfunktionen
- keine allgemeine Provider-Plattform
- keine Änderungen an Persistenz oder Nachvollziehbarkeit, sofern sie für diese Erweiterung nicht zwingend erforderlich sind (additive Provider-Identifikator-Spalte ist die einzige zwingende Persistenzänderung)
### 10. Architekturtreue
Es gilt unverändert:
- strikte hexagonale Architektur
- Abhängigkeiten zeigen nach innen
- keine Infrastrukturtypen in Domain oder Application
- keine direkte Adapter-zu-Adapter-Kopplung
- keine Vermischung von Provider-spezifischer HTTP-Kommunikation mit fachlicher Entscheidungslogik
- der `AiNamingPort` bleibt provider-neutral
---
## AP-001 Konfigurations-Schema, Migration mit `.bak` und Startvalidierung
### Voraussetzung
Keine. Dieses Arbeitspaket ist der Startpunkt der Erweiterung.
### Ziel
Die Konfiguration wird mit minimalem Eingriff so erweitert, dass zwischen den unterstützten Provider-Familien gewählt werden kann, und bestehende Properties-Dateien aus dem Vorgängerstand werden beim ersten Start automatisch sicher in das neue Schema überführt.
### Muss umgesetzt werden
- Properties-Schema minimal so erweitern, dass folgende Informationen konfigurierbar sind:
- aktiver Provider (`ai.provider.active`),
- Konfigurations-Namensraum für die OpenAI-kompatible Provider-Familie,
- Konfigurations-Namensraum für die Claude-Provider-Familie.
- Legacy-Form (flache `api.*`-Schlüssel) eindeutig erkennen.
- Vor jeder Migration automatisch eine **`.bak`-Sicherung** anlegen.
- Migration als **In-Place-Update** umsetzen:
- Legacy lesen,
- in neues Schema überführen,
- in-place schreiben,
- neu laden,
- validieren.
- Legacy-Werte korrekt in den Namensraum `openai-compatible` überführen und `ai.provider.active=openai-compatible` setzen.
- Startvalidierung gezielt erweitern, insbesondere für:
- genau ein gesetzter, unterstützter aktiver Provider,
- nur die für den aktiven Provider nötigen Pflichtwerte,
- technisch konsistente Provider-Konfiguration (Modellname, Timeout, ggf. Basis-URL),
- API-Schlüssel des aktiven Providers (Umgebungsvariable hat Vorrang vor Properties).
- Konfigurationsbeispiele, JavaDoc und unmittelbar betroffene Repository-Dokumente anpassen.
- Tests ergänzen für:
- erfolgreiche Migration einer realistischen Legacy-Datei,
- `.bak`-Erzeugung,
- korrekte Übernahme der Legacy-Werte in den `openai-compatible`-Namensraum,
- Abweisung ungültiger oder fehlender `ai.provider.active`,
- Abweisung unvollständiger Pflichtwerte für den aktiven Provider,
- Vorrang der Umgebungsvariablen vor dem Properties-Schlüssel des aktiven Providers.
### Explizit nicht Teil
- nativer Claude-Adapter
- Bootstrap-Auswahl des aktiven Providers (folgt in AP-002)
- Refactoring des bestehenden OpenAI-kompatiblen Adapters über das für das neue Schema nötige Maß hinaus
- Persistenz- oder Schemaänderungen
- fachliche Änderungen am KI-Ergebnisvertrag
### Fertig wenn
- das erweiterte Properties-Schema technisch nutzbar ist,
- Legacy-Dateien beim ersten Start sicher mit `.bak` migriert werden,
- ungültige Provider-Konfigurationen sauber abgewiesen werden,
- der Build weiterhin fehlerfrei ist und alle bestehenden Tests grün bleiben.
---
## AP-002 Bestehenden OpenAI-kompatiblen Pfad an die Provider-Auswahl anbinden
### Voraussetzung
AP-001 ist abgeschlossen.
### Ziel
Der bestehende OpenAI-kompatible KI-Weg wird mit minimalem Umbau so eingebettet, dass das Bootstrap-Modul den aktiven Provider aus der Konfiguration auswählen und verdrahten kann, ohne den bisherigen fachlichen Ablauf zu verändern.
### Muss umgesetzt werden
- Im Bootstrap-Modul eine **Provider-Auswahl** einführen, die anhand von `ai.provider.active` genau eine `AiNamingPort`-Implementierung als aktive Implementierung verdrahtet.
- Den bestehenden OpenAI-kompatiblen Adapter so anbinden, dass er die Werte aus dem Namensraum `ai.provider.openai-compatible.*` konsumiert.
- Den bisherigen OpenAI-kompatiblen Weg dabei funktional unverändert erhalten.
- Application und Domain weiterhin frei von provider-spezifischen HTTP-/JSON-Typen halten.
- Provider-spezifische Request-/Response-Abbildung und Fehlerbehandlung weiterhin klar im Adapter-Out kapseln.
- Sicherstellen, dass ein zukünftiger zweiter Provider nur durch eine zusätzliche Implementierung im Adapter-Out und einen zusätzlichen Eintrag in der Provider-Auswahl angebunden wird ohne neue Zwischenschicht und ohne Adapter-zu-Adapter-Kopplung.
- Den Provider-Identifikator des aktiven Providers in die Versuchshistorie einfließen lassen (additive Schema-Erweiterung mit definiertem Default für historische Versuche).
- Logging-Mindestumfang um den **aktiven Provider beim Laufstart** ergänzen.
- Relevante JavaDoc- und Repository-Dokumentation mitziehen.
- Tests gezielt anpassen oder ergänzen, um nachzuweisen:
- der bisherige OpenAI-kompatible Pfad bleibt funktional intakt,
- die Provider-Auswahl ist technisch sauber angebunden,
- eine ungültige Provider-Auswahl scheitert in der Startvalidierung,
- der Provider-Identifikator landet pro Versuch korrekt in der Persistenz,
- der fachliche Ergebnisvertrag bleibt unverändert,
- bestehende Datenbestände bleiben lesbar und korrekt interpretierbar.
### Explizit nicht Teil
- nativer Claude-Adapter
- Fallback-Logik
- zusätzliche Provider-Familien
- Persistenz- oder Schemaänderungen jenseits der additiven Provider-Identifikator-Spalte
- globale Abschlussprüfung
### Fertig wenn
- der OpenAI-kompatible Weg über die neue Provider-Auswahl sauber nutzbar bleibt,
- sein fachliches Verhalten gegenüber dem Vorgängerstand unverändert ist,
- keine Provider-Implementierungsdetails in den fachlichen Kern durchsickern,
- der Provider-Identifikator persistent erfasst wird,
- bestehende Datenbestände unverändert nutzbar bleiben,
- der Build weiterhin fehlerfrei ist.
---
## AP-003 Nativen Anthropic-Messages-API-Adapter implementieren und verdrahten
### Voraussetzung
AP-001 und AP-002 sind abgeschlossen.
### Ziel
Ein nativer Adapter für die Anthropic Messages API ist technisch nutzbar, wird über die Provider-Auswahl als aktiver Provider verdrahtet und liefert fachlich denselben Ergebnisvertrag wie der bestehende OpenAI-kompatible Weg.
### Muss umgesetzt werden
- Im Adapter-Out-Modul eine zweite `AiNamingPort`-Implementierung anlegen, die die **native Anthropic Messages API** anspricht.
- Die Claude-spezifische Konfiguration aus dem Namensraum `ai.provider.claude.*` technisch anbinden, mindestens:
- Modellname,
- API-Schlüssel (Umgebungsvariable hat Vorrang),
- Timeout,
- Basis-URL als optionaler Konfigurationswert mit fachlich neutralem Default.
- Provider-spezifische Request-Erzeugung und Response-Verarbeitung so umsetzen, dass das fachliche JSON-Ergebnis (`date`, `title`, `reasoning`) wie beim bestehenden Weg in den vorhandenen Domain-Typ `NamingProposal` abgebildet wird.
- Technische Fehlerfälle des Claude-Pfads (HTTP-Fehler, Timeouts, ungültige Antwortstrukturen, Authentifizierungsfehler) **im Adapter** klassifizieren und auf die bestehende technische Fehlersemantik des Projekts abbilden. Es entstehen keine neuen Fehlerklassen.
- Sicherstellen, dass Claude **keinen** Sonderweg im fachlichen Kern erzwingt und keine Application-/Domain-Klasse provider-spezifisch wird.
- Die Provider-Auswahl im Bootstrap-Modul um die neue Implementierung erweitern. Das geschieht ausschließlich in der bereits in AP-002 angelegten Auswahlstelle, ohne neue Zwischenschicht.
- Adapter-zu-Adapter-Kopplung aktiv vermeiden: keine gemeinsame Basisklasse, kein gemeinsamer Hilfsadapter zwischen Port und konkreten Adaptern.
- Konfigurationsbeispiele, JavaDoc und unmittelbar betroffene Repository-Dokumente mitziehen.
- Tests ergänzen für:
- korrekte Request-Erzeugung gegen die Anthropic Messages API (Adapter-Test mit gemocktem HTTP-Layer),
- korrekte Response-Abbildung auf den bestehenden fachlichen Vertrag,
- technische Claude-Fehlerfälle (HTTP-Fehler, Timeout, Auth-Fehler, defekte Antwortstruktur) und deren Klassifikation,
- Auswahl und Nutzung von Claude als aktivem Provider über die Konfiguration,
- keine fachliche Sonderbehandlung gegenüber dem OpenAI-kompatiblen Pfad,
- korrekter Provider-Identifikator in der Versuchshistorie für Claude-Läufe.
### Explizit nicht Teil
- automatische Fallback-Logik
- weitere Provider-Familien
- Persistenz- oder Schemaänderungen jenseits der bereits in AP-002 eingeführten additiven Provider-Identifikator-Spalte
- neue Fachfunktionalität außerhalb der Provider-Erweiterung
- globale Abschlussprüfung
### Fertig wenn
- der native Anthropic-Messages-API-Adapter technisch nutzbar ist,
- Claude über die Konfiguration als aktiver Provider auswählbar ist,
- sein Ergebnis fachlich auf denselben Vertrag wie der bestehende Provider abgebildet wird,
- provider-spezifische Details ausschließlich im Adapter-Out leben,
- der bestehende OpenAI-kompatible Pfad weiterhin unverändert nutzbar ist,
- der Build weiterhin fehlerfrei ist.
---
## AP-004 Regressionsschutz, Dokumentationskonsolidierung und Abschlussnachweis
### Voraussetzung
AP-001 bis AP-003 sind abgeschlossen.
### Ziel
Der vollständige Erweiterungsstand wird automatisiert abgesichert, dokumentarisch konsolidiert und als minimale Erweiterung des freigegebenen Basisstands belastbar nachgewiesen.
### Muss umgesetzt werden
- Den vollständigen Erweiterungsstand gegen die in diesem Dokument definierten Regeln prüfen.
- Tests vervollständigen bzw. konsolidieren, insbesondere für:
- erfolgreiche Migration einer realistischen Legacy-Properties-Datei,
- `.bak`-Erzeugung,
- OpenAI-kompatibler Provider weiterhin nutzbar (Regression),
- nativer Anthropic-Provider nutzbar,
- genau ein aktiver Provider, ohne Fallback-Umschaltung,
- einheitlicher fachlicher Ergebnisvertrag über beide Provider hinweg,
- Provider-Identifikator in der Versuchshistorie korrekt gesetzt,
- Logging des aktiven Providers beim Laufstart vorhanden,
- Sensibilitätsregel für KI-Inhalte gilt provider-unabhängig,
- bestehende Datenbestände bleiben lesbar und korrekt interpretierbar.
- Vorhandene PIT-/Mutationstest-Konfiguration auf die neuen oder geänderten Klassen ausdehnen, soweit für den Stand sinnvoll.
- Smoke-Tests so erweitern, dass für **beide** Provider-Konfigurationen der Bootstrap-Pfad bis zur erfolgreichen Verdrahtung des `AiNamingPort` durchläuft (ohne realen externen Aufruf).
- Konfigurationsbeispiele, Startdokumentation und sonstige Repository-Dokumente konsolidieren, sodass die Erweiterung ohne implizite Annahmen verständlich bleibt.
- Einen knappen, im Repository verbleibenden Abschlussnachweis ergänzen, der mindestens festhält:
- welche Prüfungen tatsächlich ausgeführt wurden,
- dass die Erweiterung minimal-invasiv umgesetzt wurde,
- dass beide Provider-Familien unterstützt werden,
- dass die Konfigurationsmigration und `.bak`-Sicherung nachgewiesen sind,
- dass keine Architekturbrüche eingeführt wurden.
- Den relevanten Build-/Test-Umfang tatsächlich ausführen.
### Explizit nicht Teil
- weitere Provider-Familien
- zusätzliche Konfigurationsprofile
- neue Komfort- oder Bedienfunktionen
- weitergehende Architekturumbauten ohne direkten Bezug zur Erweiterung
### Fertig wenn
- der vollständige Erweiterungsstand automatisiert abgesichert ist,
- die Dokumentation konsistent zum realen Verhalten passt,
- die Minimalinvasivität gegenüber dem Basisstand belastbar nachgewiesen ist,
- ein fehlerfreier, übergabefähiger Stand vorliegt.