333 lines
18 KiB
Markdown
333 lines
18 KiB
Markdown
# 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.
|
||
|
||
Ab V2.0 wird die Anwendung um eine **lokale JavaFX-Desktop-GUI** erweitert. Die GUI ist der neue Standardstart. Der bestehende headless Batch-Betrieb bleibt über `--headless` vollständig erhalten.
|
||
|
||
## Autoritative Dokumente
|
||
@docs/specs/technik-und-architektur.md
|
||
@docs/specs/fachliche-anforderungen.md
|
||
@docs/specs/meilensteine-v2_0.md
|
||
|
||
Für die Umsetzung ist zusätzlich immer das aktuell aktive Arbeitspaket unter `docs/workpackages/` maßgeblich.
|
||
Dateinamensschema: `M9 - Arbeitspakete.md`, `M10 - Arbeitspakete.md`, … `M13 - Arbeitspakete.md`
|
||
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-v2_0.md` = verbindliche V2.0-Zieldefinition und Meilensteinabgrenzung
|
||
- `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 V2.0**
|
||
Verbindliche Zieldefinition, Abgrenzungen und Leitplanken für den V2.0-Ausbau.
|
||
|
||
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 (ein gemeinsames JAR für GUI und headless)
|
||
- **GUI ist der neue Standardstart** (ab V2.0)
|
||
- `--headless` startet weiterhin den bestehenden Batch-/Scheduler-Betrieb
|
||
- `--config <pfad>` steht für GUI und headless zur Verfügung
|
||
- kein Webserver
|
||
- kein Applikationsserver
|
||
- keine Dauerlauf-Anwendung
|
||
- kein interner Scheduler
|
||
- keine EXE, kein Installer
|
||
- Log4j2 für Logging
|
||
- SQLite als lokaler Persistenzspeicher
|
||
- JavaFX wird mit dem JAR ausgeliefert (kein separates JavaFX-Setup)
|
||
- GUI offiziell nur für Windows; headless bleibt für Windows Server / Task Scheduler geeignet
|
||
- gemappte Laufwerke wie `S:\` oder `H:\` sind ausdrücklich zu unterstützen
|
||
- KI-Anbindung über genau **eine** der beiden unterstützten Provider-Familien:
|
||
- **OpenAI-kompatible HTTP-Schnittstelle** (Chat-Completions-Stil)
|
||
- **native Anthropic Messages API** (Claude-Modelle)
|
||
- Pro Lauf ist genau ein Provider aktiv. Kein Fallback, keine Parallelnutzung.
|
||
- `.properties` bleibt die einzige Konfigurationswahrheit
|
||
- Konkrete Provider-Familie, Base-URL und Modellname sind **Konfiguration**, keine Architekturentscheidung.
|
||
|
||
## Verbindliche Modulstruktur (ab V2.0)
|
||
- `pdf-umbenenner-domain`
|
||
- `pdf-umbenenner-application`
|
||
- `pdf-umbenenner-adapter-in-cli`
|
||
- `pdf-umbenenner-adapter-in-gui`
|
||
- `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, keine HTTP-Kommunikation und **kein JavaFX**
|
||
- Application enthält keine technischen Implementierungsdetails und **keine JavaFX-Typen**
|
||
- Externe Zugriffe erfolgen ausschließlich über **Ports**
|
||
- Konkrete technische Implementierungen sind **Adapter**
|
||
- Adapter dürfen nicht direkt voneinander abhängen
|
||
- Die GUI ist ein **Inbound-Adapter** (`pdf-umbenenner-adapter-in-gui`) – sie wird **nicht** in Bootstrap vermischt
|
||
- Bootstrap bleibt verantwortlich für: Startmoduswahl, Konfigurationsauflösung, Objektgraph, kontrollierten Start des passenden Adapters, Exit-Code-Ableitung bei harten Startfehlern
|
||
- GUI-Code und JavaFX dürfen im **headless Pfad** nicht unnötig früh initialisiert oder geladen werden
|
||
- 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
|
||
- 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
|
||
|
||
## GUI-Leitplanken (verbindlich für alle V2.0-Arbeitspakete)
|
||
|
||
### Threadingmodell
|
||
- Jede potenziell blockierende Operation (Modellabruf, technische Tests, Pfad-/Dateisystemprüfungen, SQLite-Prüfungen, Lesen/Schreiben der `.properties`) läuft auf einem **Hintergrund-Worker-Thread**
|
||
- UI-Updates erfolgen ausschließlich über den **JavaFX Application Thread** (`Platform.runLater`)
|
||
- Die GUI darf während laufender Hintergrund-Operationen **nicht einfrieren**
|
||
|
||
### GUI-Teststrategie
|
||
- **View-Modelle und Application-nahe GUI-Logik** werden mit JUnit unit-getestet; Fokus auf Zustandsübergängen, Validierungsregeln und Datenflüssen – nicht auf Rendering
|
||
- **GUI-Smoke-Tests** laufen unter **headless JavaFX (Monocle)** in der Maven-Test-Phase
|
||
- Kein TestFX, kein weiteres GUI-Testframework über Monocle hinaus
|
||
|
||
### GUI-Logging
|
||
- Der GUI-Adapter nutzt denselben Log4j2-Stack wie der headless Pfad
|
||
- Logformat und Log-Verzeichnis bleiben gegenüber dem headless Betrieb unverändert
|
||
- Mindesteinträge für GUI-nahe Ereignisse: Start- und Beendigungsereignisse der GUI, Modellabruf-Versuche (Provider, Erfolg/Misserfolg, **ohne API-Key**), Dateischreibvorgänge inkl. Zielpfad, Ergebnisse der Aktionen `Validieren` und `Technische Tests ausführen`, sowie alle schreibenden Korrekturen
|
||
|
||
### `--config`-Semantik
|
||
- Zeigt `--config <pfad>` im **GUI-Start** auf eine nicht existente Datei: Fehlermeldung, danach verhält sich die GUI so, als wäre `--config` nicht angegeben worden
|
||
- Zeigt `--config <pfad>` im **headless Start** auf eine nicht existente Datei: **harter Startfehler**, kein stiller Fallback
|
||
|
||
## JavaDoc-Standard (verbindlich für alle V2.0-Arbeitspakete)
|
||
Für jede **neu hinzugefügte** oder **substanziell geänderte** öffentliche Klasse, öffentliche Methode und jedes neue Java-Package gilt:
|
||
- **Klassen-JavaDoc**: Zweck, Verantwortung und Abgrenzung der Klasse
|
||
- **Methoden-JavaDoc**: Zweck, Parameter, Rückgabewert und dokumentierte Ausnahmen
|
||
- **`package-info.java`**: pro neuem Package, mit Kurzbeschreibung der Paketverantwortung
|
||
|
||
Ein Arbeitspaket ist erst fertig, wenn die betroffenen öffentlichen Klassen und Methoden dem JavaDoc-Standard entsprechen.
|
||
|
||
## 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
|
||
V1.1 ist vollständig umgesetzt, dokumentiert, getestet und freigegeben.
|
||
|
||
Der aktive Entwicklungsstand ist **V2.0**. Ziel ist der Ausbau um eine lokale JavaFX-Desktop-GUI als neuen Standardstart, ohne die bestehende Architektur, das Standalone-JAR-Betriebsmodell oder den headless Scheduler-Betrieb aufzugeben.
|
||
|
||
Die fachliche Kernverarbeitung des PDF-Umbenenners bleibt in V2.0 unverändert.
|
||
|
||
## 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
|
||
- Inkonsistente Proposal-Zustände werden **nicht stillschweigend geheilt**, sondern als technische Dokumentfehler behandelt
|
||
|
||
## Retry-Semantik
|
||
|
||
### Deterministische Inhaltsfehler
|
||
- **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
|
||
- 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
|
||
|
||
### 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
|
||
|
||
## Exit-Codes (verbindlich)
|
||
- **`0`**: normale erfolgreiche Beendigung eines headless Laufs sowie für das reguläre Beenden der GUI
|
||
- **`1`**: harte Start-, Bootstrap-, Verdrahtungs-, Konfigurations- oder Initialisierungsfehler, einschließlich ungültiger CLI-Verwendung, nicht existenter `--config`-Datei im headless Start und GUI-Startfehlern vor erfolgreicher Anzeige der Oberfläche
|
||
- Dokumentbezogene Verarbeitungsfehler im headless Lauf ändern dieses Exit-Code-Modell nicht
|
||
|
||
## Persistenz
|
||
|
||
Zwei-Ebenen-Modell – 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
|
||
- **Provider-Identifikator des aktiven KI-Providers für den Versuch**
|
||
|
||
**Invariante:** Der führende `PROPOSAL_READY`-Versuch wird nicht überschrieben. Jeder Lauf erzeugt einen **zusätzlichen** neuen Versuchseintrag.
|
||
|
||
**Rückwärtsverträglichkeit:** Bestehende Datenbestände bleiben lesbar, fortschreibbar und korrekt interpretierbar.
|
||
|
||
## Naming-Regel (verbindlich für alle Arbeitspakete)
|
||
In Implementierungen, Kommentaren und JavaDoc dürfen **keine** Meilenstein- oder Arbeitspaket-Bezeichner erscheinen:
|
||
|
||
- Verboten: `M1`, `M2`, …, `M13`
|
||
- Verboten: `AP-001`, `AP-002`, … `AP-0xx`
|
||
- Verboten: Versionsbezeichner wie `V1.0`, `V1.1`, `V2.0` in Code/JavaDoc
|
||
|
||
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 Arbeitspaket**
|
||
- **Kein Vorgriff** auf spätere 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
|
||
- Keine stillen Änderungen am bestehenden headless Batch-Betrieb
|
||
- GUI-Code darf den headless Pfad nicht unnötig früh initialisieren
|
||
|
||
## 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 (inkl. `package-info.java` für neue Packages) und Tests ergänzt sind
|
||
- der JavaDoc-Standard für alle neu hinzugefügten oder substanziell geänderten öffentlichen Klassen und Methoden eingehalten wurde
|
||
- keine Inhalte späterer Arbeitspakete 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:
|
||
- <Dateipfad>
|
||
- ...
|
||
- Build-Kommando: <verwendetes Kommando>
|
||
- Build-Status: ERFOLGREICH / FEHLGESCHLAGEN
|
||
- Offene Punkte: keine / <Beschreibung>
|
||
- Risiken: keine / <Beschreibung>
|
||
```
|
||
|
||
## 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 (Beispiel für vollständigen Reactor-Build ab V2.0):
|
||
`.\mvnw.cmd clean verify -pl pdf-umbenenner-domain,pdf-umbenenner-application,pdf-umbenenner-adapter-out,pdf-umbenenner-adapter-in-cli,pdf-umbenenner-adapter-in-gui,pdf-umbenenner-bootstrap --also-make`
|
||
- 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`
|
||
- 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
|
||
- 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`
|
||
|
||
## Konfigurationsparameter
|
||
Verbindlich zweckmäßige Parameter:
|
||
- `source.folder` – Quellordner
|
||
- `target.folder` – Zielordner (muss vorhanden oder anlegbar sein, Schreibzugriff erforderlich)
|
||
- `sqlite.file` – SQLite-Datenbankdatei
|
||
- `ai.provider.active` – aktiver KI-Provider (Pflicht)
|
||
- `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)
|
||
|
||
Pro Provider-Familie existiert ein eigener Parameter-Namensraum:
|
||
|
||
```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 (flache Schlüssel 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 → Namensraum `openai-compatible`, `ai.provider.active=openai-compatible`)
|
||
4. Datei in-place schreiben
|
||
5. Datei erneut laden und validieren
|
||
6. Erst danach den normalen Lauf fortsetzen
|
||
|
||
## Nicht-Ziele / Verbote
|
||
- kein manueller Verarbeitungslauf aus der GUI (erst V2.1+)
|
||
- kein DB-/Historien-Tab in der GUI (erst V2.x+)
|
||
- kein Kosten-Tracking (erst V2.x+)
|
||
- kein echter Mini-KI-Testaufruf mit fachlicher Antwortauswertung
|
||
- keine EXE, kein Installer
|
||
- 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** 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
|
||
- kein neues Konfigurationsformat
|
||
- keine Änderung der fachlichen Kernverarbeitung des PDF-Umbenenners
|
||
- keine Änderung der bestehenden Status-, Retry- oder Persistenz-Wahrheit
|
||
- keine stillen Änderungen am bestehenden headless Batch-Betrieb
|
||
- kein Sofort-Wiederholversuch außerhalb des Zielkopierpfads
|
||
- keine spekulativen Umbauten ohne konkreten Qualitäts- oder Konsistenzbezug
|
||
- kein großflächiges Refactoring ohne nachweisbaren Defektbezug
|