docs: Dokumentation nach Projektstandard, MIT-Lizenz

- README knapp: Zweck, Schnellstart, Stand, Abschnitt "Documentation", Lizenz
- FUNKTIONSWEISE.md neu: Aufbau, Datenfluss (Mermaid), Entscheidungsregel,
  Normalform, elastischer Bildvergleich, Quellen, Sicherheit, Messungen,
  Designentscheidungen, Grenzen
- BEDIENUNGSANLEITUNG gegliedert: Installation, Modellserver, Benutzung,
  Konfiguration (Umgebungsvariablen, workspace.json), Betrieb, Werkzeuge,
  Fehlersuche mit echten Meldungen und Rückgabecodes
- CHANGELOG im Format Keep a Changelog mit "Beim Update zu tun"
- LICENSE (MIT)
- cli.py: Hilfetexte beschreiben die Regel p2t und z-ai/glm-4.6v statt des
  Pixelvergleichs und gemini-2.5-flash
- requirements.txt: requests ergänzt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-20 12:26:49 +02:00
commit 6a0e9587f5

View file

@ -1,136 +1,151 @@
# Changelog
# Änderungsprotokoll
## Unveröffentlicht
Alle nennenswerten Änderungen an formula_img2latex. Format nach
[Keep a Changelog](https://keepachangelog.com/de/1.1.0/), Versionen nach
[Semantic Versioning](https://semver.org/lang/de/) (vor 1.0: Nebenversion = möglicher Bruch).
Messergebnisse im Einzelnen: [FUNKTIONSWEISE.md, Messungen](FUNKTIONSWEISE.md#12-messungen).
## [Unreleased]
Alle Formeln eines PDF-Buchs, auch im Fließtext, und etwa dreimal schneller.
- **pdf2md --formulas** (Nachbarprojekt): Die Formelerkennung von pix2text (MFD) findet jede Formel auf der
Seite, eingebettet oder abgesetzt, auch in Merkkästen. Sie wird zeichengenau aus dem Text geschnitten
(300 dpi) und mit Seite, Rechteck und PDF-Text in `formulas-*.json` vermerkt. "Formel"-Boxen mit Text
werden zu Text, solche mit Kurven zu Grafiken. formula_img2latex liest die Liste
(`sources/pdf2md.listed`). Corral, 10 % der 9239 Formeln: **79 % automatisch** (im Text 83 %).
- **Eingebettete Formeln:** Ein Satzzeichen am Ende wird vor dem Vergleich abgetrennt und als Text hinter
die Formel gesetzt (`final_suffix`).
- **Normalform:** `\underset{…}{\lim}` = `\lim_{…}`, Gleichungsnummer am Ende = `\tag`, `\textbf` als
Fettdruck, `\cfrac` = `\frac` (pix2text schreibt `\dfrac`), wörtliches `\n` aus Modellantworten entfällt.
- **Tempo** (Pilot 869 Formeln: 70 → ~24 min):
- Markdown-Verweise und Ausschnitte nur einmal lesen (`crops/`);
- pix2text gebündelt nach Pixelbudget, auf der freiesten GPU, einmal geladen;
- Lesen und Prüfen überlappen, die Prüfprozesse starten per `forkserver`;
- Qwen mit 8 parallelen Anfragen (`llama-server --parallel 8 -c 32768`);
- pdflatex beim Entscheiden nur, wenn gleiche Bilder möglich sind;
- kein neuer Scan beim Fortsetzen;
- je Paket nur dessen Datensätze laden;
- Zeiten je Stufe in der Statuszeile.
- **Bildprüfung:** Originale höchstens 1600 px breit, über 2,5 MP nicht, Lesarten mit mehr als 2,5-fach
falschen Proportionen sofort abgelehnt. Vorher hielten einzelne Formeln den Lauf über 10 Minuten auf.
- **Gemessen und verworfen:**
- PDF-Textebene als Bestätigung: 12 von 319 widersprachen Qwen, fehlende Punkte und Indizes; Schalter
`pdftext` bleibt aus.
- pix2texts eigene Sicherheit: Fehler auch bei 1,0.
- Qwen3-VL-8B: nicht schneller als das MoE-30B-Modell (3B aktiv), etwas schlechter.
- **Offen:** Formeln in Tabellen.
### Neu
- **Formeln im Fließtext** über `pdf2md --formulas` (Nachbarprojekt): Die Formelerkennung von pix2text (MFD)
findet jede Formel auf der Seite, auch in Merkkästen; pdf2md schneidet sie zeichengenau aus (300 dpi) und
vermerkt Seite, Rechteck und PDF-Text in `formulas-*.json`. formula_img2latex liest die Liste
(`sources/pdf2md.listed`). Corral, Stichprobe 10 % von 9239 Formeln: 79 % automatisch (im Text 83 %).
- Ein Satzzeichen am Ende einer Formel im Text wird vor dem Vergleich abgetrennt und als Text hinter die
Formel gesetzt (`final_suffix`).
- Normalform: `\underset{…}{\lim}` = `\lim_{…}`, Gleichungsnummer am Ende = `\tag`, `\textbf` als Fettdruck,
`\cfrac` = `\frac`, wörtliches `\n` aus Modellantworten entfällt.
- Schalter `pdftext` (aus): Die PDF-Textebene einer flachen Formel darf pix2text bestätigen.
- `LICENSE` (MIT) und `FUNKTIONSWEISE.md` (Aufbau, Datenfluss, Designentscheidungen, Grenzen).
## 0.4.0 – 2026-10-09
### Geändert
- **Tempo** (Pilot 869 Formeln: 70 → ~24 Minuten): Markdown-Verweise und Ausschnitte nur einmal lesen
(`crops/`); pix2text gebündelt nach Pixelbudget auf der freiesten GPU, einmal geladen; Lesen und Prüfen
überlappen, die Prüfprozesse starten per `forkserver`; Qwen mit 8 parallelen Anfragen; pdflatex beim
Entscheiden nur, wenn gleiche Bilder möglich sind; kein neuer Scan beim Fortsetzen; je Paket nur dessen
Datensätze laden; Zeiten je Stufe in der Statuszeile.
- Bildprüfung: Originale höchstens 1600 px breit, über 2,5 MP nicht verglichen, Lesarten mit mehr als
2,5-fach falschen Proportionen sofort abgelehnt (einzelne Formeln hielten den Lauf über 10 Minuten auf).
- Dokumentation nach dem Projektstandard gegliedert: README knapp mit Abschnitt „Documentation“,
Bedienungsanleitung mit Konfiguration, Betrieb und Fehlersuche, Hintergrund und Messungen in
`FUNKTIONSWEISE.md`.
- Hilfetexte der Kommandozeile beschreiben die Regel `p2t` statt des Pixelvergleichs; Cloud-Standard
`z-ai/glm-4.6v` statt `google/gemini-2.5-flash`.
### Behoben
- `requirements.txt` enthält `requests` (von den Modell-Engines benötigt).
Gemessen und verworfen: PDF-Textebene als Bestätigung (12 von 319 widersprachen Qwen), pix2texts eigene
Sicherheit (Fehler auch bei 1,0), Qwen3-VL-8B (nicht schneller, etwas schlechter).
### Beim Update zu tun
- `pip install -r requirements.txt`.
- Qwen-Server mit `--parallel 8 -c 32768` neu starten (BEDIENUNGSANLEITUNG, Abschnitt 2).
- Für Formeln im Fließtext: aktuelles pdf2md verwenden und das Buch mit `--formulas` neu umwandeln.
- Bestehende Arbeitsordner bleiben gültig; Lesarten werden nicht neu gefragt.
## [0.4.0] – 2026-10-09
Bessere Normalform: Lesarten, die sich nur in der Schreibweise unterscheiden, gelten als gleich.
Göllmann (400 Formeln mit bekannter Lösung, gleiche Lesarten): **+17 automatisch, weiterhin 0 falsch**.
Göllmann (400 Formeln mit bekannter Lösung, gleiche Lesarten): +17 automatisch, weiterhin 0 falsch.
- **Mehrzeilige Formeln:** gleich bei gleichen Zeilen mit gleichen Zeichen, egal in welchem Rahmen
### Neu
- **Mehrzeilige Formeln** sind gleich bei gleichen Zeilen mit gleichen Zeichen, egal in welchem Rahmen
(`aligned`/`gathered`/`split` mit `&` oder nur `\\`; `cases` = `\left\{array\right.` =
`\left\{aligned\right.`); eine leere letzte Zeile zählt nicht. In Matrizen trennt `&` weiter Spalten.
- **Argumente nach Argumentzahl:** Eine Gruppe ist nur Argument, wenn der Befehl noch eines erwartet
(`t^{2}\,{\sqrt{2}}` = `t^2\sqrt{2}`, `\Delta{x_{n}}` = `\Delta x_n`).
- **Weitere Gleichsetzungen:** `\cdot\cdot\cdot` und `...` = `\dots`, `\root3\of{x}` = `\sqrt[3]{x}`,
- Weitere Gleichsetzungen: `\cdot\cdot\cdot` und `...` = `\dots`, `\root3\of{x}` = `\sqrt[3]{x}`,
`\left.`/`\right.` entfallen.
- **Messung genauer:** Der Wahrheitsvergleich nutzt dieselbe Normalform; richtige mehrzeilige Lesarten
zählten bisher als falsch (pix2text allein richtig: Band 2 jetzt 45/50 und 47/50).
- **Ergebnis:** Band 1 89 % / 88 % automatisch (bisher 86 % / 85 %), Band 2 44 und 45 von 50 (bisher 39
und 43), 0 falsch.
- **Strukturvergleich mit sympy** (`structure.py`, neu, optional, aus): gleicher unausgewerteter
Ausdrucksbaum, nichts umgerechnet; Relationen nie an sympy, Zeichen durch Platzhalter geschützt.
Brachte vor der neuen Normalform +1 Formel, danach nichts – `structural` = 1 bzw.
`FORMULA_STRUCTURAL=1` schaltet ihn ein (`pip install sympy lark`).
- **Bild-Schiedsrichter** (`verify.image_arbiter`, gemessen, aus): bei „Qwen = Gemma gegen pix2text“
entscheidet der Bildbeleg. +11 Formeln ab Schwelle 8, aber der gemeinsame Fehler `\mathcal{E}_r`
bekam Beleg 7,2 – zu knapp. Einstellungen `arbiter`, `arbiter_margin`.
- **Prompt-Stilvorgabe** getestet und verworfen (Band 2: 44/44 statt 44/45; die Modelle schrieben nach
`\\` ein wörtliches `\n`). Prompt-Version bleibt 2, gespeicherte Lesarten bleiben gültig.
- **Werkzeuge:** `tools/vergleich_bericht.py` (Vorher/Nachher-Seite zweier Läufe), `regeltest.py
--refresh` (Engines trotz `--reuse` neu fragen) und `--arbiter`; `calibrate` misst den
Schiedsrichter (Werte je Fall, Schwellen) und listet nur strukturell gefundene Übereinstimmungen;
`tools/buch_bericht.py` (Ergebnisseite eines ganzen Buchs: jede Formel mit Original, gesetztem
LaTeX, Status, Begründung und allen Lesarten, filterbar).
- **Erstes ganzes PDF-Buch** (Corral, *Elementary Calculus*, 346 Seiten, pdf2md): 1150 Ausschnitte,
**429 automatisch ersetzt (37 %)**, 633 Review, 61 keine Formel. Gefundene und behobene Probleme:
- pix2text schreibt hier Brüche als `\cfrac`: in der Normalform = `\frac`, beim Bereinigen zu
`\dfrac` (Pandoc kennt `\cfrac` nicht und ließ die Formel als TeX-Text stehen).
- Qwen und Gemma schreiben Zeilenumbrüche als wörtliches `\n` (`\begin{aligned}\n…`): wird zu
Leerraum (`tex.fix_literal_newlines`), echte Befehle wie `\nu`, `\neq` bleiben.
- 600-dpi-Ausschnitte bis 3800 × 2700 Pixel: Qwen lehnte sie ab („400 Bad Request“, Kontext voll),
eine ganzseitige Abbildung (33 MP) brachte den Bildvergleich zum Absturz. Jetzt: Bilder für die
Modelle höchstens 1600 Pixel lang, Bildvergleich nur bis 4 MP (größte übernommene Formel: 1,7 MP).
- Fehlgeschlagene Modellanfragen werden beim nächsten Lauf wiederholt (zählten als „schon gefragt“).
- Göllmann danach unverändert: 0 falsch.
- Grenze: pdf2md schneidet in diesem Buch auch Merkkästen mit Text, Tabellen und ganze
Herleitungsblöcke als „Formel“ aus; sie bilden den Großteil des Reviews.
- **Strukturvergleich mit sympy** (`structure.py`, optional, aus): gleicher unausgewerteter
Ausdrucksbaum. Einschalten mit `structural` = 1 bzw. `FORMULA_STRUCTURAL=1`.
- **Bild-Schiedsrichter** (`verify.image_arbiter`, aus): bei „Qwen = Gemma gegen pix2text“ entscheidet
der Bildbeleg. Einstellungen `arbiter`, `arbiter_margin`.
- Werkzeuge: `tools/vergleich_bericht.py` (Vorher/Nachher-Seite), `tools/buch_bericht.py`
(Ergebnisseite eines ganzen Buchs), `regeltest.py --refresh` und `--arbiter`.
## 0.3.0 – 2026-10-09
### Geändert
- Eine Klammergruppe ist nur Argument, wenn der Befehl noch eines erwartet (`t^{2}\,{\sqrt{2}}` =
`t^2\sqrt{2}`, `\Delta{x_{n}}` = `\Delta x_n`).
- Der Wahrheitsvergleich der Messung nutzt dieselbe Normalform (richtige mehrzeilige Lesarten zählten
bisher als falsch).
- Bilder für die Modelle höchstens 1600 Pixel lang.
Neue Standardregel `p2t`: **pix2text liest zuerst, Qwen bestätigt, Gemma nur bei Uneinigkeit**; GLM (Cloud)
wird nicht mehr benutzt.
### Behoben
- pix2texts `\cfrac` wird beim Bereinigen zu `\dfrac` (Pandoc kennt `\cfrac` nicht und ließ die Formel als
TeX-Text stehen).
- Wörtliches `\n` in Antworten von Qwen und Gemma wird zu Leerraum (`tex.fix_literal_newlines`).
- Sehr große Ausschnitte: Qwen lehnte sie ab („400 Bad Request“), eine ganzseitige Abbildung brachte den
Bildvergleich zum Absturz.
- Fehlgeschlagene Modellanfragen werden beim nächsten Lauf wiederholt (zählten als „schon gefragt“).
Gemessen und verworfen: Strukturvergleich (nach der neuen Normalform kein Gewinn), Bild-Schiedsrichter
(der gemeinsame Fehler `\mathcal{E}_r` bekam Beleg 7,2), Prompt-Stilvorgabe (keine Verbesserung).
Erstes ganzes PDF-Buch: Corral, *Elementary Calculus*, 1150 Ausschnitte, 429 automatisch (37 %).
### Beim Update zu tun
- Nichts Pflichtiges. Prompt-Version bleibt 2, gespeicherte Lesarten bleiben gültig; `run` rechnet die
Entscheidungen mit der neuen Normalform neu.
- Optional für den Strukturvergleich: `pip install sympy lark`.
## [0.3.0] – 2026-10-09
Neue Standardregel `p2t`: pix2text liest zuerst, Qwen bestätigt, Gemma nur bei Uneinigkeit; GLM (Cloud) wird
nicht mehr benutzt. Göllmann Band 1: 86 % / 85 % automatisch, 0 falsch (bisher 78 % / 70 %).
### Neu
- **pix2text** (Formel-OCR MFR 1.5, ONNX) als Engine `p2t`, im Prozess, auf der GPU mit `onnxruntime-gpu`
(`FORMULA_P2T_DEVICE`: `auto`, `cpu`, `cuda:N`). Allein am häufigsten richtig (Göllmann Band 1: 90 % /
85 %) und am schnellsten (0,1 s/Formel auf der GPU, Qwen 0,7 s, Gemma 1,8 s).
- **Regel:** übernommen wird immer pix2texts Lesart (trifft den Fettdruck am besten), wenn Qwen sie
bestätigt oder – nur bei Uneinigkeit gefragt – Gemma. Qwen und Gemma gemeinsam gegen pix2text gehen
an einen Menschen (so kamen an Band 1 die gemeinsamen Fehler der beiden Bildmodelle durch). Der
Schlusspunkt muss bestätigt sein. Bild-Veto und Pandoc wie bisher, geprüft auf pix2texts Lesart.
Die alte Regel bleibt als `"consensus_rule": "vlm3"` in `workspace.json` wählbar.
- **pix2text-Ausgabe bereinigt:** Leerzeichen mit `post_process` aus pix2tex (installiert mit
`--no-deps`), Fettschreibweisen `\mathrm{\boldmath~ x ~}` / `\mathrm{\bf~ r o t}` →
`\boldsymbol{x}` / `\mathbf{rot}`. An 400 Lesarten geprüft: gleiches gesetztes Bild.
- **Normalform:** `\operatorname{l i m}` = `\lim`, `\ddot{u}` in Text = ü, `^{\prime}` = `'`,
abschließendes `\\` vor `\end`, `\begin{array}[t]`, `\mathop{…}`.
- **calibrate:** beliebig viele Engines (`--engines`), Regel-Tabelle, `--reuse` rechnet aus einem
früheren Bericht ohne Modellabfragen; wahre Formeln aus dem alt-Text werden bereinigt
(einzeiliges `aligned`, `\mathop{}\!\mathrm{d}`, upgreek).
- **Werkzeuge:** `tools/zeittest.py` (Zeit und Trefferquote je Tool), `tools/regeltest.py` (Standardregel
an Formeln mit bekanntem TeX, Seite zum Mitbeurteilen; `--reuse`, `--exclude`).
- **Messung:** Göllmann Band 1 (2 × 150) 86 % / 85 % automatisch, 0 falsch (bisher 78 % / 70 %);
Band 2, zwei frische Stichproben zu 50: 78 % und 86 % automatisch, 0 falsch.
(`FORMULA_P2T_DEVICE`: `auto`, `cpu`, `cuda:N`).
- **Regel `p2t`:** übernommen wird pix2texts Lesart, wenn Qwen sie bestätigt oder – nur bei Uneinigkeit
gefragt – Gemma. Qwen und Gemma gemeinsam gegen pix2text gehen an einen Menschen.
- `calibrate`: beliebig viele Engines (`--engines`), Regel-Tabelle, `--reuse` ohne Modellabfragen.
- Werkzeuge: `tools/zeittest.py`, `tools/regeltest.py`.
## 0.2.0 – 2026-10-07
### Geändert
- pix2text-Ausgabe bereinigt: Leerzeichen mit `post_process` aus pix2tex, Fettschreibweisen
`\mathrm{\boldmath~ x ~}` → `\boldsymbol{x}`. An 400 Lesarten geprüft: gleiches gesetztes Bild.
- Normalform: `\operatorname{l i m}` = `\lim`, `\ddot{u}` in Text = ü, `^{\prime}` = `'`, abschließendes
`\\` vor `\end`, `\begin{array}[t]`, `\mathop{…}`.
Entscheider ist jetzt der **Konsens dreier Bildmodelle** statt eines Pixelvergleichs.
### Beim Update zu tun
- pix2text installieren: `pip install "pix2text[multilingual]"`, `pip install --no-deps pix2tex munch`,
für die GPU `pip uninstall -y onnxruntime && pip install onnxruntime-gpu`.
- Bestehende Arbeitsordner: `run` erneut aufrufen; pix2text liest nach, Qwen-Lesarten bleiben gültig.
- Wer die Regel mit GLM behalten will: `"consensus_rule": "vlm3"` in `workspace.json`.
- **Annahmeregel:** jedes Zeichen richtig und an der richtigen Stelle; Abstände, Längen, Schriftgröße,
kursiv/aufrecht und Fettdruck egal.
- **Konsens:** Qwen3-VL-30B-A3B (lokal) = Gemma-4-26B-A4B (lokal) = GLM-4.6V (OpenRouter, andere
Modellfamilie); Pandoc muss die Formel umsetzen; grobes Bild-Veto (elastischer Vergleich,
Ähnlichkeit ≥ 0,65). Bei 2:1 entscheidet ein Mensch.
- **`consensus.py`:** Normalform auf Baumbasis (Abstände, `\left`/`\right`, freistehende Klammern,
`\vec`/`\overrightarrow`, `\frac`/`\dfrac`, `\iff`/`\Leftrightarrow`, Matrix-Umgebungen, TeX-Umlaute,
`\atop`/`\substack`, kursiv/aufrecht, fett/normal) und Render-Gleichheit als Rückfallebene.
- **Engines:** zweite lokale Engine `local2`; Token-Wahrscheinlichkeiten aus Logprobs; Nachdenken
abgeschaltet (Gemma ~10× schneller, GLM besser und ~25× billiger); Antworten auf 800 Tokens begrenzt;
Prompt fragt ausdrücklich nach Fettdruck; Prompt-Version und Nachdenk-Einstellung im Cache-Schlüssel.
- **`run`:** in Paketen zu 50 mit Statuszeile; beide lokalen Modelle parallel; GLM nur für Einige;
geprüft wird nur die übernommene Lesart; Prüfergebnisse mit Verfahrensversion.
- **Bildvergleich:** elastische Ausrichtung (DTW über Spalten und Zeilen, Dehnen kostet proportional zur
Tinte); layouttreue Prüfvarianten und rauschnormierter Kontrast im Pixel-Modus (`decide=pixel`).
- **apply:** deutsches Dezimalkomma `3{,}6`.
- **Behoben:** Gleichungsnummern wurden aus alten, verworfenen Lesarten übernommen (erfundene „(3.7)“);
sie kommen jetzt nur aus der übernommenen Lesart. Gleichzeitige Speicherungen zweier Engines sind
abgesichert. Verify stürzte bei Formeln ohne aktuelle Lesart ab.
- **Werkzeuge:** `calibrate --consensus`, `tools/vergleich.py` (50er-Stichprobe mit Bildern),
`tools/konsens_bericht.py`; Ausgaben in `vergleich/` (nicht versioniert).
- **Messung** (2 × 150 Formeln mit bekanntem TeX): 63–68 % automatisch, 0 falsch.
Gehrke-Brückenkurs: 942 von 1505 automatisch (63 %), 62 von 62 geprüften korrekt.
## [0.2.0] – 2026-10-07
## 0.1.0 – 2026-10-07
Entscheider ist der Konsens dreier Bildmodelle statt eines Pixelvergleichs.
Gehrke-Brückenkurs: 942 von 1505 automatisch (63 %), 62 von 62 geprüften korrekt.
Erste Fassung: scan, recognize (ein Vision-Modell), verify mit Pixelvergleich und Kontrasttest gegen
Verwechslungsvarianten, Review-Galerie, apply/revert, calibrate. Sicher (0 Falsch-Annahmen), aber an
echten Büchern nur 1–2 % automatisch.
### Neu
- **Konsens:** Qwen3-VL-30B-A3B (lokal) = Gemma-4-26B-A4B (lokal) = GLM-4.6V (OpenRouter); Pandoc muss die
Formel umsetzen; grobes Bild-Veto (elastischer Vergleich, Ähnlichkeit ≥ 0,65).
- `consensus.py`: Normalform auf Baumbasis und Render-Gleichheit als Rückfallebene.
- Zweite lokale Engine `local2`; Token-Wahrscheinlichkeiten aus Logprobs.
- `run` in Paketen zu 50 mit Statuszeile; `calibrate --consensus`; `tools/vergleich.py`,
`tools/konsens_bericht.py`.
- `apply`: deutsches Dezimalkomma `3{,}6`.
### Geändert
- Nachdenken der Modelle abgeschaltet (Gemma ~10× schneller, GLM besser und ~25× billiger); Antworten auf
800 Tokens begrenzt; Prompt fragt ausdrücklich nach Fettdruck.
- Elastischer Bildvergleich (DTW über Spalten und Zeilen, Dehnen kostet proportional zur Tinte).
- Geprüft wird nur die übernommene Lesart; Prüfergebnisse tragen eine Verfahrensversion.
### Behoben
- Gleichungsnummern wurden aus alten, verworfenen Lesarten übernommen (erfundene „(3.7)“).
- Gleichzeitiges Speichern zweier Engines; Absturz bei Formeln ohne aktuelle Lesart.
### Beim Update zu tun
- Zwei llama.cpp-Server starten (Qwen auf Port 8011, Gemma auf Port 8012) und Gemma laden
(BEDIENUNGSANLEITUNG, Abschnitte 1 und 2); `OPENROUTER_API_KEY` setzen.
- Arbeitsordner aus 0.1.0: Standard ist jetzt der Konsens; den alten Entscheider behält
`"decide": "pixel"` in `workspace.json`.
## [0.1.0] – 2026-10-07
Erstveröffentlichung: scan, recognize (ein Bildmodell), verify mit Pixelvergleich und Kontrasttest gegen
Verwechslungsvarianten, Review-Galerie, apply/revert, calibrate. Sicher (0 Falsch-Annahmen), aber an echten
Büchern nur 1–2 % automatisch.