Claude commited on
Commit
e4838d8
·
unverified ·
1 Parent(s): 05d1699

feat(sprint-A14): refonte intégrale de SPECS.md (B-12)

Browse files

Sprint A14 — Refonte SPECS.md vers la v2.0 (3 PJ, item B-12).

État avant : SPECS v1.0 (mars 2025 + addendum Sprints 16-30) qui :
- promettait 9 fonctionnalités jamais livrées (Kraken, AWS Textract,
Calamari, OCRopus, moteur custom YAML, export PDF/ALTO/PAGE/images,
picarones estimate, recommandation auto, k-means, annotations
inline, badge SVG, dataset 100 docs, prompt latin) ;
- ignorait ~25 modules majeurs livrés depuis Sprint 30.

État après : 12 sections cohérentes avec le code réel au 2 mai 2026.

Sections principales :

§1 Vision et positionnement — banc d'essai, neutralité éditoriale,
contributions scientifiques (registre typé, BaseModule, narrative
anti-hallucination, Friedman+Nemenyi+CDD, Pareto, philologique).

§2 Architecture en 3 cercles — règle de dépendance enforcée par
tests/core/test_circle_dependencies.py (Sprint A3) ; cartographie
des sous-packages.

§3 Module 1 — Corpus et imports : 5 formats GT (TEXT/ALTO/PAGE/
ENTITIES/READING_ORDER, Sprint 32), 7 sources d'import, gestion
des fallbacks via Fact IMPORTER_FALLBACK_TRIGGERED.

§4 Module 2 — 5 adapters OCR avec confidence native exposée
(Sprints 47-51), execution_mode IO/CPU pour le runner.

§5 Module 3 — 3 modes pipelines OCR+LLM historiques + pipelines
composables YAML (Sprint 63-70) avec compute_at_junction
automatique. Détection over-normalisation : modernisation
lexicale, absorption d'erreur, delta Flesch, anchor score.

§6 Module 4 — catalogue exhaustif des métriques en 3 familles
(classique, philologique, comparaison & décision) avec leur
jonction de types et leur source primaire. ~30 métriques
listées (vs ~10 dans v1).

§7 Module 5 — rapport HTML : 5 vues + sections globales
(synthèse narrative, CDD, inter-engine, Pareto, leviers),
panneaux latéraux (glossaire 25 entrées, mode avancé),
accessibilité WCAG 2.1 AA (Sprint A6/A7).

§8 Module 6 — interface web FastAPI + CLI 15 commandes (incl.
workflows pré-câblés diagnose/economics/edition).

§9 Reproductibilité et sécurité — snapshots Sprint 27, lock files
Sprint A8, release pipeline Sprint A9, mode public + CSRF +
defusedxml + zip-slip + RGPD Sprint A11.

§10 LIMITES ASSUMÉES ET NON-FONCTIONNALITÉS — section centrale
qui liste explicitement les 9 promesses v1 abandonnées avec
leur raison. Marquée par les balises HTML
<!-- specs-check: known-abandoned-{start,end} --> consommées
par le test A2 test_specs_consistency.

§11 Roadmap — pointe CHANGELOG, evolution-2026, audits/.

§12 Migration v1 → v2 — annexe historique : table de migration
ligne par ligne pour les lecteurs qui avaient pris connaissance
de SPECS v1.

Tests :
- tests/docs/test_specs_consistency.py (Sprint A2) : 10/10 verts
avec la nouvelle structure (bloc known-abandoned).
- Aucune régression attendue (changement purement documentaire).

SPECS passe de 761 lignes (v1 + addendum) à 839 lignes (v2) — +10 %
mais couverture 100% du code réel et les non-fonctionnalités sont
explicitement listées.

Files changed (1) hide show
  1. SPECS.md +718 -667
SPECS.md CHANGED
@@ -1,799 +1,850 @@
1
- # Picarones — Spécifications Fonctionnelles et Techniques
2
 
3
- > **Plateforme de comparaison et d'évaluation de moteurs OCR/HTR et de pipelines OCR+LLM pour documents patrimoniaux**
 
4
  >
5
- > Version 1.0 — Mars 2025
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  ---
8
 
9
  ## Table des matières
10
 
11
- 1. [Vision générale et positionnement](#1-vision-générale-et-positionnement)
12
- 2. [Architecture générale](#2-architecture-générale)
13
- 3. [Module 1 — Gestion des corpus et imports](#3-module-1--gestion-des-corpus-et-imports)
14
- 4. [Module 2 — Adaptateurs moteurs OCR](#4-module-2--adaptateurs-moteurs-ocr)
15
- 5. [Module 3 — Pipelines OCR+LLM](#5-module-3--pipelines-ocrllm)
16
- 6. [Module 4 — Métriques et analyse](#6-module-4--métriques-et-analyse)
17
- 7. [Module 5 — Rapport interactif HTML](#7-module-5--rapport-interactif-html)
18
- 8. [Module 6 — Interface de lancement et CLI](#8-module-6--interface-de-lancement-et-cli)
19
- 9. [Fonctionnalités avancées](#9-fonctionnalités-avancées)
20
- 10. [Plan de développement](#10-plan-de-développement)
21
- 11. [Exigences non fonctionnelles](#11-exigences-non-fonctionnelles)
 
22
 
23
  ---
24
 
25
- ## 1. Vision générale et positionnement
26
 
27
  ### 1.1 Problématique
28
 
29
- Les équipes OCR/HTR travaillant sur des fonds patrimoniaux (manuscrits, imprimés anciens, archives) disposent d'un paysage de moteurs hétérogène — moteurs locaux (Tesseract, Pero OCR, Kraken), solutions cloud (Mistral OCR, Google Vision, AWS Textract), modèles fine-tunés maison — sans outil unifié pour les comparer rigoureusement sur leurs propres corpus.
30
-
31
- Les outils existants (ocrevalUAtion, dinglehopper) sont soit obsolètes, soit limités au CER/WER, soit non adaptés aux spécificités des documents historiques : glyphes anciens, ligatures, abréviations, graphies variables, pathologies d'image.
32
-
33
- À cela s'ajoute une question de recherche émergente : **est-ce qu'une couche de correction par LLM améliore réellement la sortie OCR, de combien, sur quels types d'erreurs ?** Aucun outil existant ne permet de tester et mesurer cela rigoureusement.
34
-
35
- **Picarones** comble ce vide en proposant une plateforme complète, open-source, pensée pour le milieu patrimonial, capable de comparer des moteurs OCR seuls **et** des pipelines OCR+LLM.
36
-
37
- ### 1.2 Objectifs stratégiques
38
-
39
- - Permettre une évaluation rigoureuse, reproductible et multi-dimensionnelle des moteurs OCR/HTR sur des corpus patrimoniaux réels
40
- - Évaluer l'apport réel des LLMs en post-correction OCR, en termes de qualité
41
- - Produire des rapports interactifs exploitables par des profils variés : ingénieurs, chercheurs, responsables de projets de numérisation
42
- - S'intégrer dans les workflows patrimoniaux existants (IIIF, eScriptorium, HTR-United, Gallica)
43
- - Offrir une base extensible pour le suivi longitudinal de la qualité OCR dans le temps
44
-
45
- ### 1.3 Utilisateurs cibles
46
-
47
- | Profil | Besoins principaux |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  |---|---|
49
- | Ingénieur OCR/ML | Pipeline programmatique, métriques fines, export JSON/CSV, CI/CD |
50
- | Chargé de numérisation | Rapport visuel, comparaison simple A vs B, recommandation de moteur |
51
- | Responsable de projet | Vue agrégée, graphiques, export PDF, analyse coût/bénéfice des APIs |
52
- | Chercheur en humanités numériques | Métriques diplomatiques, corpus HTR-United, analyse des erreurs par catégorie |
53
- | Paléographe | Diff visuel sur l'image, annotation inline des cas difficiles |
54
-
55
- ### 1.4 Proposition de valeur unique
56
-
57
- Picarones est le seul outil combinant :
58
- 1. **Métriques adaptées aux documents historiques** (glyphes, ligatures, diacritiques, abréviations, normalisation diplomatique)
59
- 2. **Évaluation des pipelines OCR+LLM** avec mesure du delta de qualité
60
- 3. **Intégration native des standards bibliothéconomiques** (IIIF, ALTO, PAGE XML, HTR-United, eScriptorium, Gallica)
61
- 4. **Rapport interactif auto-contenu** exploitable sans compétences techniques
62
 
63
  ---
64
 
65
- ## 2. Architecture générale
66
-
67
- ### 2.1 Vue d'ensemble
68
 
69
  ```
70
- ┌──────────────────────────────────────────────────────────────────────────┐
71
- PICARONES │
72
- │ │
73
- │ ┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────┐ │
74
- │ │ Import / │ Pipeline │ │ Rapport │ │
75
- │ │ Corpus Mgmt │──▶│ Orchestrator │──▶│ Interactif │
76
- │ └─────────────────┘ └──────────────────────┘ └─────────────────┘ │
77
- │ ▲ │ │ │
78
- │ IIIF / Gallica ┌──────▼──────┐ HTML self-contained │
79
- │ HTR-United │ Moteurs │ Export PDF/CSV/ALTO │
80
- │ HuggingFace │ OCR │ │
81
- │ eScriptorium └──────┬──────┘ │
82
- │ Dossier local │ │
83
- │ ┌──────▼──────┐ │
84
- │ │ Couche │ │
85
- │ │ LLM │ ◀── optionnelle │
86
- │ │ (optionel) │ │
87
- │ └─────────────┘ │
88
- └──────────────────────────────────────────────────────────────────────────┘
89
  ```
90
 
91
- ### 2.2 Stack technique
92
-
93
- | Couche | Technologie | Justification |
94
- |---|---|---|
95
- | Backend / Pipeline | Python 3.11+ | Écosystème OCR mature, jiwer, Pillow, NumPy |
96
- | API serveur | FastAPI | Async, auto-documentation OpenAPI, léger |
97
- | Rapport interactif | HTML + Vanilla JS + Chart.js + diff2html | Zéro dépendance runtime, fichier unique transportable |
98
- | Configuration | YAML | Déclaration simple des moteurs et paramètres |
99
- | Stockage résultats | JSON + SQLite optionnel | Léger, portable, requêtable |
100
- | CLI | Click (Python) | Usage sans interface, intégration CI/CD |
101
-
102
- ### 2.3 Principes d'architecture
103
-
104
- - **Moteur-agnostique** : chaque moteur OCR ou LLM est un adaptateur interchangeable, déclaré en YAML
105
- - **Pipeline composable** : un "concurrent" peut être un moteur seul (`tesseract`), un pipeline (`tesseract → gpt-4o`), ou un LLM seul en mode zero-shot (`gpt-4o`)
106
- - **Pipeline idempotent** : les sorties sont cachées par hash d'image, relance partielle possible
107
- - **Rapport auto-contenu** : le fichier HTML final embarque toutes les données, lisible hors-ligne
108
- - **Traçabilité complète** : versions des moteurs, paramètres, prompts LLM utilisés, dates d'exécution — tout est loggé dans les métadonnées du rapport
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  ---
111
 
112
- ## 3. Module 1 — Gestion des corpus et imports
113
 
114
  ### 3.1 Formats de vérité terrain acceptés
115
 
116
- | Format | Extension | Usage typique |
117
- |---|---|---|
118
- | Texte brut parallèle | `image.jpg` + `image.gt.txt` | Convention Tesseract, HTR-United |
119
- | ALTO XML | `.alto.xml` | Standard bibliothèques nationales, eScriptorium export |
120
- | PAGE XML | `.page.xml` | Transkribus, OCRopus |
121
- | JSON HuggingFace | `dataset.json` | HuggingFace Datasets |
122
- | eScriptorium export | `.zip` (PAGE+images) | Export natif eScriptorium |
123
- | CSV simple | `image,texte_gt` | Exports maison, tableaux Callico |
124
-
125
- ### 3.2 Sources d'import
126
-
127
- #### 3.2.1 Dossier local
128
- Import d'un dossier contenant des paires image/GT. Détection automatique du format. Prévisualisation du corpus avant lancement (nombre de documents, longueur moyenne de GT, aperçu des images).
129
-
130
- #### 3.2.2 Import IIIF — fonctionnalité clé
131
-
132
- L'intégration IIIF est la fonctionnalité d'import la plus stratégique pour le contexte patrimonial. Elle permet d'accéder directement aux fonds numérisés de toutes les grandes bibliothèques sans téléchargement manuel.
133
-
134
- - Import par URL de manifeste IIIF v2 et v3
135
- - Sélection des canvas (pages) via interface de sélection visuelle
136
- - Récupération des annotations de transcription si le manifeste les contient
137
- - Compatibilité : Gallica (BnF), Bodleian, BL, BSB, e-codices, Europeana et tout entrepôt IIIF-compliant
138
- - Résolution configurable des images
139
-
140
- > **Exemple :** coller l'URL du manifeste Gallica d'un incunable, sélectionner 50 pages, lancer le benchmark. La GT est fournie séparément ou issue d'un export eScriptorium.
141
-
142
- #### 3.2.3 Import HuggingFace Datasets
143
- - Recherche et prévisualisation de datasets OCR/HTR
144
- - Filtrage par langue, type de script, époque, institution
145
- - Datasets patrimoniaux pré-référencés : IAM, RIMES, READ-BAD, Esposalles, Bozen-Baptism, datasets HTR-United
146
- - Import partiel : sous-ensemble aléatoire ou filtré
147
- - Cache local avec gestion des versions
148
 
149
- #### 3.2.4 Import HTR-United
150
- - Listing et recherche dans le catalogue HTR-United
151
- - Import direct des corpus publiés (Bréviaires, chartes médiévales, registres paroissiaux, presse ancienne...)
152
- - Lecture des métadonnées : langue, script, institution, époque, nombre de lignes
153
 
154
- #### 3.2.5 Import Gallica (API BnF)
155
- - Recherche dans Gallica par cote, titre, auteur, date
156
- - Récupération des images via API IIIF Gallica
157
- - Récupération de l'OCR Gallica existant comme moteur de référence ou GT partielle
158
 
159
- #### 3.2.6 Import eScriptorium
160
- - Connexion à une instance eScriptorium locale ou distante via API
161
- - Import de projets, documents et transcriptions
162
- - Export des résultats de benchmark vers eScriptorium
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  ### 3.3 Gestion des corpus
165
 
166
- - Corpus nommés et versionnés avec métadonnées descriptives
167
- - Tags : type de script (gothique, humanistique, caroline, textura, cursive, imprimé ancien...), langue, siècle, institution, état de conservation
168
- - Statistiques : distribution des longueurs de GT, histogramme des scores de qualité image, aperçu des caractères unicode présents
169
- - Partage de corpus (format JSON exportable/importable)
170
- - Corpus de référence fournis avec Picarones : 100 documents représentatifs multi-scripts pour benchmarks rapides
 
171
 
172
  ---
173
 
174
- ## 4. Module 2 — Adaptateurs moteurs OCR
175
 
176
  ### 4.1 Architecture des adaptateurs
177
 
178
- Chaque moteur OCR est un adaptateur Python standardisé exposant une interface commune. Ajouter un nouveau moteur = créer un fichier YAML de configuration et, si nécessaire, une classe Python de ~30 lignes.
 
 
 
 
 
179
 
180
- ### 4.2 Moteurs OCR supportés nativement
 
 
181
 
182
- | Moteur | Type | Priorité | Notes |
183
- |---|---|---|---|
184
- | Tesseract 5 | Local CLI | v1.0 | `pytesseract`, multi-langues, LSTM |
185
- | Pero OCR | Local Python | v1.0 | Excellent sur documents historiques |
186
- | Kraken | Local Python | v1.0 | Référence HTR manuscrits, compatible eScriptorium |
187
- | Mistral OCR | API REST | v1.0 | Mistral OCR 3, multimodal |
188
- | Google Vision | API REST | v1.1 | Document AI, bonne couverture unicode |
189
- | AWS Textract | API REST | v1.1 | Détection layout avancée |
190
- | Azure Document Intelligence | API REST | v1.1 | Anciennement Form Recognizer |
191
- | Calamari | Local Python | v1.1 | Basé TF, modèles pré-entraînés HTR |
192
- | OCRopus4 | Local Python | v1.2 | Historique, utile pour comparaison |
193
- | Moteur custom | CLI/API YAML | v1.0 | Déclaration YAML, aucun code requis |
194
-
195
- ### 4.3 Configuration d'un moteur (YAML)
196
-
197
- ```yaml
198
- # Moteur custom via CLI
199
- name: mon_ocr_interne
200
- type: cli
201
- command: "mon_ocr {input_image} --output {output_file} --lang fra"
202
- output_format: txt
203
- version_command: "mon_ocr --version"
204
-
205
- # Moteur via API REST
206
- name: api_ocr_bnf
207
- type: api
208
- endpoint: http://localhost:8080/ocr
209
- method: POST
210
- image_field: file
211
- response_path: $.result.text
212
- ```
213
 
214
- ### 4.4 Gestion de l'exécution
215
-
216
- - Parallélisation configurable : N moteurs tournent en parallèle
217
- - Cache des sorties par hash SHA-256 de l'image relance partielle possible
218
- - Timeout configurable par moteur, avec rapport d'erreur si dépassé
219
- - Retry automatique sur erreur transitoire (rate limit, timeout réseau) avec backoff exponentiel
220
- - Rapport d'avancement en temps réel : barre de progression par moteur, ETA
221
- - Mode dry-run : validation de la configuration sans lancer les moteurs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
 
223
  ---
224
 
225
- ## 5. Module 3 — Pipelines OCR+LLM
226
-
227
- > Ce module est la fonctionnalité la plus originale de Picarones. Il permet de tester l'apport réel d'une couche de correction LLM sur une sortie OCR, et de comparer des pipelines complets entre eux.
228
 
229
- ### 5.1 Concept de "concurrent"
230
 
231
- Dans Picarones, l'unité de comparaison est le **concurrent** — pas forcément un moteur OCR seul, mais n'importe quelle combinaison produisant du texte à partir d'une image :
 
 
232
 
233
- | Type de concurrent | Description | Exemple |
234
  |---|---|---|
235
- | OCR seul | Un moteur OCR classique | `tesseract` |
236
- | LLM zero-shot | Le LLM reçoit uniquement l'image | `gpt-4o` en mode vision |
237
- | OCR → LLM (texte) | Le LLM reçoit la sortie OCR brute et corrige | `tesseract mistral-large` |
238
- | OCR → LLM (image + texte) | Le LLM reçoit image ET sortie OCR | `pero_ocr → gpt-4o` |
239
- | OCR → LLM → LLM | Chaîne de correction en deux passes | `tesseract → llm1 → llm2` |
240
 
241
- Ce modèle composable permet de tester toutes les configurations imaginables et de mesurer l'apport exact de chaque couche.
 
 
242
 
243
- ### 5.2 LLMs supportés
244
 
245
- | LLM | Type | Modes supportés | Priorité |
246
- |---|---|---|---|
247
- | GPT-4o / GPT-4o mini | API OpenAI | texte seul, image+texte, zero-shot | v1.0 |
248
- | Claude Sonnet / Haiku | API Anthropic | texte seul, image+texte, zero-shot | v1.0 |
249
- | Mistral Large / Pixtral | API Mistral | texte seul, image+texte, zero-shot | v1.0 |
250
- | Llama 3 (via Ollama) | Local | texte seul | v1.1 |
251
- | Gemma / Phi (via Ollama) | Local | texte seul | v1.1 |
252
- | LLM custom | API REST YAML | configurable | v1.0 |
253
-
254
- ### 5.3 Modes de correction LLM
255
-
256
- #### Mode 1 — Post-correction texte brut
257
- Le LLM reçoit uniquement la sortie OCR textuelle et un prompt de correction. Le plus rapide.
258
 
259
- ```
260
- [Sortie OCR brute] ──▶ [LLM + prompt] ──▶ [Texte corrigé]
 
 
 
 
 
 
 
 
261
  ```
262
 
263
- **Usage typique :** correction rapide sur grand volume, LLM non multimodal (Llama local), test de la valeur ajoutée d'un LLM de correction pur.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- #### Mode 2 — Post-correction avec image
266
- Le LLM reçoit l'image originale ET la sortie OCR. Permet au LLM de vérifier visuellement les passages ambigus.
267
 
268
- ```
269
- [Image] ──────────────┐
270
-
271
- [Sortie OCR brute] ──▶ [LLM multimodal + prompt] ──▶ [Texte corrigé]
272
- ```
273
 
274
- **Usage typique :** meilleure qualité, test de la valeur ajoutée du contexte visuel pour la correction.
275
 
276
- #### Mode 3 Zero-shot LLM
277
- Le LLM reçoit uniquement l'image, sans sortie OCR préalable. Teste la capacité de transcription native du LLM.
 
 
 
278
 
279
- ```
280
- [Image] ──▶ [LLM multimodal + prompt] ──▶ [Transcription]
281
- ```
282
 
283
- **Usage typique :** évaluer si GPT-4o ou Claude peut remplacer un moteur OCR sur des documents patrimoniaux.
 
 
 
 
 
 
284
 
285
- ### 5.4 Système de prompts
286
 
287
- Les prompts LLM sont configurables, versionnés et font partie intégrante des métadonnées du rapport.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
 
289
- ```yaml
290
- # Configuration d'un concurrent OCR+LLM
291
- name: tesseract_gpt4o_correction
292
- type: pipeline
293
- steps:
294
- - engine: tesseract
295
- config:
296
- lang: fra
297
- psm: 6
298
- - llm: gpt-4o
299
- mode: text_and_image # text_only | text_and_image | zero_shot
300
- prompt: prompts/correction_medieval_french.txt
301
- temperature: 0.0
302
- max_tokens: 4096
303
- ```
304
 
305
- ```
306
- # prompts/correction_medieval_french.txt
307
- Tu es un expert en paléographie et en transcription de documents en français médiéval.
308
- On te fournit la sortie brute d'un moteur OCR et l'image originale du document.
309
- Ta tâche est de corriger les erreurs de transcription en te basant sur :
310
- - Le contexte linguistique (français médiéval, XVe siècle)
311
- - Les confusions visuelles typiques de l'OCR (rn/m, l/1, u/n, ſ/f...)
312
- - Les abréviations et ligatures médiévales visibles sur l'image
313
-
314
- Retourne UNIQUEMENT le texte corrigé, sans commentaire ni explication.
315
- Conserve fidèlement la graphie originale (ne modernise pas l'orthographe).
316
-
317
- OCR BRUT :
318
- {ocr_output}
319
- ```
320
 
321
- - Bibliothèque de prompts intégrée : prompts optimisés pour manuscrits médiévaux, imprimés anciens, cursives administratives, latin, documents mixtes
322
- - Versionning des prompts : le prompt exact utilisé est stocké dans le JSON de résultats
323
- - Comparaison de prompts : tester différents prompts sur le même concurrent OCR+LLM
324
 
325
- ### 5.5 Questions de recherche adressées par ce module
326
 
327
- Picarones permet de répondre empiriquement, sur vos propres corpus, à des questions qui font débat :
328
 
329
- 1. **Un LLM améliore-t-il systématiquement la sortie OCR ?** (Pas toujours il peut halluciner)
330
- 2. **Le mode image+texte est-il meilleur que texte seul ?** (Coût plus élevé, apport variable)
331
- 3. **Un LLM zero-shot peut-il remplacer un moteur OCR sur des documents anciens ?**
332
- 4. **Sur quels types d'erreurs le LLM apporte-t-il le plus ?** (Diacritiques ? Abréviations ? Hapax ?)
333
- 5. **Y a-t-il un risque de sur-normalisation ?** Le LLM modernise-t-il à tort la graphie médiévale ?
334
- 6. **Quel est le seuil de CER OCR en dessous duquel un LLM n'apporte plus rien ?**
335
- 7. **Quel est le seuil de CER OCR en dessous duquel un LLM n'apporte plus rien ?**
 
 
 
 
 
 
 
336
 
337
- ---
338
 
339
- ## 6. Module 4 Métriques et analyse
 
 
 
340
 
341
- > L'objectif est de fournir la vision la plus complète possible, adaptée aux spécificités des documents patrimoniaux — bien au-delà du CER/WER brut.
342
 
343
- ### 6.1 Métriques de base
 
 
 
 
344
 
345
- #### CER — Character Error Rate
346
- - CER brut (distance d'édition caractère / longueur GT)
347
- - CER avec normalisation Unicode NFC
348
- - CER sans distinction de casse
349
- - CER diplomatique : avec table de correspondances historiques (ſ=s, u=v, i=j...)
350
- - CER par ligne : distribution, médiane, percentiles P90/P95
351
- - Intervalles de confiance à 95% par bootstrap (1000 itérations)
352
 
353
- #### WER Word Error Rate
354
- - WER brut et normalisé
355
- - WER avec tokenisation historique (traits d'union, abréviations)
356
- - Match Error Rate (MER) et Word Information Lost (WIL)
357
 
358
- #### Métriques de précision/rappel
359
- - Précision et rappel au niveau caractère, mot, ligne
360
- - F1-score global et par classe de caractère
361
 
362
- ### 6.2 Métriques spécifiques aux documents patrimoniaux
 
 
 
 
 
 
363
 
364
- #### Glyphes et caractères spéciaux
365
- - **Matrice de confusion unicode** : quels caractères GT sont transcrits par quels caractères OCR — fingerprint de chaque moteur
366
- - **CER par bloc Unicode** : Latin de Base / Latin Étendu A & B / Diacritiques combinants / Formes de présentation latines
367
- - **Score ligatures** : fi, fl, ff, ffi, ffl, st, ct, œ, æ, ꝑ, ꝓ...
368
- - **Score abréviations** : taux de restitution correcte des formes abrégées
369
- - **Précision diacritiques** : taux de conservation des accents, cédilles, trémas
370
- - **Précision chiffres romains et arabes** séparément
371
 
372
- #### Analyse structurelle
373
- - **Score d'ordre de lecture** : les blocs sont-ils dans l'ordre logique ? Critique pour documents multi-colonnes, marginalia, réclames
374
- - **Taux de segmentation des lignes** : fusion abusive / fragmentation — indépendant du contenu
375
- - **Conservation des sauts de paragraphe et de section**
376
- - **Détection des transpositions de blocs**
377
- - **Score de mise en page** (si bounding boxes disponibles) : IoU entre zones détectées et zones GT
378
 
379
- #### Taxonomie des erreurs
380
- Catégorisation automatique de chaque erreur :
381
 
382
- | Classe | Description |
383
- |---|---|
384
- | 1 — Confusion visuelle | Caractères morphologiquement proches (rn/m, l/1, O/0, u/n...) |
385
- | 2 — Erreur diacritique | Accent manquant, mauvais accent, cédille manquante |
386
- | 3 Erreur de casse | Majuscule/minuscule |
387
- | 4 Ligature | Non résolue ou mal résolue |
388
- | 5 Abréviation | Non développée ou mal développée |
389
- | 6 Hapax | Mot absent de tout dictionnaire moderne |
390
- | 7 Segmentation | Fusion ou fragmentation de tokens |
391
- | 8 — Hors-vocabulaire | Caractère absent du modèle du moteur |
392
- | 9 — Lacune | Zone non transcrite |
393
- | 10 — Sur-normalisation LLM | Le LLM a modernisé à tort la graphie (spécifique pipelines LLM) |
394
-
395
- #### Métriques sur entités et contenus critiques
396
- - Précision sur les entités nommées (NER via spaCy multilingue) : personnes, lieux, dates
397
- - Précision sur les séquences numériques (foliotation, pagination, montants)
398
- - Taux de conservation de la ponctuation
399
-
400
- ### 6.3 Analyse qualité image et corrélations
401
-
402
- #### Métriques de qualité image automatiques
403
- - Score de netteté (variance du Laplacien)
404
- - Niveau de bruit (écart-type sur région homogène)
405
- - Détection du biais/rotation résiduel (transformée de Hough)
406
- - Score de contraste (ratio Michelson encre/fond)
407
- - Détection du show-through (transparence verso)
408
- - Score de déformation géométrique (courbure de page)
409
- - Détection des dégradations chimiques (taches, foxing)
410
-
411
- #### Corrélations image ↔ performance
412
- - Scatter plots interactifs : qualité image (X) vs CER (Y) par concurrent
413
- - Corrélation de Pearson et Spearman, avec test de significativité
414
- - Identification des concurrents robustes aux dégradations vs sensibles
415
- - Segmentation du corpus en terciles qualité (bonne/moyenne/mauvaise)
416
-
417
- ### 6.4 Analyses statistiques et agrégées
418
-
419
- #### Score de difficulté intrinsèque
420
- Indicateur calculé indépendamment des moteurs, combinant :
421
- - Variance du CER entre tous les concurrents (si tous ratent → document difficile)
422
- - Métriques de qualité image
423
- - Densité de caractères spéciaux (ligatures, abréviations, diacritiques)
424
- - Longueur des lignes et densité du texte
425
-
426
- **Valeur :** séparer deux questions distinctes — *est-ce que ce moteur est mauvais ?* vs *est-ce que ce document est objectivement difficile ?*
427
-
428
- #### Tests statistiques
429
- - Test de Wilcoxon (non-paramétrique) pour comparer deux concurrents
430
- - Correction de Bonferroni pour comparaisons multiples (>2 concurrents)
431
- - Intervalles de confiance à 95% par bootstrap sur toutes les métriques
432
- - Test de Student apparié pour grands corpus
433
-
434
- #### Analyse des séquences et clustering
435
- - Longueur moyenne des séquences correctes entre deux erreurs
436
- - Distribution des longueurs d'erreurs (erreurs isolées vs blocs)
437
- - Clustering automatique des patterns d'erreurs (k-means) avec exemples représentatifs
438
- - Export des clusters pour cibler le fine-tuning
439
-
440
- #### Analyse inter-concurrents
441
- - Score de consensus : vote majoritaire, souvent meilleur que n'importe quel moteur seul
442
- - Carte d'accord : zones de consensus vs désaccord sur le corpus
443
- - Complémentarité : quels concurrents ont des erreurs différentes (bons candidats pour ensemble) ?
444
- - Analyse de dominance : pour quels types de documents le concurrent A bat-il systématiquement B ?
445
 
446
- ---
447
 
448
- ## 7. Module 5 — Rapport interactif HTML
449
-
450
- Le rapport est un **fichier HTML unique auto-contenu**, lisible hors-ligne, embarquant toutes les données et visualisations. C'est la livrable principale de Picarones.
451
-
452
- ### 7.1 Structure du rapport
453
-
454
- #### Page d'accueil — Tableau de bord exécutif
455
- - Résumé de l'expérience : concurrents testés, corpus, date, paramètres de normalisation
456
- - **Tableau de classement** des concurrents : CER, WER, score ligatures, score diacritiques — trié par colonne au clic
457
- - **Graphique radar (spider chart)** : CER / WER / Précision diacritiques / Précision ligatures / Score mise en page — snapshot visuel des forces/faiblesses
458
- - Histogrammes de distribution CER côte-à-côte
459
- - Alertes : concurrents avec CER > seuil, tests statistiques non-significatifs
460
- - Recommandation automatique : quel concurrent pour quel usage (manuscrits anciens, imprimés, grand volume...)
461
-
462
- #### Vue Galerie — exploration du corpus
463
- - Toutes les images en grille de vignettes avec badge CER par concurrent (code couleur vert→rouge)
464
- - Filtres dynamiques : CER > X%, score qualité image, type de script, longueur GT, concurrent gagnant
465
- - Tri multi-critères : CER, difficulté intrinsèque, longueur, date
466
- - Vue **"Worst cases"** : top N documents les plus difficiles par concurrent, avec explication automatique
467
- - Vue **"Consensus"** : documents où tous les concurrents s'accordent — les plus fiables
468
- - Vue **"LLM gagne"** / **"LLM dégrade"** : documents où la couche LLM améliore vs détériore la sortie OCR
469
-
470
- #### Vue Document — analyse détaillée
471
- - Image originale zoomable (panneau gauche) avec superposition des zones en erreur si bounding boxes disponibles
472
- - **Affichage N-way synchronisé** : GT + sortie de chaque concurrent en colonnes parallèles avec scroll synchronisé
473
- - **Diff token coloré** façon GitHub : insertions (vert), suppressions (rouge), substitutions (orange)
474
- - **Diff aligné sur l'image** : surlignage de la zone correspondante au survol d'une erreur (si bounding boxes)
475
- - Bascule **"Diplomatique / Normalisé"** : diff exact vs diff avec normalisation configurée
476
- - **Vue spécifique OCR+LLM** : trois colonnes — GT / Sortie OCR brute / Sortie après correction LLM — avec double diff pour voir exactement ce que le LLM a modifié
477
- - Détail des métriques pour ce document
478
-
479
- #### Vue Analyse — graphiques et statistiques
480
- - Distribution complète des CER (histogramme + courbe de densité)
481
- - Scatter plots interactifs : qualité image vs CER, colorés par type de script
482
- - Courbes de fiabilité : pour les X% documents les plus faciles, quel CER ?
483
- - **Heatmap de confusion de caractères** : cliquable — cliquer affiche tous les exemples
484
- - Diagramme de Venn des erreurs (communes et exclusives entre concurrents)
485
- - Visualisation des clusters d'erreurs avec exemples représentatifs
486
- - Matrices de corrélation entre toutes les métriques
487
- - Graphiques de significativité (p-values des tests de Wilcoxon)
488
- - Analyse temporelle si métadonnées de date disponibles
489
-
490
- #### Vue Caractères — analyse unicode
491
- - Matrice de confusion unicode interactive, colorée par fréquence
492
- - Tableau des caractères les plus souvent manqués par chaque concurrent
493
- - CER par bloc unicode en diagramme à barres groupées
494
- - Analyse des ligatures : taux de reconnaissance par ligature
495
- - Caractères absents du vocabulaire d'un moteur
496
-
497
-
498
- ### 7.2 Fonctionnalités transversales
499
-
500
- - Thème sombre / clair, interface responsive
501
- - Recherche plein texte dans le corpus (GT et sorties de tous les concurrents)
502
- - **URL stateful** : chaque vue filtrée accessible via URL — partager un cas précis avec un collègue
503
- - **Mode présentation** : vue épurée pour contextes institutionnels
504
- - **Annotations inline** : notes du paléographe exportées en JSON
505
- - **Comparaison de rapports** : charger deux rapports (avant/après fine-tuning) et voir les deltas
506
-
507
- ### 7.3 Exports depuis le rapport
508
-
509
- | Format | Contenu |
510
  |---|---|
511
- | CSV / Excel | Toutes les métriques par document et par concurrent |
512
- | JSON | Données brutes complètes réutilisables |
513
- | PDF | Rapport synthétique avec graphiques, pour non-techniciens |
514
- | ALTO XML | Sorties OCR sélectionnées au format standard bibliothèques |
515
- | PAGE XML | Format Transkribus / eScriptorium |
516
- | Images annotées | Images originales avec zones d'erreur surlignées (PNG) |
517
- | Corpus d'erreurs | Pires cas pour cibler le fine-tuning (image + GT + sortie OCR) |
518
- | Prompts LLM | Export de tous les prompts utilisés avec leurs performances |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
 
520
  ---
521
 
522
- ## 8. Module 6 — Interface de lancement et CLI
523
-
524
- ### 8.1 Interface web légère (FastAPI)
525
 
526
- - Configuration du benchmark : sélection corpus, concurrents, paramètres de normalisation
527
- - Visualisation de l'avancement en temps réel avec log streamé
528
- - Gestion des configurations enregistrées (profils)
529
- - Accès aux rapports générés précédemment
530
- - Configuration des adaptateurs moteurs et LLM via formulaire
531
 
532
- ### 8.2 Interface en ligne de commande (CLI)
 
 
 
 
 
 
 
 
 
 
 
 
533
 
534
- ```bash
535
- # Lancer un benchmark
536
- picarones run --corpus ./mes_gt/ --engines tesseract,pero_ocr,mistral --output ./rapport/
537
 
538
- # Avec pipeline OCR+LLM
539
- picarones run --corpus ./gt/ --config pipelines/medieval_correction.yaml
540
 
541
- # Import IIIF puis benchmark
542
- picarones import iiif https://gallica.bnf.fr/ark:/12148/xxx/manifest.json --pages 1-50
543
- picarones run --corpus iiif:xxx --engines tesseract,pero_ocr --llm gpt-4o
544
-
545
- # Rapport seul depuis résultats existants
546
- picarones report --results ./results.json --output ./rapport.html
547
-
548
- # Mode CI/CD : exit code non-zero si CER > seuil
549
- picarones run --corpus ./gt/ --engines mon_moteur --fail-if-cer-above 5.0
550
-
551
- picarones estimate --corpus ./gt/ --config pipelines/gpt4o_correction.yaml
 
 
 
 
 
552
  ```
553
 
 
 
 
 
554
  ### 8.3 Intégration CI/CD
555
 
556
- - Mode headless complet, exit code paramétrable selon les métriques
557
- - Output JSON machine-readable pour intégration dans systèmes de monitoring
558
- - Badge de qualité générable (SVG) affichant le CER du modèle courant
559
- - Détection automatique des régressions (CER augmente par rapport au run précédent)
 
560
 
561
  ---
562
 
563
- ## 9. Fonctionnalités avancées
564
 
565
- ### 9.1 Profils de normalisation pré-configurés
566
 
567
- | Profil | Règles principales |
568
- |---|---|
569
- | Français médiéval (XIIe-XVe) | u/v, i/j, ſ/s, abréviations courantes |
570
- | Français moderne (XVIe-XVIIIe) | ſ/s, ligatures fi/fl, esperluettes |
571
- | Latin médiéval | Abréviations, contractions, ligatures spécifiques |
572
- | Imprimés anciens (XVe-XVIIe) | Conventions typographiques, réclames |
573
- | Personnalisé | Configurable et exportable |
574
 
575
- ### 9.2 Analyse par type de script
 
 
 
 
 
576
 
577
- Si les documents sont tagués, calcul automatique des métriques par catégorie :
578
- - Gothique textura / rotunda / cursiva
579
- - Minuscule caroline
580
- - Humanistique / italique
581
- - Imprimé romain / italique ancien
582
- - Cursives administratives (XVIIe-XIXe)
583
 
584
- ### 9.3 Suivi longitudinal
585
-
586
- - Base de données des benchmarks historiques (SQLite optionnel)
587
- - Courbes d'évolution : CER dans le temps pour un modèle en développement
588
- - Détection automatique des régressions entre deux versions
589
- - Comparaison avant/après fine-tuning
590
-
591
- ### 9.4 Analyse de robustesse
592
-
593
- - Génération automatique de versions dégradées des images (bruit, flou, rotation, réduction de résolution, binarisation)
594
- - Courbes de robustesse : CER en fonction du niveau de dégradation
595
- - Identification du seuil de dégradation critique pour chaque concurrent
596
-
597
- ### 9.5 Évaluation par sous-région
598
-
599
- Si bounding boxes disponibles dans la GT (ALTO/PAGE XML) :
600
- - CER par zone : corps du texte / titres courants / marginalia / initiales / notes de bas de page
601
- - Heatmap de densité d'erreur sur l'image
602
-
603
- ### 9.6 Détection de la sur-normalisation LLM
604
-
605
- Risque spécifique aux pipelines OCR+LLM : le LLM "corrige" à tort des graphies médiévales légitimes en les modernisant. Picarones mesure :
606
- - Taux de modification introduites par le LLM sur des passages déjà corrects
607
- - Score de sur-normalisation : combien de transcriptions correctes le LLM a-t-il dégradées ?
608
- - Liste des interventions LLM non souhaitées pour affiner le prompt
609
-
610
- ---
611
-
612
- ## 10. Plan de développement
613
-
614
- | Sprint | Durée | Livrables |
615
- |---|---|---|
616
- | **Sprint 1** | 1-2 sem. | Structure du projet, adaptateurs Tesseract + Pero OCR, calcul CER/WER avec `jiwer`, export JSON, CLI de base |
617
- | **Sprint 2** | 1-2 sem. | Rapport HTML v1 : galerie, vue document avec diff coloré, tableau de classement, graphiques de base |
618
- | **Sprint 3** | 1-2 sem. | Pipelines OCR+LLM (modes text_only et text_and_image), adaptateurs GPT-4o et Claude |
619
- | **Sprint 4** | 1-2 sem. | Adaptateurs API OCR (Mistral OCR, Google Vision), import IIIF, normalisation unicode, CER diplomatique |
620
- | **Sprint 5** | 1-2 sem. | Métriques avancées : matrice confusion unicode, ligatures, structure, qualité image, taxonomie des erreurs |
621
- | **Sprint 6** | 1-2 sem. | Interface web FastAPI, import HTR-United / HuggingFace, profils de normalisation, Ollama (LLMs locaux) |
622
- | **Sprint 7** | 1-2 sem. | Rapport HTML v2 : vue Caractères, scatter plots, heatmaps, clustering |
623
- | **Sprint 8** | 2 sem. | Intégration eScriptorium et Gallica API, suivi longitudinal, analyse de robustesse, prompts bibliothèque |
624
- | **Sprint 9+** | Continu | Tests utilisateurs, documentation, packaging Docker, CI/CD, publication open-source |
625
 
626
- ---
 
 
 
 
 
627
 
628
- ## 11. Exigences non fonctionnelles
629
 
630
- ### Performance
631
- - Pipeline capable de traiter 1000 documents en moins de 30 minutes (moteurs locaux)
632
- - Rapport HTML interactif fluide pour des corpus de 10 000 documents
633
- - Calcul des métriques en moins de 1 seconde par document
 
 
 
 
 
 
634
 
635
- ### Interopérabilité
636
- - Compatibilité Linux, macOS, Windows
637
- - Docker fourni pour un déploiement reproductible
638
- - API REST documentée (OpenAPI) pour intégration tierce
639
- - Conformité IIIF, ALTO XML, PAGE XML, TEI
640
 
641
- ### Qualité et maintenabilité
642
- - Tests unitaires pour toutes les métriques (vérification sur cas connus)
643
- - Tests d'intégration sur corpus de référence
644
- - Documentation de chaque métrique (définition, formule, interprétation)
645
- - Code open-source (licence Apache 2.0)
646
 
647
- ### Sécurité et confidentialité
648
- - Aucune donnée envoyée vers l'extérieur sans consentement explicite
649
- - Mode entièrement hors-ligne possible (moteurs locaux + Ollama uniquement)
650
- - Clés API dans variables d'environnement uniquement
651
 
652
  ---
653
 
654
- ## Addendum Évolutions Sprints 16-30
655
-
656
- Cette section complète les spécifications initiales avec les fonctionnalités
657
- ajoutées entre les Sprints 16 et 30. Le cœur du document ci-dessus reste
658
- fidèle au cahier des charges originel ; cet addendum documente les briques
659
- qui ont enrichi la plateforme depuis.
660
 
661
- ### Promesses non livrées reportées à la refonte SPECS v2 (Sprint A14)
662
-
663
- > Le présent document (SPECS v1.0 + addendum Sprints 16-30) prédate la
664
- > refonte structurelle Sprints 32+ et plusieurs choix éditoriaux ont
665
- > évolué. Une refonte intégrale est planifiée en **Sprint A14** du plan
666
- > de remédiation institutionnelle (cf.
667
- > [`docs/audits/remediation-plan-2026-05.md`](docs/audits/remediation-plan-2026-05.md)).
668
- >
669
- > En attendant, les promesses suivantes mentionnées dans le présent
670
- > document **ne sont pas livrées** et seront soit implémentées
671
- > ultérieurement, soit explicitement abandonnées dans SPECS v2 :
672
 
673
  <!-- specs-check: known-abandoned-start -->
674
 
675
- - **AWS Textract** (§4.2 priorité v1.1) : adapter non implémenté ;
676
- reporté à un sprint ultérieur de l'axe B (modules contribués).
677
- - **Calamari** (§4.2 priorité v1.1) : adapter non implémenté ; reporté
678
- ou abandonné selon la demande utilisateur.
679
- - **OCRopus** / OCRopus4 (§4.2 priorité v1.2) : adapter non
680
- implémenté ; reporté.
681
- - **Recommandation automatique** « quel concurrent pour quel usage »
682
- (§7.1) : **abandonné** au profit du moteur narratif factuel
683
- (Sprint 19) — pivot philosophique vers la stricte neutralité
684
- éditoriale Picarones mesure et classe, il ne tranche pas »).
685
- - **Export PDF** du rapport (§7.3) : non implémenté ; CSV + JSON
686
- couvrent les usages observés. Reporté à un sprint dédié si demande
687
- utilisateur.
688
- - **Clustering automatique k-means des patterns d'erreurs** (§6.4) :
689
- non implémenté ; remplacé partiellement par la taxonomie discrète
690
- (Sprint 5) et la co-occurrence Jaccard (Sprint 75).
691
- - **Annotations inline du paléographe exportées en JSON** (§7.2) :
692
- non implémentées ; reportées.
693
- - **Badge SVG de qualité OCR pour CI** (§8.3, mention historique
694
- « Badge de qualité générable ») : non implémenté ; reporté à un
695
- sprint dédié si demande utilisateur.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
696
 
697
  <!-- specs-check: known-abandoned-end -->
698
 
699
- ### Synthèse narrative factuelle (Sprint 19)
700
-
701
- Le rapport HTML embarque en tête une **synthèse en langage naturel**
702
- construite à partir de 12 détecteurs déterministes. Aucun LLM n'intervient :
703
- chaque nombre ou nom apparaissant dans la synthèse est traçable à un
704
- ``payload`` de ``Fact`` qui provient lui-même du JSON d'entrée. Garantie
705
- testée en CI (``test_sprint19_narrative_engine.py``).
706
-
707
- Les 12 détecteurs couvrent : leader CER, ex-aequo statistique (Nemenyi),
708
- écart significatif (Wilcoxon), gagnant et effondrement par strate, profil
709
- d'erreurs atypique, hallucination LLM, fragilité robustesse, alternative
710
- Pareto, gagnant en vitesse, coût aberrant, avertissement sur la fiabilité.
711
-
712
- Politique éditoriale (ordre canonique) documentée dans
713
- ``docs/developer/narrative-engine.md`` et surchargeable via
714
- ``select_facts(..., type_order=...)``. Le registre Sprint 29 permet
715
- d'ajouter un détecteur en touchant 2 fichiers (au lieu de 4 avant).
716
-
717
- ### Tests statistiques multi-moteurs (Sprint 18)
718
-
719
- Friedman + post-hoc Nemenyi + **Critical Difference Diagram** (Demšar 2006)
720
- rendu en SVG côté serveur, sans JavaScript. Table Nemenyi pour k = 2 à 50,
721
- α ∈ {0,01 ; 0,05}. Fallback pur Python (Wilson-Hilferty pour le χ²) avec
722
- support scipy optionnel via l'extra ``[stats]``.
723
-
724
- ### Modèle de coût et front Pareto (Sprint 20)
725
-
726
- - ``picarones/core/pricing.py`` + ``picarones/data/pricing.yaml``.
727
- - ``compute_pareto_front(points, objectives)`` — multi-objectifs, N dim.
728
- - Vue Chart.js avec front Pareto en surbrillance et trois axes :
729
- coût € / vitesse / empreinte carbone (étiqueté *expérimental*).
730
-
731
- ### Glossaire contextuel + panneau avancé (Sprint 21)
732
-
733
- - 25 entrées bilingues dans ``picarones/report/glossary/{fr,en}.yaml``.
734
- - Panneau *« ⚙ Mode avancé »* : choix de colonnes, filtres par strate,
735
- score composite opt-in. État persisté en URL.
736
-
737
- ### Études de cas et documentation (Sprint 22)
738
-
739
- ``docs/case-studies/`` (deux cas explicitement étiquetés *« Cas d'école »*),
740
- ``docs/user/reading-a-report.md``, trois guides développeur dans
741
- ``docs/developer/``.
742
-
743
- ### Reproductibilité scientifique (Sprint 27)
744
-
745
- Le rapport HTML embarque ``report_data["snapshots"]`` :
746
-
747
- - **pricing** — YAML brut intégral de la table de prix ;
748
- - **glossary** — entrées effectivement référencées ;
749
- - **normalization** — profil sérialisé (``diplomatic_table``,
750
- ``exclude_chars``…) ;
751
- - **environment** — version Picarones, Python, plateforme, commit git,
752
- paquets installés.
753
-
754
- Un lecteur peut rejouer la synthèse, le Pareto et le glossaire sans
755
- accès au code source du moment où le rapport a été généré.
756
-
757
- ### Sécurité institutionnelle (Sprint 24)
758
 
759
- Cf. ``SECURITY.md`` à la racine :
760
 
761
- - Mode public (``PICARONES_PUBLIC_MODE=1``) refuse les moteurs cloud
762
- mutualisés et les pipelines LLM facturés à la clef serveur.
763
- - Validation Pillow systématique sur les images (CVE-2023-50447 et autres).
764
- - Browse roots configurables via ``PICARONES_BROWSE_ROOTS``.
765
- - Rate limiting par IP + sémaphore de jobs concurrents.
766
- - CSP + en-têtes durcis.
767
 
768
- ### Persistance des jobs et frontend Jinja2 (Sprints 25-26)
 
 
 
 
 
 
769
 
770
- - Sprint 25 : ``_HTML_TEMPLATE`` (3000 L) 8 partials Jinja2 dans
771
- ``picarones/web/templates/`` + ``static/web-app.js``.
772
- - Sprint 26 : ``picarones/core/jobs.py`` — ``JobStore`` SQLite (WAL,
773
- thread-safe). Reprise SSE via ``Last-Event-ID``. Jobs orphelins
774
- marqués ``interrupted`` au boot.
775
 
776
- ### Comparaison de runs et UX (Sprint 28)
 
 
 
 
 
 
 
 
 
 
777
 
778
- - ``picarones compare A.json B.json -o diff.html`` (exit code 2 si
779
- régression — branchable sur GitHub Actions).
780
- - ``/api/config/save`` + ``/api/config/load`` : sérialisation/import
781
- d'une configuration de benchmark.
782
- - ``/api/benchmark/{id}/synthesis_preview`` : synthèse narrative sans
783
- rouvrir le HTML.
784
- - ``/api/history/regressions`` : surface de l'infra Sprint 8.
785
 
786
- ### Accessibilité (Sprint 30)
787
 
788
- Les badges CER du rapport HTML portent un attribut ``data-cer-tier``
789
- (``excellent`` / ``acceptable`` / ``mediocre`` / ``critical``) et un
790
- ``aria-label``. Le CSS associe une icône unicode (``●``, ``◐``, ``◑``,
791
- ``○``) et un pattern de bordure différenciant à chaque tier — la
792
- couleur n'est plus la seule information visuelle.
793
 
794
- Pre-commit hook installé (``ruff`` + check YAML/JSON/secrets) ; cf.
795
- ``.pre-commit-config.yaml`` et ``CONTRIBUTING.md``.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
 
797
  ---
798
 
799
- *Picarones est conçu pour devenir la référence open-source de l'évaluation OCR/HTR dans le champ patrimonial — métriques adaptées aux documents historiques, pipelines OCR+LLM, intégration native des standards bibliothéconomiques, rapport interactif exportable.*
 
 
 
 
 
 
 
 
1
+ # Picarones — Spécifications fonctionnelles et techniques
2
 
3
+ > **Plateforme de banc d'essai d'OCR / HTR / VLM et de pipelines de
4
+ > post-correction pour documents patrimoniaux.**
5
  >
6
+ > Version **2.0**Mai 2026. Refonte intégrale (Sprint A14 du plan
7
+ > de remédiation institutionnelle, item **B-12**).
8
+
9
+ > **Note de lecture** : ce document décrit ce que Picarones **fait
10
+ > aujourd'hui**, dans la version 1.x. Pour les **non-fonctionnalités
11
+ > assumées** (ce que Picarones *ne fait pas et ne fera pas* dans
12
+ > la v1.x — par exemple la recommandation prescriptive, l'export PDF,
13
+ > les adapters Kraken/AWS Textract), voir la section §10.
14
+ >
15
+ > Pour la cartographie technique du code et les règles de
16
+ > contribution interne, voir [`CLAUDE.md`](CLAUDE.md). SPECS.md
17
+ > reste tourné « public » (vocabulaire bibliothécaire, exemples
18
+ > patrimoniaux). Les deux documents sont complémentaires, pas
19
+ > redondants.
20
 
21
  ---
22
 
23
  ## Table des matières
24
 
25
+ 1. [Vision et positionnement](#1-vision-et-positionnement)
26
+ 2. [Architecture en 3 cercles](#2-architecture-en-3-cercles)
27
+ 3. [Module 1 — Corpus et imports](#3-module-1--corpus-et-imports)
28
+ 4. [Module 2 — Adaptateurs OCR / HTR](#4-module-2--adaptateurs-ocr--htr)
29
+ 5. [Module 3 — Pipelines OCR+LLM et pipelines composables](#5-module-3--pipelines-ocrllm-et-pipelines-composables)
30
+ 6. [Module 4 — Métriques et analyses](#6-module-4--métriques-et-analyses)
31
+ 7. [Module 5 — Rapport HTML interactif](#7-module-5--rapport-html-interactif)
32
+ 8. [Module 6 — Interface web et CLI](#8-module-6--interface-web-et-cli)
33
+ 9. [Reproductibilité et sécurité](#9-reproductibilité-et-sécurité)
34
+ 10. [Limites assumées et non-fonctionnalités](#10-limites-assumées-et-non-fonctionnalités)
35
+ 11. [Roadmap d'évolution](#11-roadmap-dévolution)
36
+ 12. [Migration v1 → v2 — annexe historique](#12-migration-v1--v2--annexe-historique)
37
 
38
  ---
39
 
40
+ ## 1. Vision et positionnement
41
 
42
  ### 1.1 Problématique
43
 
44
+ Les équipes OCR/HTR travaillant sur des fonds patrimoniaux
45
+ (manuscrits, imprimés anciens, archives) disposent d'un paysage
46
+ hétérogène moteurs locaux (Tesseract, Pero OCR), services cloud
47
+ (Mistral OCR, Google Vision, Azure Document Intelligence), modèles
48
+ fine-tunés maison, VLMs (GPT-4o, Claude, Mistral Large) sans
49
+ outil unifié pour les comparer rigoureusement sur leurs propres
50
+ corpus.
51
+
52
+ Les outils existants (ocrevalUAtion, dinglehopper) sont soit
53
+ obsolètes, soit limités au CER/WER, soit non adaptés aux
54
+ spécificités des documents historiques : glyphes anciens,
55
+ ligatures, abréviations, graphies variables, pathologies d'image,
56
+ ordre de lecture multi-colonnes, structure ALTO/PAGE.
57
+
58
+ À cela s'ajoute une question de recherche émergente : **est-ce
59
+ qu'une couche de correction par LLM améliore réellement la sortie
60
+ OCR, de combien, sur quels types d'erreurs, et sans introduire
61
+ d'over-normalisation moderne ?** Aucun outil existant ne permet
62
+ de tester et mesurer cela rigoureusement.
63
+
64
+ ### 1.2 Philosophie : un banc d'essai, pas un atelier
65
+
66
+ Picarones est conçu comme un **banc d'essai** :
67
+
68
+ - L'utilisateur amène son **golden dataset** annoté (paires image +
69
+ vérité terrain). Sans VT, pas de benchmark.
70
+ - Picarones exécute les IA candidates et **mesure** l'écart à la VT.
71
+ - Picarones **classe** les résultats avec rigueur statistique.
72
+ - Picarones **n'arbitre pas le débat éditorial**. Il ne dit pas si
73
+ un moteur diplomatique vaut mieux qu'un moteur modernisant —
74
+ il rapporte les chiffres et laisse le chercheur, l'archiviste
75
+ ou le paléographe trancher selon ses critères propres.
76
+
77
+ Cette philosophie est tenue jusque dans le moteur narratif
78
+ factuel : chaque phrase de la synthèse en tête du rapport est
79
+ traçable à un payload de `Fact` qui provient du JSON d'entrée
80
+ (garde-fou anti-hallucination prouvé par tests).
81
+
82
+ ### 1.3 Contributions scientifiques
83
+
84
+ Au-delà de la simple agrégation de moteurs, Picarones apporte
85
+ plusieurs briques nouvelles dans l'écosystème OCR/HTR open-source :
86
+
87
+ - **Registre typé de métriques** (Sprint 34) : chaque métrique
88
+ est enregistrée pour une jonction de types `ArtifactType`
89
+ (TEXT/ALTO/PAGE/ENTITIES/READING_ORDER) ; un pipeline composé
90
+ peut alors calculer automatiquement la métrique adéquate à
91
+ chaque jonction de son DAG.
92
+ - **Interface BaseModule générique** (Sprint 33) : OCR, mappeur
93
+ VLM→ALTO, rewriter ALTO→ALTO, classifieur d'entités texte→entités
94
+ partagent la même API ; le runner les enchaîne sans privilégier
95
+ un type particulier.
96
+ - **GT multi-niveaux** (Sprint 32) : un document peut porter
97
+ simultanément une vérité terrain texte, ALTO, PAGE, entités,
98
+ et reading order — chacune calibrée à son niveau d'évaluation.
99
+ - **Moteur narratif factuel anti-hallucination** (Sprint 19+) :
100
+ 20+ détecteurs déterministes produisent une synthèse en
101
+ langage naturel dont chaque chiffre est traçable au payload
102
+ d'un `Fact`. Aucune intervention LLM, garde-fou prouvé par
103
+ test (`test_sprint23_anti_hallucination`).
104
+ - **Test multi-moteurs Friedman + Nemenyi + Critical Difference
105
+ Diagram** (Sprint 18, Demšar 2006) : référence canonique pour
106
+ la comparaison statistique de classifieurs, transposée à l'OCR.
107
+ - **Pareto coût / vitesse / CO₂** (Sprint 20) : positionnement
108
+ tri-objectifs avec front explicite, table de pricing
109
+ surchargeable.
110
+ - **Métriques philologiques transversales** (Sprints 55–60) :
111
+ six modules couvrant l'imprimé ancien, le médiéval, les
112
+ archives modernes (XIXᵉ–XXᵉ), avec scores éditoriaux séparés
113
+ (préservation stricte vs équivalence diplomatique).
114
+
115
+ ### 1.4 Utilisateurs cibles
116
+
117
+ | Profil | Cas d'usage typique |
118
  |---|---|
119
+ | **Ingénieur OCR/ML** | Pipeline programmatique, métriques fines, export JSON, intégration CI/CD via `picarones run --fail-if-cer-above` |
120
+ | **Chargé de numérisation** | Rapport HTML autonome, comparaison A vs B, lecture du Pareto coût/qualité |
121
+ | **Responsable de projet** | Vue agrégée multi-corpus, analyse coût/bénéfice des APIs cloud, suivi longitudinal SQLite |
122
+ | **Chercheur en humanités numériques** | Métriques philologiques, corpus HTR-United, taxonomie d'erreurs en 10 classes, glossaire contextuel |
123
+ | **Paléographe / éditeur critique** | Diff visuel par document, bascule diplomatique / normalisé, profil philologique séparant strict et expansion |
124
+ | **DSI institutionnel** | Déploiement intranet derrière SSO, RGPD, observabilité (cf. `docs/operations/`) |
 
 
 
 
 
 
 
125
 
126
  ---
127
 
128
+ ## 2. Architecture en 3 cercles
 
 
129
 
130
  ```
131
+ Cercle 3 (extras, report, cli, web)
132
+
133
+
134
+ Cercle 2 (measurements, engines, llm, pipelines, modules)
135
+
136
+
137
+ Cercle 1 (core)
 
 
 
 
 
 
 
 
 
 
 
 
138
  ```
139
 
140
+ **Règle de dépendance** : les imports vont uniquement de
141
+ l'extérieur vers l'intérieur. Aucun shim — un module a un seul
142
+ emplacement. La règle est appliquée par
143
+ `tests/core/test_circle_dependencies.py` (Sprint A3) qui parse
144
+ l'AST de chaque fichier et bloque toute violation au merge.
145
+
146
+ ### 2.1 Cercle 1 abstractions pures
147
+
148
+ 7 modules dans `picarones/core/` :
149
+
150
+ - `corpus.py` — `Document`, `Corpus`, `GTLevel.{TEXT,ALTO,PAGE,ENTITIES,READING_ORDER}`,
151
+ payloads typés, loader auto-détectant les fichiers `.gt.alto.xml`,
152
+ `.gt.page.xml`, `.gt.entities.json`, `.gt.reading_order.json`.
153
+ - `modules.py` `BaseModule`, `ArtifactType`. Interface commune
154
+ à OCR, mappeurs, rewriters, classifieurs.
155
+ - `metric_registry.py` `MetricSpec`, `@register_metric`,
156
+ `select_metrics`, `compute_at_junction`. Sélection par signature
157
+ de types exacte (pas de coercion).
158
+ - `metric_hooks.py` — registre legacy compatible (Sprint 16-).
159
+ - `metrics.py` — `MetricsResult`, `aggregate_metrics`.
160
+ - `results.py` — `DocumentResult`, `EngineReport`, `BenchmarkResult`,
161
+ sérialisation JSON.
162
+ - `facts.py` — `Fact`, `FactType` (20 entrées), `FactImportance`,
163
+ `DetectorRegistry`. Modèle de données du moteur narratif.
164
+ - `diff_utils.py` — `compute_word_diff`, `compute_char_diff`,
165
+ `diff_stats` (déplacé Cercle 3 → Cercle 1 en A3).
166
+ - `pipeline.py` — `PipelineRunner`, `PipelineSpec`, `PipelineStep`.
167
+ - `xml_utils.py` — `safe_parse_xml` (defusedxml).
168
+
169
+ ### 2.2 Cercle 2 — logique métier
170
+
171
+ 5 sous-packages :
172
+
173
+ - `measurements/` — ~70 modules de calcul de métriques + le
174
+ moteur narratif (`narrative/` avec arbiter, registry, renderer,
175
+ 20 détecteurs en 6 familles).
176
+ - `engines/` — adaptateurs OCR : Tesseract, Pero OCR, Mistral OCR,
177
+ Google Vision, Azure Document Intelligence (5 adapters).
178
+ - `llm/` — adaptateurs LLM : OpenAI, Anthropic, Mistral, Ollama
179
+ (4 adapters).
180
+ - `pipelines/` — orchestration OCR+LLM (3 modes historiques).
181
+ - `modules/` — modules `BaseModule` officiels (ALTO text→region
182
+ mappers).
183
+
184
+ ### 2.3 Cercle 3 — entrées et rendu
185
+
186
+ - `report/` — générateur HTML, ~25 modules de rendu, vendor
187
+ Chart.js, templates Jinja2 (10 partials), i18n FR/EN, glossaire
188
+ contextuel (25 entrées bilingues).
189
+ - `cli/` — Click CLI (15 commandes) en package `picarones/cli/`.
190
+ - `web/` — FastAPI (app + 11 routers + sécurité + jobs SQLite +
191
+ maintenance auto-purge).
192
+ - `extras/` — plugins : importers (IIIF, Gallica, HTR-United, HF
193
+ Datasets, eScriptorium), modules historiques.
194
 
195
  ---
196
 
197
+ ## 3. Module 1 — Corpus et imports
198
 
199
  ### 3.1 Formats de vérité terrain acceptés
200
 
201
+ | Format | Extension | Niveau GT | Usage typique |
202
+ |---|---|---|---|
203
+ | Texte brut | `image.gt.txt` | TEXT | Convention Tesseract, HTR-United |
204
+ | ALTO XML v4 | `.gt.alto.xml` | ALTO | Standard bibliothèques nationales, eScriptorium export |
205
+ | PAGE XML 2019 | `.gt.page.xml` | PAGE | Transkribus, OCRopus |
206
+ | Entités nommées | `.gt.entities.json` | ENTITIES | Format HIPE simplifié |
207
+ | Reading order | `.gt.reading_order.json` | READING_ORDER | Liste ordonnée de region IDs |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
209
+ Le loader (`load_corpus_from_directory`) détecte automatiquement
210
+ chacun de ces niveaux à côté de l'image. Un même document peut
211
+ porter plusieurs niveaux simultanément (Sprint 32).
 
212
 
213
+ ### 3.2 Sources d'import
 
 
 
214
 
215
+ #### Local
216
+ Import d'un dossier de paires image / GT. Détection automatique
217
+ du format. Filtrage des fichiers macOS `._*`.
218
+
219
+ #### IIIF
220
+ Import par URL de manifeste IIIF v2 et v3. Compatible Gallica
221
+ (BnF), Bodleian, BL, Vatican, e-codices, Europeana, et tout
222
+ entrepôt IIIF-compliant. Sélection par range de canvas.
223
+
224
+ #### HuggingFace Datasets
225
+ Recherche par filtre langue/script/époque/institution. Datasets
226
+ patrimoniaux pré-référencés (IAM, RIMES, READ-BAD, Esposalles,
227
+ HTR-United datasets). Statut : module
228
+ `extras/importers/huggingface.py` marqué expérimental
229
+ (`UserWarning` à l'import).
230
+
231
+ #### HTR-United
232
+ Listing du catalogue distant + import direct. Lecture des
233
+ métadonnées (langue, script, institution, époque). En cas
234
+ d'échec réseau ou parsing, fallback sur catalogue de démo +
235
+ émission d'un `Fact` `IMPORTER_FALLBACK_TRIGGERED` (Sprint A3).
236
+
237
+ #### Gallica (API BnF)
238
+ Recherche par cote, titre, auteur, date. Récupération des
239
+ images via API IIIF Gallica.
240
+
241
+ #### eScriptorium
242
+ Connexion à une instance distante via API. Statut
243
+ expérimental.
244
+
245
+ #### Upload ZIP via navigateur
246
+ Endpoint `POST /api/corpus/upload`. Validation Pillow
247
+ (décompression bombs), zip-slip prévenu, taille plafonnée
248
+ (`PICARONES_MAX_UPLOAD_MB`).
249
 
250
  ### 3.3 Gestion des corpus
251
 
252
+ - Corpus nommés et versionnés avec métadonnées descriptives.
253
+ - Tags : type de script, langue, siècle, institution, état de
254
+ conservation.
255
+ - Stratification par `script_type` (Sprint 45-46) — vue stratifiée
256
+ dans le rapport, détecteur narratif `STRATIFICATION_RECOMMENDED`
257
+ qui invite l'utilisateur quand le corpus est hétérogène.
258
 
259
  ---
260
 
261
+ ## 4. Module 2 — Adaptateurs OCR / HTR
262
 
263
  ### 4.1 Architecture des adaptateurs
264
 
265
+ Chaque moteur OCR est une classe Python qui hérite de
266
+ `BaseOCREngine` (`picarones/engines/base.py`), elle-même héritière
267
+ de `BaseModule` (Sprint 33). Une instance déclare son
268
+ `execution_mode` (`"io"` ou `"cpu"`) que le runner utilise pour
269
+ choisir entre `ThreadPoolExecutor` (cloud APIs) et
270
+ `ProcessPoolExecutor` (Tesseract, Pero).
271
 
272
+ Ajouter un nouveau moteur = créer une classe Python de ~50 lignes
273
+ qui implémente `_run_ocr(image_path) -> str` et déclare son
274
+ `execution_mode`.
275
 
276
+ ### 4.2 Moteurs OCR livrés
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
+ | Moteur | Type | Mode d'exécution | Confidence native exposée ? |
279
+ |---|---|---|---|
280
+ | **Tesseract 5** | Local CLI | CPU (ProcessPool) | ✅ Sprint 47 (`image_to_data`) |
281
+ | **Pero OCR** | Local Python | CPU (ProcessPool) | Sprint 48 (`transcription_confidence` ligne) |
282
+ | **Mistral OCR** | Cloud API | IO (ThreadPool) | ✅ Sprint 49 (quand disponible côté API) |
283
+ | **Google Vision** | Cloud API | IO (ThreadPool) | Sprint 50 (`Word.confidence` en mode `DOCUMENT_TEXT_DETECTION`) |
284
+ | **Azure Doc Intelligence** | Cloud API | IO (ThreadPool) | Sprint 51 (`Word.confidence`) |
285
+
286
+ Quand un moteur expose ses confidences natives, le runner calcule
287
+ automatiquement les métriques de calibration (ECE, MCE, reliability
288
+ diagram — Sprint 39-43).
289
+
290
+ ### 4.3 Robustesse runtime
291
+
292
+ - **Erreurs HTTP cloud** (4xx/5xx, timeout, body mal formé) :
293
+ remontées dans `EngineResult.error` avec le code HTTP, jamais
294
+ avalées silencieusement (Sprint A5 / m-10, 19 cas testés).
295
+ - **Crash isolé d'un document** : le runner continue avec les
296
+ autres documents. Le doc en échec a `engine_error` rempli.
297
+ - **Cancel mid-run** : `cancel_event.set()` interrompt proprement.
298
+ - **Timeout par document** : configurable via paramètre
299
+ `timeout_seconds`.
300
 
301
  ---
302
 
303
+ ## 5. Module 3 — Pipelines OCR+LLM et pipelines composables
 
 
304
 
305
+ ### 5.1 Pipelines OCR+LLM historiques (Sprint 3+)
306
 
307
+ L'unité de comparaison est le **concurrent** — pas forcément un
308
+ moteur seul, mais une chaîne produisant du texte à partir d'une
309
+ image.
310
 
311
+ | Mode | Description | Usage typique |
312
  |---|---|---|
313
+ | `zero_shot` | Le LLM/VLM reçoit l'image directement et transcrit | Test si GPT-4o ou Claude peut remplacer un OCR sur des documents anciens |
314
+ | `post_correction_texte` | OCR → texte brut → LLM corrige le texte | LLM non multimodal (Llama local), grand volume |
315
+ | `post_correction_image_texte` | OCR → LLM reçoit image ET texte brut | Meilleure qualité ; le LLM voit le contexte visuel |
 
 
316
 
317
+ Les prompts sont **versionnés** dans `picarones/prompts/` (8 fichiers
318
+ FR + EN), embarqués dans le snapshot du rapport pour
319
+ reproductibilité.
320
 
321
+ ### 5.2 Pipelines composables (Sprint 63+)
322
 
323
+ Au-delà des 3 modes historiques, Picarones livre une infrastructure
324
+ générique : un pipeline est une **liste d'étapes `BaseModule`**
325
+ qui produit un artefact à chaque étape (TEXT, ALTO, PAGE,
326
+ ENTITIES…) ; à chaque jonction, le runner calcule
327
+ **automatiquement** la métrique adéquate via `compute_at_junction`
328
+ (registre typé Sprint 34).
 
 
 
 
 
 
 
329
 
330
+ ```yaml
331
+ # Spec YAML chargée par picarones pipeline run
332
+ name: ocr_then_corrector
333
+ steps:
334
+ - name: ocr
335
+ module: picarones.engines.tesseract.TesseractEngine
336
+ args: { lang: "fra", psm: 6 }
337
+ - name: post_correction
338
+ module: my_module.MyLLMCorrector
339
+ args: { model: "gpt-4o" }
340
  ```
341
 
342
+ `picarones pipeline compare specs.yaml --corpus ./scans --output rapport.html`
343
+ exécute N pipelines sur le même corpus et produit un rapport
344
+ comparatif. Conçu pour qu'un mainteneur tiers puisse contribuer
345
+ ses propres modules sans toucher au cœur de Picarones (cf.
346
+ `docs/developer/module-policy.md`, Sprint 97).
347
+
348
+ ### 5.3 Détection d'over-normalisation LLM
349
+
350
+ Risque spécifique aux pipelines OCR+LLM : le LLM modernise à tort
351
+ des graphies historiques légitimes. Picarones mesure :
352
+
353
+ - **Modernisation lexicale** (Sprint 80) : top-N tokens GT
354
+ systématiquement remplacés (`maistre → maître` dans 100 % des
355
+ cas → signal exploitable).
356
+ - **Score d'absorption d'erreur** (Sprint 94) : à chaque jonction
357
+ OCR→LLM, calcule le **taux de correction** (parmi les erreurs
358
+ avant, combien corrigées) **et** le **taux d'introduction**
359
+ (parmi les erreurs après, combien nouvelles). Distingue un
360
+ module qui *corrige* d'un module qui *écrase*.
361
+ - **Delta Flesch** (Sprint 52) : sur les langues prises en
362
+ charge, signale les LLM qui rendent le texte « trop moderne »
363
+ par rapport à la GT.
364
+ - **Score d'ancrage** (Sprint 10) : proportion des trigrammes
365
+ produits par le LLM qui s'ancrent dans la GT — score bas =
366
+ hallucination probable.
367
 
368
+ ---
 
369
 
370
+ ## 6. Module 4 — Métriques et analyses
 
 
 
 
371
 
372
+ ### 6.1 Catalogue exhaustif des métriques
373
 
374
+ Picarones livre **plus de 30 métriques** organisées en familles.
375
+ Pour chaque métrique : son nom, sa jonction de types, sa source,
376
+ ses limites — voir le **glossaire contextuel** intégré au rapport
377
+ HTML (25 entrées bilingues, ouvre via le `?` à côté du nom de
378
+ colonne) et `picarones/report/glossary/{fr,en}.yaml`.
379
 
380
+ #### Classique OCR/HTR
 
 
381
 
382
+ | Métrique | Jonction | Source primaire |
383
+ |---|---|---|
384
+ | CER (raw, NFC, caseless, diplomatique) | `(TEXT, TEXT)` | Levenshtein character / [jiwer](https://github.com/jitsi/jiwer) |
385
+ | WER, MER, WIL | `(TEXT, TEXT)` | jiwer |
386
+ | Bootstrap CI 95 % | dérivé | Efron (1979) |
387
+ | Distribution CER par ligne, Gini | dérivé | Sprint 10 |
388
+ | Détection hallucinations VLM (anchor score, length ratio) | dérivé | Sprint 10 |
389
 
390
+ #### Philologique (Sprints 52-60, 80, 84-85, 92-94)
391
 
392
+ | Métrique | Jonction | Cible patrimoniale |
393
+ |---|---|---|
394
+ | Couverture MUFI | `(TEXT, TEXT)` | Manuscrits médiévaux |
395
+ | Score d'expansion d'abréviations Capelli | `(TEXT, TEXT)` | Médiéval |
396
+ | Précision par bloc Unicode | `(TEXT, TEXT)` | Imprimés anciens / médiéval |
397
+ | Préservation des marqueurs typographiques de l'imprimé ancien (long-s, ligatures, tildes nasaux) | `(TEXT, TEXT)` | XVIᵉ-XVIIIᵉ |
398
+ | Marqueurs des archives modernes (titres, ordinaux, monnaies, état civil…) | `(TEXT, TEXT)` | XIXᵉ-XXᵉ |
399
+ | Préservation des numéraux romains (5 statuts) | `(TEXT, TEXT)` | Toutes périodes |
400
+ | Recherchabilité fuzzy (Levenshtein distance ≤ 2) | `(TEXT, TEXT)` | Indexation Elastic / full-text |
401
+ | Précision sur séquences numériques (dates, foliotation, monnaies) | `(TEXT, TEXT)` | Archives, économie historique |
402
+ | Modernisation lexicale (top-N tokens GT modernisés) | `(TEXT, TEXT)` | Pipelines OCR+LLM |
403
+ | Delta Flesch (FR + EN) | `(TEXT, TEXT)` | Repère VLM hallucinant du français moderne |
404
+ | Score d'absorption d'erreur par jonction | `(TEXT, TEXT)` | Pipelines composées |
405
+ | Précision sur entités nommées (HIPE) | `(ENTITIES, ENTITIES)` | Indexation prosopographique |
406
+ | Reading order F1 (ICDAR 2015) | `(READING_ORDER, READING_ORDER)` | Manuscrits glosés, journaux multi-colonnes |
407
+ | Layout F1 par type de région (IoU 0.5) | `(ALTO, ALTO)` | Texte/glose/marginalia |
408
+
409
+ #### Comparaison & décision (Sprints 18, 20, 35-37, 81, 89-92, 96)
410
+
411
+ | Métrique | Source primaire |
412
+ |---|---|
413
+ | Test multi-moteurs Friedman + post-hoc Nemenyi + CDD | Demšar (2006) |
414
+ | Test pairé Wilcoxon | Wilcoxon (1945) |
415
+ | Pareto coût / vitesse / CO₂ (multi-objectifs N dim) | Pareto (1896) |
416
+ | Divergence taxonomique inter-moteurs (Jensen-Shannon) | Lin (1991) |
417
+ | Oracle complementarity (recall borné supérieur) | Sprint 35 |
418
+ | Score de spécialisation inter-moteurs | Sprint 89 |
419
+ | Stabilité multi-runs (CV CER, accord identique) | Sprint 83 |
420
+ | Accord inter-annotateurs (Cohen κ, Krippendorff α) | Cohen (1960), Krippendorff (1970) |
421
+ | Tendance longitudinale + change-point Pettitt | Sprint 92 |
422
+ | Throughput effectif (pages/h après correction humaine 5s/erreur) | Sprint 91, HTR-United |
423
+ | Coût marginal par erreur évitée | Sprint 91 |
424
+ | Comparaison incrémentale ANOVA-like par slot | Sprint 96 |
425
+
426
+ **Note de traçabilité** : les références primaires (Demšar 2006,
427
+ Wilcoxon 1945, Efron 1979, etc.) sont citées dans les docstrings
428
+ de chaque fonction de `picarones/measurements/statistics.py`.
429
+ Le glossaire contextuel relie chaque métrique à sa publication
430
+ canonique (champ `reference`).
431
+
432
+ ### 6.2 Profils de normalisation
433
+
434
+ 11 profils livrés (`picarones/measurements/normalization.py`,
435
+ exposés via `/api/normalization/profiles`) : `nfc`, `caseless`,
436
+ `minimal`, `medieval_french`, `early_modern_french`,
437
+ `medieval_latin`, `medieval_english`, `early_modern_english`,
438
+ `secretary_hand`, `sans_ponctuation`, `sans_apostrophes`.
439
+
440
+ Chaque profil applique un ensemble d'équivalences diplomatiques
441
+ (ſ=s, u=v, i=j, ꝑ=per, þ=th, etc.). Un profil custom peut être
442
+ chargé depuis YAML.
443
+
444
+ **Traçabilité aux standards éditoriaux** (MUFI v4.0, TEI P5
445
+ Unicode chapter 3.4, DEAF) : prévue Sprint A12 (item B-6 du
446
+ plan de remédiation institutionnelle).
447
+
448
+ ### 6.3 Taxonomie des erreurs en 10 classes
449
+
450
+ Catégorisation automatique de chaque erreur (Sprint 5) :
451
+
452
+ 1. Confusion visuelle (rn/m, l/1, O/0, u/n…)
453
+ 2. Erreur diacritique
454
+ 3. Erreur de casse
455
+ 4. Ligature non résolue
456
+ 5. Abréviation non développée
457
+ 6. Hapax (mot absent du lexique)
458
+ 7. Segmentation (fusion / fragmentation)
459
+ 8. Hors-vocabulaire
460
+ 9. Lacune (texte présent en GT, absent en OCR)
461
+ 10. Sur-normalisation LLM
462
+
463
+ ### 6.4 Score de difficulté intrinsèque
464
+
465
+ Indicateur calculé **indépendamment des moteurs** (Sprint 7) :
466
+
467
+ - variance du CER entre tous les concurrents (si tous ratent →
468
+ document objectivement difficile),
469
+ - métriques de qualité image,
470
+ - densité de caractères spéciaux (ligatures, abréviations,
471
+ diacritiques),
472
+ - longueur et densité du texte.
473
+
474
+ Sépare deux questions distinctes : *« est-ce que ce moteur est
475
+ mauvais ? »* vs *« est-ce que ce document est objectivement
476
+ difficile ? »*.
477
 
478
+ ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
 
480
+ ## 7. Module 5 — Rapport HTML interactif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
 
482
+ Le rapport est un **fichier HTML auto-portant** (Jinja2 server-side,
483
+ Chart.js vendoré inline), lisible hors-ligne, embarquant toutes
484
+ les données et visualisations.
485
 
486
+ ### 7.1 Cinq vues + sections globales
487
 
488
+ #### Sections globales (en tête)
489
 
490
+ - **Synthèse narrative factuelle** (Sprint 19+) : 3-5 phrases
491
+ produites par 20+ détecteurs déterministes. Chaque chiffre
492
+ rendu est traçable au payload du `Fact` correspondant
493
+ (anti-hallucination prouvé par test).
494
+ - **Critical Difference Diagram** (Sprint 18) : SVG server-side,
495
+ Friedman + post-hoc Nemenyi.
496
+ - **Section inter-moteurs** (Sprint 37) : matrice de divergence
497
+ taxonomique + encart oracle complementarity.
498
+ - **Front Pareto** (Sprint 20) : coût / vitesse / CO₂ avec
499
+ toggles d'axes.
500
+ - **Section leviers d'amélioration** (Sprint 51-82) : 5 leviers
501
+ factuels (taxonomie récupérable, concentration Pareto,
502
+ complémentarité, modernisation lexicale, déficit projeté de
503
+ robustesse).
504
 
505
+ #### Vue Classement (Ranking)
506
 
507
+ Tableau triable : CER (médiane par défaut depuis Sprint 44),
508
+ WER, MER, WIL, scores ligatures et diacritiques, Gini, score
509
+ d'ancrage, sur-normalisation, etc. Vue stratifiée optionnelle
510
+ par `script_type` (Sprint 45-46).
511
 
512
+ #### Vue Galerie (Gallery)
513
 
514
+ Grille de vignettes avec badge CER coloré. Filtres dynamiques
515
+ (CER > X, qualité image, type de script, longueur GT). Tri
516
+ multi-critères. Vue **« Worst lines globale »** (Sprint 72)
517
+ qui transcende les documents et liste les lignes individuelles
518
+ les plus mal transcrites.
519
 
520
+ #### Vue Document
 
 
 
 
 
 
521
 
522
+ Image originale + diff token coloré façon GitHub par moteur,
523
+ scroll synchronisé N-way. Vue spécifique OCR+LLM : triple diff
524
+ GT / sortie OCR brute / sortie après LLM.
 
525
 
526
+ #### Vue Analyses
 
 
527
 
528
+ Distribution CER (histogramme + densité), scatter plots
529
+ qualité image vs CER, heatmap de confusion de caractères,
530
+ diagrammes de fiabilité (calibration ECE/MCE — Sprint 43),
531
+ graphiques de bootstrap CI 95 %, profil philologique par moteur
532
+ (Sprint 62), throughput effectif (Sprint 91), tendances
533
+ longitudinales (Sprint 92), DAG de pipeline composée (Sprint 95),
534
+ etc.
535
 
536
+ #### Vue Caractères
 
 
 
 
 
 
537
 
538
+ Matrice de confusion Unicode interactive, tableau des
539
+ caractères les plus souvent manqués par chaque moteur, CER par
540
+ bloc Unicode (Sprint 55), analyse des ligatures.
 
 
 
541
 
542
+ ### 7.2 Panneaux latéraux
 
543
 
544
+ - **Glossaire contextuel** (Sprint 21) : `?` à côté de chaque
545
+ en-tête de colonne ; clic ouvre un panneau avec définition,
546
+ ce qu'on mesure, usage, limites, référence primaire (25
547
+ entrées bilingues).
548
+ - **Mode avancé** (Sprint 21) : choix de colonnes visibles,
549
+ filtres par strate, opt-in score composite personnel
550
+ (curseurs à 0 par défaut, formule visible, warning explicite
551
+ « il n'existe pas de pondération universellement valide »),
552
+ toggle palette daltonien-friendly (Sprint A7), URL stateful.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
 
554
+ ### 7.3 Exports
555
 
556
+ | Format | Statut |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  |---|---|
558
+ | HTML autonome | Livré |
559
+ | CSV (vue courante avec filtres) | ✅ Livré |
560
+ | JSON (BenchmarkResult complet) | Livré |
561
+ | Snapshot reproductibilité (versions, commit, lock) | Sprint 27 |
562
+ | Lazy images (rapport HTML + dossier `report-assets/`) | Sprint A5 / M-16 |
563
+ | PDF | Non livré (cf. §10) |
564
+ | ALTO XML / PAGE XML / images annotées | Non livré (cf. §10) |
565
+
566
+ ### 7.4 Accessibilité
567
+
568
+ Conformité WCAG 2.1 niveau AA (cf.
569
+ [`ACCESSIBILITY.md`](ACCESSIBILITY.md)) :
570
+
571
+ - Skip-to-content link (WCAG 2.4.1).
572
+ - `role="img"` + `aria-label` + table de données jumelle
573
+ pour chaque graphique Chart.js (WCAG 1.1.1).
574
+ - `scope="col"` sur tous les `<th>`.
575
+ - Palette par défaut Okabe-Ito (daltonien-friendly), toggle vers
576
+ l'ancienne palette via panneau Avancé ou `?palette=classic`.
577
+ - Bilinguisme intégral (skip-link, ARIA labels, captions des
578
+ tables jumelles).
579
+ - Audit RGAA externe planifié Sprint A15.
580
 
581
  ---
582
 
583
+ ## 8. Module 6 — Interface web et CLI
 
 
584
 
585
+ ### 8.1 Interface web FastAPI
 
 
 
 
586
 
587
+ - Configuration de benchmark : sélection corpus, moteurs,
588
+ normalisation.
589
+ - Streaming SSE de la progression en temps réel (`Last-Event-ID`
590
+ reconnexion supportée — Sprint 26).
591
+ - Persistance des jobs en SQLite (mode WAL, thread-safe), reprise
592
+ des jobs orphelins au boot.
593
+ - Upload ZIP depuis le navigateur.
594
+ - Imports HTR-United / HuggingFace via formulaire.
595
+ - Bilingue FR/EN.
596
+ - Healthcheck minimal `/health` (Sprint A4 / M-3).
597
+ - Token CSRF (`/api/csrf/token`) + middleware (Sprint A4 / B-11)
598
+ activable via `PICARONES_CSRF_REQUIRED=1` pour les déploiements
599
+ institutionnels derrière SSO.
600
 
601
+ ### 8.2 Interface en ligne de commande (Click)
 
 
602
 
603
+ 15 commandes :
 
604
 
605
+ ```bash
606
+ picarones run # benchmark
607
+ picarones report # rapport HTML depuis JSON
608
+ picarones demo # rapport démo synthétique
609
+ picarones compare # compare deux runs JSON, exit-code 2 si régression
610
+ picarones diagnose # workflow bench + leviers + recommandations factuelles
611
+ picarones economics # workflow bench + throughput + coût projeté
612
+ picarones edition # workflow bench + métriques philologiques
613
+ picarones pipeline # run/compare pipelines composées YAML
614
+ picarones import # IIIF / HF / HTR-United
615
+ picarones serve # interface web locale
616
+ picarones history # historique longitudinal SQLite
617
+ picarones robustness # courbes CER vs dégradation
618
+ picarones engines # liste les moteurs disponibles
619
+ picarones metrics # CER/WER entre deux fichiers texte
620
+ picarones info # version + system info
621
  ```
622
 
623
+ Toutes les commandes supportent `--help`. Workflows pré-câblés
624
+ (`diagnose`, `economics`, `edition`) sont des combinaisons
625
+ canoniques pour les profils utilisateurs typiques.
626
+
627
  ### 8.3 Intégration CI/CD
628
 
629
+ - Mode headless (`--no-progress`).
630
+ - Output JSON machine-readable.
631
+ - Exit code 2 sur `picarones compare` si régression CER détectée.
632
+ - Workflow GitHub Actions `perf_regression.yml` (Sprint A5 /
633
+ M-14) — cron hebdomadaire + sur PR touchant le runner.
634
 
635
  ---
636
 
637
+ ## 9. Reproductibilité et sécurité
638
 
639
+ ### 9.1 Snapshots de reproductibilité (Sprint 27)
640
 
641
+ Chaque rapport HTML embarque un dict `report_data["snapshots"]`
642
+ qui contient :
 
 
 
 
 
643
 
644
+ - **pricing** YAML brut intégral de `picarones/data/pricing.yaml`
645
+ utilisé.
646
+ - **glossary** — entrées du glossaire effectivement référencées.
647
+ - **normalization** — profil sérialisé.
648
+ - **environment** — version Picarones, Python, plateforme, commit
649
+ git, paquets installés (top 200).
650
 
651
+ Procédure complète de re-jeu d'un benchmark à 5 ans d'écart :
652
+ [`docs/reproducibility-snapshots.md`](docs/reproducibility-snapshots.md)
653
+ (Sprint A8 / M-12).
 
 
 
654
 
655
+ ### 9.2 Reproductibilité des builds
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
 
657
+ - Lock files `requirements.lock` + `requirements-dev.lock`
658
+ générés via `uv pip compile` (Sprint A8).
659
+ - Image Docker épinglée à un patch précis via `ARG PYTHON_BASE_IMAGE`
660
+ (rotation trimestrielle).
661
+ - Release pipeline GitHub Actions (Sprint A9) : tag `v*.*.*` →
662
+ PyPI via OIDC trust + ghcr.io multi-arch + GitHub Release auto.
663
 
664
+ ### 9.3 Sécurité institutionnelle
665
 
666
+ - **Mode public** (`PICARONES_PUBLIC_MODE=1`) : refuse les moteurs
667
+ cloud mutualisés et les pipelines LLM facturés à la clef serveur.
668
+ - **CSRF** double-submit (`PICARONES_CSRF_REQUIRED=1`) Sprint A4.
669
+ - **XML défendu** par `defusedxml` partout (XXE / Billion Laughs).
670
+ - **Zip-slip prévenu** par `Path(member.filename).name`.
671
+ - **Validation Pillow** systématique (CVE bombes de
672
+ décompression).
673
+ - **Rate limiting** par IP + sémaphore de jobs concurrents.
674
+ - **CSP + en-têtes durcis** (X-Content-Type-Options,
675
+ Referrer-Policy).
676
 
677
+ Voir [`SECURITY.md`](SECURITY.md) pour la procédure complète.
 
 
 
 
678
 
679
+ ### 9.4 RGPD et rétention
 
 
 
 
680
 
681
+ Politique documentée dans
682
+ [`docs/operations/data-retention-rgpd.md`](docs/operations/data-retention-rgpd.md)
683
+ (Sprint A11 / M-8). Purge automatique des uploads anciens
684
+ configurable via `PICARONES_UPLOAD_RETENTION_DAYS=7` par défaut.
685
 
686
  ---
687
 
688
+ ## 10. Limites assumées et non-fonctionnalités
 
 
 
 
 
689
 
690
+ Cette section décrit explicitement **ce que Picarones ne fait pas
691
+ et ne fera pas dans la v1.x**. Plusieurs items étaient promis dans
692
+ la SPECS v1 (Mars 2025) leur abandon est un choix éditorial
693
+ documenté ci-dessous, pas un oubli.
 
 
 
 
 
 
 
694
 
695
  <!-- specs-check: known-abandoned-start -->
696
 
697
+ > Toutes les fonctionnalités listées ci-dessous étaient promises ou
698
+ > évoquées dans SPECS v1 et sont **explicitement abandonnées,
699
+ > non implémentées ou reportées** dans la v2.0 de ce document.
700
+ > Le test ``tests/docs/test_specs_consistency.py`` (Sprint A2)
701
+ > détecte cette section comme la déclaration officielle des
702
+ > non-fonctionnalités du projet.
703
+
704
+ ### 10.1 Adapters OCR non livrés
705
+
706
+ - **Kraken** : prévu v1.0 dans SPECS v1, jamais implémenté. Choix :
707
+ ouverture en plugins externes via la politique de modules
708
+ contribués (Sprint 97), pas un adapter intégré au cœur. Un
709
+ utilisateur peut écrire son `KrakenEngine(BaseOCREngine)` et
710
+ l'exécuter via les pipelines composables.
711
+ - **AWS Textract** : prévu v1.1, abandonné. Pas de DPA Amazon
712
+ signé, et le périmètre patrimonial est mieux servi par les
713
+ trois clouds déjà intégrés (Mistral OCR, Google Vision, Azure
714
+ DI).
715
+ - **Calamari** : prévu v1.1, abandonné. Maintenance d'un adapter
716
+ par moteur 50 PJ/an ; mieux vaut concentrer sur les 5 adapters
717
+ livrés et ouvrir Calamari en plugin externe.
718
+ - **OCRopus4** : prévu v1.2, abandonné — projet historique en
719
+ fin de vie.
720
+ - **Moteur custom YAML** (`type: cli` / `type: api`) : prévu en
721
+ SPECS v1.0, abandonné. **Refondu en pipelines composables**
722
+ (Sprint 63-70) qui permettent de brancher n'importe quel module
723
+ via une spec YAML — plus puissant que la déclaration d'engine
724
+ custom imaginée à l'origine.
725
+
726
+ ### 10.2 Exports non livrés
727
+
728
+ - **Export PDF** du rapport. CSV + JSON + HTML autonome couvrent
729
+ les usages observés. Reportable sur demande utilisateur si
730
+ besoin tracé.
731
+ - **Export ALTO XML** des sorties OCR.
732
+ - **Export PAGE XML** des sorties OCR.
733
+ - **Export images annotées** (PNG avec zones d'erreur surlignées).
734
+
735
+ ### 10.3 Fonctionnalités explicitement abandonnées
736
+
737
+ - **Recommandation automatique** « quel concurrent pour quel
738
+ usage ». Promise dans SPECS v1 §7.1, **abandonnée** au profit
739
+ du moteur narratif factuel (Sprint 19) et de la philosophie
740
+ « Picarones mesure et classe — il ne tranche pas ». Les leviers
741
+ d'amélioration (Sprint 51-82) restent factuels.
742
+ - **Score de consensus / vote majoritaire / ensemble** : Picarones
743
+ livre l'**oracle borné supérieur** (Sprint 35) et le score de
744
+ spécialisation inter-moteurs (Sprint 89) — observations
745
+ factuelles. Pas de mécanisme de vote actif intégré ; au
746
+ chercheur de combiner les sorties s'il le décide.
747
+ - **Clustering automatique k-means des erreurs**. Remplacé par
748
+ la taxonomie discrète (Sprint 5) + co-occurrence Jaccard
749
+ (Sprint 75) + heatmap intra-doc (Sprint 76).
750
+ - **Annotations inline du paléographe exportées en JSON**. Non
751
+ implémentées.
752
+ - **Badge SVG de qualité OCR pour CI**. `picarones compare` avec
753
+ exit code 2 sur régression couvre l'usage CI ; un badge SVG
754
+ reste nice-to-have, non priorisé.
755
+ - **Dataset de référence embarqué de 100 documents
756
+ patrimoniaux**. Picarones est volontairement un **banc d'essai
757
+ sur votre golden dataset** — le 100-doc corpus de référence
758
+ imaginé en SPECS v1 §3.3 entrerait en concurrence avec les
759
+ corpus institutionnels existants (HTR-United, Esposalles,
760
+ IAM, RIMES, READ-BAD) et en fragmenterait l'écosystème. Les
761
+ 5 documents synthétiques de Sprint A5 (`tests/fixtures/reference_corpus/`)
762
+ servent uniquement à l'anti-régression CER en CI, pas à la
763
+ valeur scientifique.
764
+
765
+ ### 10.4 Fonctionnalités scientifiques planifiées
766
+
767
+ À livrer dans des sprints futurs :
768
+
769
+ - **CITATION.cff + DOI Zenodo + papier JOSS** (Sprint A12 du
770
+ plan institutionnel) — débloque la citation académique propre.
771
+ - **Traçabilité des profils de normalisation aux standards
772
+ éditoriaux** (MUFI v4.0, TEI P5, DEAF) — Sprint A12.
773
+ - **Citations primaires des méthodes statistiques** dans les
774
+ docstrings (Demšar 2006, Wilcoxon 1945, Efron 1979) —
775
+ Sprint A12.
776
 
777
  <!-- specs-check: known-abandoned-end -->
778
 
779
+ ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
 
781
+ ## 11. Roadmap d'évolution
782
 
783
+ Trois documents complémentaires pilotent l'évolution :
 
 
 
 
 
784
 
785
+ - [`CHANGELOG.md`](CHANGELOG.md) historique sprint par sprint,
786
+ format Keep a Changelog.
787
+ - [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md) —
788
+ roadmap technique 2026+ (axes A et B : nouvelles métriques et
789
+ pipelines composables).
790
+ - [`docs/audits/`](docs/audits/) — audits institutionnels et
791
+ plans de remédiation (sprints A1 à A15 du plan en cours).
792
 
793
+ L'**état du plan institutionnel** au 2 mai 2026 :
 
 
 
 
794
 
795
+ | Phase | Sprints | Statut |
796
+ |---|---|---|
797
+ | Phase 0 — Garde-fous CI | A1, A2 | ✅ Terminée |
798
+ | Phase 1 — Hygiène architecturale | A3 | ✅ Terminée |
799
+ | Phase 2 — Robustesse runtime | A4, A5 | ✅ Terminée |
800
+ | Phase 3 — Accessibilité | A6, A7 | ✅ Terminée |
801
+ | Phase 4 — Reproductibilité ops | A8, A9 | ✅ Terminée |
802
+ | Phase 5 — Gouvernance | A10, A11 | ✅ Terminée |
803
+ | Phase 7 — Refonte doc produit | A13, **A14 (ce document)** | ✅ Terminée |
804
+ | Phase 6 — Publication scientifique | A12 | ⏳ Planifiée |
805
+ | Phase 8 — Validation externe | A15 | ⏳ Planifiée (calendrier externe) |
806
 
807
+ ---
 
 
 
 
 
 
808
 
809
+ ## 12. Migration v1 → v2 — annexe historique
810
 
811
+ Pour les lecteurs qui avaient pris connaissance de SPECS v1.0
812
+ (mars 2025) ou de l'addendum Sprints 16-30, voici la table de
813
+ migration des promesses changées :
 
 
814
 
815
+ | SPECS v1 disait | SPECS v2 documente | Raison |
816
+ |---|---|---|
817
+ | Adapter Kraken (priorité v1.0) | Ouvert en plugin externe | Politique modules contribués Sprint 97 ; concentration sur 5 adapters cœur. |
818
+ | Adapter AWS Textract (v1.1) | Abandonné | Pas de DPA, périmètre couvert par 3 clouds existants. |
819
+ | Adapter Calamari (v1.1) | Abandonné | Maintenance par adapter ≈ 50 PJ/an ; mieux servi en plugin externe. |
820
+ | Adapter OCRopus4 (v1.2) | Abandonné | Projet historique en fin de vie. |
821
+ | Moteur custom YAML | Refondu en pipelines composables | Sprint 63-70 livre une infrastructure plus puissante. |
822
+ | Recommandation automatique | Remplacée par moteur narratif factuel | Pivot philosophique vers la neutralité éditoriale. |
823
+ | Export PDF | Abandonné | CSV + JSON + HTML couvrent les usages. |
824
+ | Export ALTO/PAGE/images annotées | Abandonné | Idem. |
825
+ | `picarones estimate` (preview coût) | Remplacé par vue Pareto post hoc | Sprint 20 livre la même information dans le rapport. |
826
+ | Score consensus / k-means | Remplacé par oracle borné + taxonomie discrète + Jaccard | Sprint 35, 5, 75 — équivalence fonctionnelle, formalisme différent. |
827
+ | Annotations inline JSON | Abandonné | Pas de demande utilisateur observée. |
828
+ | Badge SVG qualité OCR | Abandonné | `picarones compare` exit code 2 couvre la CI. |
829
+ | Dataset 100 docs embarqué | Abandonné | Banc d'essai sur votre golden dataset, pas un dataset de référence. |
830
+ | Prompt latin | Pas livré | Reportable sur demande. |
831
+
832
+ À l'inverse, **~25 modules majeurs ajoutés depuis Sprint 30** sont
833
+ documentés dans la nouvelle SPECS aux §6 (NER, reading order F1,
834
+ layout F1, recherchabilité fuzzy, séquences numériques, 6 modules
835
+ philologiques transversaux, narrative engine, Friedman+Nemenyi+CDD,
836
+ Pareto, glossaire, métriques inter-moteurs, absorption d'erreur,
837
+ pipelines composables, registre typé, audit modules, comparaison
838
+ de runs, stratification, calibration, longitudinal, throughput
839
+ effectif, etc.) — invisibles dans SPECS v1.
840
 
841
  ---
842
 
843
+ *Picarones est conçu pour devenir une référence open-source
844
+ d'évaluation OCR/HTR dans le champ patrimonial — métriques
845
+ adaptées aux documents historiques, pipelines composables,
846
+ intégration des standards bibliothéconomiques (IIIF, ALTO XML,
847
+ PAGE XML, HTR-United, eScriptorium, Gallica), rapport interactif
848
+ exportable, snapshot de reproductibilité.*
849
+
850
+ *Dernière mise à jour : 2 mai 2026 (Sprint A14, refonte v2.0).*