Spaces:
Running
Picarones — Spécifications fonctionnelles et techniques
Plateforme de banc d'essai d'OCR / HTR / VLM et de pipelines de post-correction pour documents patrimoniaux.
Version 0.9.0 (pré-1.0) — Mai 2026. Politique de versionning :
../explanation/versioning.md.Itération de spec 2 (révision éditoriale du document, distincte du numéro de version du logiciel ; mai 2026).
Note de lecture : ce document décrit ce que Picarones fait aujourd'hui, dans la version
0.9.0. Pour les non-fonctionnalités assumées (ce que Picarones ne fait pas et ne fera pas dans la lignée0.x— par exemple la recommandation prescriptive, l'export PDF, les adapters Kraken/AWS Textract), voir la section §10.Pour la cartographie technique du code et les règles de contribution interne, voir
CLAUDE.md. Ce document reste tourné « public » (vocabulaire bibliothécaire, exemples patrimoniaux). Les deux documents sont complémentaires, pas redondants.
Table des matières
- Vision et positionnement
- Architecture en 8 couches concentriques
- Module 1 — Corpus et imports
- Module 2 — Adaptateurs OCR / HTR
- Module 3 — Pipelines OCR+LLM et pipelines composables
- Module 4 — Métriques et analyses
- Module 5 — Rapport HTML interactif
- Module 6 — Interface web et CLI
- Reproductibilité et sécurité
- Limites assumées et non-fonctionnalités
- Roadmap d'évolution
- Migration v1 → v2 — annexe historique
1. Vision et positionnement
1.1 Problématique
Les équipes OCR/HTR travaillant sur des fonds patrimoniaux (manuscrits, imprimés anciens, archives) disposent d'un paysage hétérogène — moteurs locaux (Tesseract, Pero OCR), services cloud (Mistral OCR, Google Vision, Azure Document Intelligence), modèles fine-tunés maison, VLMs (GPT-4o, Claude, Mistral Large) — sans outil unifié pour les comparer rigoureusement sur leurs propres corpus.
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, ordre de lecture multi-colonnes, structure ALTO/PAGE.
À 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, et sans introduire d'over-normalisation moderne ? Aucun outil existant ne permet de tester et mesurer cela rigoureusement.
1.2 Philosophie : un banc d'essai, pas un atelier
Picarones est conçu comme un banc d'essai :
- L'utilisateur amène son golden dataset annoté (paires image + vérité terrain). Sans VT, pas de benchmark.
- Picarones exécute les IA candidates et mesure l'écart à la VT.
- Picarones classe les résultats avec rigueur statistique.
- Picarones n'arbitre pas le débat éditorial. Il ne dit pas si un moteur diplomatique vaut mieux qu'un moteur modernisant — il rapporte les chiffres et laisse le chercheur, l'archiviste ou le paléographe trancher selon ses critères propres.
Cette philosophie est tenue jusque dans le moteur narratif
factuel : chaque phrase de la synthèse en tête du rapport est
traçable à un payload de Fact qui provient du JSON d'entrée
(garde-fou anti-hallucination prouvé par tests).
1.3 Contributions scientifiques
Au-delà de la simple agrégation de moteurs, Picarones apporte plusieurs briques nouvelles dans l'écosystème OCR/HTR open-source :
- Registre typé de métriques (Sprint 34) : chaque métrique
est enregistrée pour une jonction de types
ArtifactType(TEXT/ALTO/PAGE/ENTITIES/READING_ORDER) ; un pipeline composé peut alors calculer automatiquement la métrique adéquate à chaque jonction de son DAG. - Interface BaseModule générique (Sprint 33) : OCR, mappeur VLM→ALTO, rewriter ALTO→ALTO, classifieur d'entités texte→entités partagent la même API ; le runner les enchaîne sans privilégier un type particulier.
- GT multi-niveaux (Sprint 32) : un document peut porter simultanément une vérité terrain texte, ALTO, PAGE, entités, et reading order — chacune calibrée à son niveau d'évaluation.
- Moteur narratif factuel anti-hallucination (Sprint 19+) :
20+ détecteurs déterministes produisent une synthèse en
langage naturel dont chaque chiffre est traçable au payload
d'un
Fact. Aucune intervention LLM, garde-fou prouvé par test (test_sprint23_anti_hallucination). - Test multi-moteurs Friedman + Nemenyi + Critical Difference Diagram (Sprint 18, Demšar 2006) : référence canonique pour la comparaison statistique de classifieurs, transposée à l'OCR.
- Pareto coût / vitesse / CO₂ (Sprint 20) : positionnement tri-objectifs avec front explicite, table de pricing surchargeable.
- Métriques philologiques transversales (Sprints 55–60) : six modules couvrant l'imprimé ancien, le médiéval, les archives modernes (XIXᵉ–XXᵉ), avec scores éditoriaux séparés (préservation stricte vs équivalence diplomatique).
1.4 Utilisateurs cibles
| Profil | Cas d'usage typique |
|---|---|
| Ingénieur OCR/ML | Pipeline programmatique, métriques fines, export JSON, intégration CI/CD via picarones run --fail-if-cer-above |
| Chargé de numérisation | Rapport HTML autonome, comparaison A vs B, lecture du Pareto coût/qualité |
| Responsable de projet | Vue agrégée multi-corpus, analyse coût/bénéfice des APIs cloud, suivi longitudinal SQLite |
| Chercheur en humanités numériques | Métriques philologiques, corpus HTR-United, taxonomie d'erreurs en 10 classes, glossaire contextuel |
| Paléographe / éditeur critique | Diff visuel par document, bascule diplomatique / normalisé, profil philologique séparant strict et expansion |
| DSI institutionnel | Déploiement intranet derrière SSO, RGPD, observabilité (cf. docs/operations/) |
2. Architecture en 8 couches concentriques
domain → formats → evaluation → pipeline → adapters → app → reports_v2 → interfaces
Règle de dépendance : les imports vont uniquement de
l'extérieur vers l'intérieur (de gauche à droite dans le
diagramme). La règle est appliquée par
tests/architecture/test_layer_dependencies.py qui parse
l'AST de chaque fichier et bloque toute violation au merge.
Note sur le legacy : le projet est en cours de retrait du legacy. Une arborescence historique (
picarones/{core,measurements,engines,llm,pipelines, report,modules}) cohabite encore et est en train de disparaître phase par phase. Cf.docs/archive/2026-migration/legacy-retirement-plan.mdpour le statut et le calendrier. Tout nouveau code va dans l'arborescence canonique ; les chemins legacy existants sont des shims minimaux destinés à être supprimés.
2.1 picarones/domain/ — types purs
Cercle le plus interne. Stdlib + Pydantic uniquement, aucune I/O, aucun framework, aucun module legacy.
| Module | Contenu |
|---|---|
artifacts.py |
Artifact, ArtifactType (10 types : IMAGE, RAW_TEXT, CORRECTED_TEXT, ALTO_XML, PAGE_XML, CANONICAL_DOCUMENT, ENTITIES, READING_ORDER, ALIGNMENT, CONFIDENCES) |
corpus.py |
CorpusSpec |
documents.py |
DocumentRef |
evaluation_spec.py |
MetricSpec, EvaluationView, EvaluationSpec |
pipeline_spec.py |
PipelineSpec, PipelineStep, INITIAL_STEP_ID |
projection_spec.py |
ProjectionSpec |
provenance.py |
ProvenanceRecord |
run_manifest.py |
RunManifest |
module_protocol.py |
BaseModule (ABC, voie de retrait au profit de StepExecutor) |
facts.py |
Fact, FactType, FactImportance, DetectorRegistry |
errors.py |
Hiérarchie d'exceptions (PicaronesError, AdapterStepError, …) |
2.2 picarones/formats/ — parsing / sérialisation
ALTO 4, PAGE XML, JSON, XML utilitaires. Stdlib + lxml + defusedxml. Pas de logique métier.
2.3 picarones/evaluation/ — métriques et calcul
Cœur de la valeur ajoutée. Stdlib + numpy + scipy + jiwer + spacy + rapidfuzz.
| Sous-paquet | Contenu |
|---|---|
metrics/ |
~30 métriques (CER, WER, MUFI, philological, NER, calibration, taxonomy, …) |
statistics/ |
Wilcoxon, Friedman/Nemenyi, bootstrap, Pareto, clustering, CDD |
views/, projectors/ |
EvaluationView (Sprint S13+), projecteurs AltoToText, PageToText, CanonicalToText |
corpus.py |
Document, Corpus, GTLevel, payloads (legacy en cours de retrait) |
metric_registry.py, metric_hooks.py, metric_result.py |
Registres typés + hooks + dataclasses résultats |
pipeline.py, pipeline_benchmark.py, pipeline_comparison.py |
PipelineRunner legacy + orchestration corpus-wide (en cours de convergence vers pipeline.executor) |
benchmark_result.py |
BenchmarkResult, EngineReport, DocumentResult, sérialisation JSON |
engines/ |
OCR engines legacy (BaseOCREngine-based) — temporairement avant suppression complète |
_diff_utils.py |
compute_word_diff, compute_char_diff, diff_stats |
2.4 picarones/pipeline/ — orchestration canonique
PipelineExecutor instance-based, StepExecutor Protocol,
ExecutionPlan immuable. Cible canonique pour le bench
d'axe B (pipelines composées).
2.5 picarones/adapters/ — adapters externes
Adapters OCR / LLM / VLM consommant des libs externes
(pytesseract, mistralai, openai, anthropic, google.cloud,
azure.*, pero_ocr, ollama). Implémentent StepExecutor.
| Sous-paquet | Contenu |
|---|---|
ocr/ |
TesseractAdapter, PeroOCRAdapter, MistralOCRAdapter, GoogleVisionAdapter, AzureDocIntelAdapter, PrecomputedAdapter |
llm/ |
BaseLLMAdapter + Mistral / OpenAI / Anthropic / Ollama |
vlm/ |
Adapters VLM (zero-shot OCR via vision-language models) |
corpus/ |
Loaders externes : IIIF, Gallica, HTR-United, HuggingFace |
storage/ |
ArtifactStore, JobStore (S29 + S47) |
legacy_engines/, legacy_modules/ |
Engines + modules legacy BaseModule-based (en cours de retrait, cf. Phase 7.A) |
2.6 picarones/app/ — services applicatifs
BenchmarkService, CorpusRunner, RunOrchestrator.
Orchestrent les pipelines canoniques sur corpus.
2.7 picarones/reports/ — rendu HTML / JSON / CSV
Rapport final consommant un BenchmarkResult ou RunResult.
22 renderers thématiques + 5 vues (advanced_taxonomy,
diagnostics, economics, pipeline, robustness) +
ReportGenerator orchestrateur + templates Jinja2 +
glossaire bilingue (25 entrées) + i18n FR/EN.
2.8 picarones/interfaces/ — entrées utilisateur
CLI Click, Web FastAPI, IIIF/Gallica/eScriptorium importers exposés en interface.
3. Module 1 — Corpus et imports
3.1 Formats de vérité terrain acceptés
| Format | Extension | Niveau GT | Usage typique |
|---|---|---|---|
| Texte brut | image.gt.txt |
TEXT | Convention Tesseract, HTR-United |
| ALTO XML v4 | .gt.alto.xml |
ALTO | Standard bibliothèques nationales, eScriptorium export |
| PAGE XML 2019 | .gt.page.xml |
PAGE | Transkribus, OCRopus |
| Entités nommées | .gt.entities.json |
ENTITIES | Format HIPE simplifié |
| Reading order | .gt.reading_order.json |
READING_ORDER | Liste ordonnée de region IDs |
Le loader (load_corpus_from_directory) détecte automatiquement
chacun de ces niveaux à côté de l'image. Un même document peut
porter plusieurs niveaux simultanément (Sprint 32).
3.2 Sources d'import
Local
Import d'un dossier de paires image / GT. Détection automatique
du format. Filtrage des fichiers macOS ._*.
IIIF
Import par URL de manifeste IIIF v2 et v3. Compatible Gallica (BnF), Bodleian, BL, Vatican, e-codices, Europeana, et tout entrepôt IIIF-compliant. Sélection par range de canvas.
HuggingFace Datasets
Recherche par filtre langue/script/époque/institution. Datasets
patrimoniaux pré-référencés (IAM, RIMES, READ-BAD, Esposalles,
HTR-United datasets). Statut : module
extras/importers/huggingface.py marqué expérimental
(UserWarning à l'import).
HTR-United
Listing du catalogue distant + import direct. Lecture des
métadonnées (langue, script, institution, époque). En cas
d'échec réseau ou parsing, fallback sur catalogue de démo +
émission d'un Fact IMPORTER_FALLBACK_TRIGGERED (Sprint A3).
Gallica (API BnF)
Recherche par cote, titre, auteur, date. Récupération des images via API IIIF Gallica.
eScriptorium
Connexion à une instance distante via API. Statut expérimental.
Upload ZIP via navigateur
Endpoint POST /api/corpus/upload. Validation Pillow
(décompression bombs), zip-slip prévenu, taille plafonnée
(PICARONES_MAX_UPLOAD_MB).
3.3 Gestion des corpus
- Corpus nommés et versionnés avec métadonnées descriptives.
- Tags : type de script, langue, siècle, institution, état de conservation.
- Stratification par
script_type(Sprint 45-46) — vue stratifiée dans le rapport, détecteur narratifSTRATIFICATION_RECOMMENDEDqui invite l'utilisateur quand le corpus est hétérogène.
4. Module 2 — Adaptateurs OCR / HTR
4.1 Architecture des adaptateurs
Chaque moteur OCR est une classe Python qui hérite de
BaseOCREngine (picarones/adapters/legacy_engines/base.py), elle-même héritière
de BaseModule (Sprint 33). Une instance déclare son
execution_mode ("io" ou "cpu") que le runner utilise pour
choisir entre ThreadPoolExecutor (cloud APIs) et
ProcessPoolExecutor (Tesseract, Pero).
Ajouter un nouveau moteur = créer une classe Python de ~50 lignes
qui implémente _run_ocr(image_path) -> str et déclare son
execution_mode.
4.2 Moteurs OCR livrés
| Moteur | Type | Mode d'exécution | Confidence native exposée ? |
|---|---|---|---|
| Tesseract 5 | Local CLI | CPU (ProcessPool) | ✅ Sprint 47 (image_to_data) |
| Pero OCR | Local Python | CPU (ProcessPool) | ✅ Sprint 48 (transcription_confidence ligne) |
| Mistral OCR | Cloud API | IO (ThreadPool) | ✅ Sprint 49 (quand disponible côté API) |
| Google Vision | Cloud API | IO (ThreadPool) | ✅ Sprint 50 (Word.confidence en mode DOCUMENT_TEXT_DETECTION) |
| Azure Doc Intelligence | Cloud API | IO (ThreadPool) | ✅ Sprint 51 (Word.confidence) |
Quand un moteur expose ses confidences natives, le runner calcule automatiquement les métriques de calibration (ECE, MCE, reliability diagram — Sprint 39-43).
4.3 Robustesse runtime
- Erreurs HTTP cloud (4xx/5xx, timeout, body mal formé) :
remontées dans
EngineResult.erroravec le code HTTP, jamais avalées silencieusement (Sprint A5 / m-10, 19 cas testés). - Crash isolé d'un document : le runner continue avec les
autres documents. Le doc en échec a
engine_errorrempli. - Cancel mid-run :
cancel_event.set()interrompt proprement. - Timeout par document : configurable via paramètre
timeout_seconds.
5. Module 3 — Pipelines OCR+LLM et pipelines composables
5.1 Pipelines OCR+LLM historiques (Sprint 3+)
L'unité de comparaison est le concurrent — pas forcément un moteur seul, mais une chaîne produisant du texte à partir d'une image.
| Mode | Description | Usage typique |
|---|---|---|
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 |
post_correction_texte |
OCR → texte brut → LLM corrige le texte | LLM non multimodal (Llama local), grand volume |
post_correction_image_texte |
OCR → LLM reçoit image ET texte brut | Meilleure qualité ; le LLM voit le contexte visuel |
Les prompts sont versionnés dans picarones/prompts/ (8 fichiers
FR + EN), embarqués dans le snapshot du rapport pour
reproductibilité.
5.2 Pipelines composables (Sprint 63+)
Au-delà des 3 modes historiques, Picarones livre une infrastructure
générique : un pipeline est une liste d'étapes BaseModule
qui produit un artefact à chaque étape (TEXT, ALTO, PAGE,
ENTITIES…) ; à chaque jonction, le runner calcule
automatiquement la métrique adéquate via compute_at_junction
(registre typé Sprint 34).
# Spec YAML chargée par picarones pipeline run
name: ocr_then_corrector
steps:
- name: ocr
module: picarones.engines.tesseract.TesseractEngine
args: { lang: "fra", psm: 6 }
- name: post_correction
module: my_module.MyLLMCorrector
args: { model: "gpt-4o" }
picarones pipeline compare specs.yaml --corpus ./scans --output rapport.html
exécute N pipelines sur le même corpus et produit un rapport
comparatif. Conçu pour qu'un mainteneur tiers puisse contribuer
ses propres modules sans toucher au cœur de Picarones (cf.
docs/developer/module-policy.md, Sprint 97).
5.3 Détection d'over-normalisation LLM
Risque spécifique aux pipelines OCR+LLM : le LLM modernise à tort des graphies historiques légitimes. Picarones mesure :
- Modernisation lexicale (Sprint 80) : top-N tokens GT
systématiquement remplacés (
maistre → maîtredans 100 % des cas → signal exploitable). - Score d'absorption d'erreur (Sprint 94) : à chaque jonction OCR→LLM, calcule le taux de correction (parmi les erreurs avant, combien corrigées) et le taux d'introduction (parmi les erreurs après, combien nouvelles). Distingue un module qui corrige d'un module qui écrase.
- Delta Flesch (Sprint 52) : sur les langues prises en charge, signale les LLM qui rendent le texte « trop moderne » par rapport à la GT.
- Score d'ancrage (Sprint 10) : proportion des trigrammes produits par le LLM qui s'ancrent dans la GT — score bas = hallucination probable.
6. Module 4 — Métriques et analyses
6.1 Catalogue exhaustif des métriques
Picarones livre plus de 30 métriques organisées en familles.
Pour chaque métrique : son nom, sa jonction de types, sa source,
ses limites — voir le glossaire contextuel intégré au rapport
HTML (25 entrées bilingues, ouvre via le ? à côté du nom de
colonne) et picarones/report/glossary/{fr,en}.yaml.
Classique OCR/HTR
| Métrique | Jonction | Source primaire |
|---|---|---|
| CER (raw, NFC, caseless, diplomatique) | (TEXT, TEXT) |
Levenshtein character / jiwer |
| WER, MER, WIL | (TEXT, TEXT) |
jiwer |
| Bootstrap CI 95 % | dérivé | Efron (1979) |
| Distribution CER par ligne, Gini | dérivé | Sprint 10 |
| Détection hallucinations VLM (anchor score, length ratio) | dérivé | Sprint 10 |
Philologique (Sprints 52-60, 80, 84-85, 92-94)
| Métrique | Jonction | Cible patrimoniale |
|---|---|---|
| Couverture MUFI | (TEXT, TEXT) |
Manuscrits médiévaux |
| Score d'expansion d'abréviations Capelli | (TEXT, TEXT) |
Médiéval |
| Précision par bloc Unicode | (TEXT, TEXT) |
Imprimés anciens / médiéval |
| Préservation des marqueurs typographiques de l'imprimé ancien (long-s, ligatures, tildes nasaux) | (TEXT, TEXT) |
XVIᵉ-XVIIIᵉ |
| Marqueurs des archives modernes (titres, ordinaux, monnaies, état civil…) | (TEXT, TEXT) |
XIXᵉ-XXᵉ |
| Préservation des numéraux romains (5 statuts) | (TEXT, TEXT) |
Toutes périodes |
| Recherchabilité fuzzy (Levenshtein distance ≤ 2) | (TEXT, TEXT) |
Indexation Elastic / full-text |
| Précision sur séquences numériques (dates, foliotation, monnaies) | (TEXT, TEXT) |
Archives, économie historique |
| Modernisation lexicale (top-N tokens GT modernisés) | (TEXT, TEXT) |
Pipelines OCR+LLM |
| Delta Flesch (FR + EN) | (TEXT, TEXT) |
Repère VLM hallucinant du français moderne |
| Score d'absorption d'erreur par jonction | (TEXT, TEXT) |
Pipelines composées |
| Précision sur entités nommées (HIPE) | (ENTITIES, ENTITIES) |
Indexation prosopographique |
| Reading order F1 (ICDAR 2015) | (READING_ORDER, READING_ORDER) |
Manuscrits glosés, journaux multi-colonnes |
| Layout F1 par type de région (IoU 0.5) | (ALTO, ALTO) |
Texte/glose/marginalia |
Comparaison & décision (Sprints 18, 20, 35-37, 81, 89-92, 96)
| Métrique | Source primaire |
|---|---|
| Test multi-moteurs Friedman + post-hoc Nemenyi + CDD | Demšar (2006) |
| Test pairé Wilcoxon | Wilcoxon (1945) |
| Pareto coût / vitesse / CO₂ (multi-objectifs N dim) | Pareto (1896) |
| Divergence taxonomique inter-moteurs (Jensen-Shannon) | Lin (1991) |
| Oracle complementarity (recall borné supérieur) | Sprint 35 |
| Score de spécialisation inter-moteurs | Sprint 89 |
| Stabilité multi-runs (CV CER, accord identique) | Sprint 83 |
| Accord inter-annotateurs (Cohen κ, Krippendorff α) | Cohen (1960), Krippendorff (1970) |
| Tendance longitudinale + change-point Pettitt | Sprint 92 |
| Throughput effectif (pages/h après correction humaine 5s/erreur) | Sprint 91, HTR-United |
| Coût marginal par erreur évitée | Sprint 91 |
| Comparaison incrémentale ANOVA-like par slot | Sprint 96 |
Note de traçabilité : les références primaires (Demšar 2006,
Wilcoxon 1945, Efron 1979, etc.) sont citées dans les docstrings
de chaque fonction de picarones/measurements/statistics/.
Le glossaire contextuel relie chaque métrique à sa publication
canonique (champ reference).
6.2 Profils de normalisation
11 profils livrés (picarones/formats/text/normalization.py,
exposés via /api/normalization/profiles) : nfc, caseless,
minimal, medieval_french, early_modern_french,
medieval_latin, medieval_english, early_modern_english,
secretary_hand, sans_ponctuation, sans_apostrophes.
Chaque profil applique un ensemble d'équivalences diplomatiques (ſ=s, u=v, i=j, ꝑ=per, þ=th, etc.). Un profil custom peut être chargé depuis YAML.
Traçabilité aux standards éditoriaux (MUFI v4.0, TEI P5 Unicode chapter 3.4, DEAF) : prévue Sprint A12 (item B-6 du plan de remédiation institutionnelle).
6.3 Taxonomie des erreurs en 10 classes
Catégorisation automatique de chaque erreur (Sprint 5) :
- Confusion visuelle (rn/m, l/1, O/0, u/n…)
- Erreur diacritique
- Erreur de casse
- Ligature non résolue
- Abréviation non développée
- Hapax (mot absent du lexique)
- Segmentation (fusion / fragmentation)
- Hors-vocabulaire
- Lacune (texte présent en GT, absent en OCR)
- Sur-normalisation LLM
6.4 Score de difficulté intrinsèque
Indicateur calculé indépendamment des moteurs (Sprint 7) :
- variance du CER entre tous les concurrents (si tous ratent → document objectivement difficile),
- métriques de qualité image,
- densité de caractères spéciaux (ligatures, abréviations, diacritiques),
- longueur et densité du texte.
Sépare deux questions distinctes : « est-ce que ce moteur est mauvais ? » vs « est-ce que ce document est objectivement difficile ? ».
7. Module 5 — Rapport HTML interactif
Le rapport est un fichier HTML auto-portant (Jinja2 server-side, Chart.js vendoré inline), lisible hors-ligne, embarquant toutes les données et visualisations.
7.1 Cinq vues + sections globales
Sections globales (en tête)
- Synthèse narrative factuelle (Sprint 19+) : 3-5 phrases
produites par 20+ détecteurs déterministes. Chaque chiffre
rendu est traçable au payload du
Factcorrespondant (anti-hallucination prouvé par test). - Critical Difference Diagram (Sprint 18) : SVG server-side, Friedman + post-hoc Nemenyi.
- Section inter-moteurs (Sprint 37) : matrice de divergence taxonomique + encart oracle complementarity.
- Front Pareto (Sprint 20) : coût / vitesse / CO₂ avec toggles d'axes.
- Section leviers d'amélioration (Sprint 51-82) : 5 leviers factuels (taxonomie récupérable, concentration Pareto, complémentarité, modernisation lexicale, déficit projeté de robustesse).
Vue Classement (Ranking)
Tableau triable : CER (médiane par défaut depuis Sprint 44),
WER, MER, WIL, scores ligatures et diacritiques, Gini, score
d'ancrage, sur-normalisation, etc. Vue stratifiée optionnelle
par script_type (Sprint 45-46).
Vue Galerie (Gallery)
Grille de vignettes avec badge CER coloré. Filtres dynamiques (CER > X, qualité image, type de script, longueur GT). Tri multi-critères. Vue « Worst lines globale » (Sprint 72) qui transcende les documents et liste les lignes individuelles les plus mal transcrites.
Vue Document
Image originale + diff token coloré façon GitHub par moteur, scroll synchronisé N-way. Vue spécifique OCR+LLM : triple diff GT / sortie OCR brute / sortie après LLM.
Vue Analyses
Distribution CER (histogramme + densité), scatter plots qualité image vs CER, heatmap de confusion de caractères, diagrammes de fiabilité (calibration ECE/MCE — Sprint 43), graphiques de bootstrap CI 95 %, profil philologique par moteur (Sprint 62), throughput effectif (Sprint 91), tendances longitudinales (Sprint 92), DAG de pipeline composée (Sprint 95), etc.
Vue Caractères
Matrice de confusion Unicode interactive, tableau des caractères les plus souvent manqués par chaque moteur, CER par bloc Unicode (Sprint 55), analyse des ligatures.
7.2 Panneaux latéraux
- Glossaire contextuel (Sprint 21) :
?à côté de chaque en-tête de colonne ; clic ouvre un panneau avec définition, ce qu'on mesure, usage, limites, référence primaire (25 entrées bilingues). - Mode avancé (Sprint 21) : choix de colonnes visibles, filtres par strate, opt-in score composite personnel (curseurs à 0 par défaut, formule visible, warning explicite « il n'existe pas de pondération universellement valide »), toggle palette daltonien-friendly (Sprint A7), URL stateful.
7.3 Exports
| Format | Statut |
|---|---|
| HTML autonome | ✅ Livré |
| CSV (vue courante avec filtres) | ✅ Livré |
| JSON (BenchmarkResult complet) | ✅ Livré |
| Snapshot reproductibilité (versions, commit, lock) | ✅ Sprint 27 |
Lazy images (rapport HTML + dossier report-assets/) |
✅ Sprint A5 / M-16 |
| ❌ Non livré (cf. §10) | |
| ALTO XML / PAGE XML / images annotées | ❌ Non livré (cf. §10) |
7.4 Accessibilité
Conformité WCAG 2.1 niveau AA (cf.
docs/operations/accessibility.md) :
- Skip-to-content link (WCAG 2.4.1).
role="img"+aria-label+ table de données jumelle pour chaque graphique Chart.js (WCAG 1.1.1).scope="col"sur tous les<th>.- Palette par défaut Okabe-Ito (daltonien-friendly), toggle vers
l'ancienne palette via panneau Avancé ou
?palette=classic. - Bilinguisme intégral (skip-link, ARIA labels, captions des tables jumelles).
- Audit RGAA externe planifié Sprint A15.
8. Module 6 — Interface web et CLI
8.1 Interface web FastAPI
- Configuration de benchmark : sélection corpus, moteurs, normalisation.
- Streaming SSE de la progression en temps réel (
Last-Event-IDreconnexion supportée — Sprint 26). - Persistance des jobs en SQLite (mode WAL, thread-safe), reprise des jobs orphelins au boot.
- Upload ZIP depuis le navigateur.
- Imports HTR-United / HuggingFace via formulaire.
- Bilingue FR/EN.
- Healthcheck minimal
/health(Sprint A4 / M-3). - Token CSRF (
/api/csrf/token) + middleware (Sprint A4 / B-11) activable viaPICARONES_CSRF_REQUIRED=1pour les déploiements institutionnels derrière SSO.
8.2 Interface en ligne de commande (Click)
15 commandes :
picarones run # benchmark
picarones report # rapport HTML depuis JSON
picarones demo # rapport démo synthétique
picarones compare # compare deux runs JSON, exit-code 2 si régression
picarones diagnose # workflow bench + leviers + recommandations factuelles
picarones economics # workflow bench + throughput + coût projeté
picarones edition # workflow bench + métriques philologiques
picarones pipeline # run/compare pipelines composées YAML
picarones import # IIIF / HF / HTR-United
picarones serve # interface web locale
picarones history # historique longitudinal SQLite
picarones robustness # courbes CER vs dégradation
picarones engines # liste les moteurs disponibles
picarones metrics # CER/WER entre deux fichiers texte
picarones info # version + system info
Toutes les commandes supportent --help. Workflows pré-câblés
(diagnose, economics, edition) sont des combinaisons
canoniques pour les profils utilisateurs typiques.
8.3 Intégration CI/CD
- Mode headless (
--no-progress). - Output JSON machine-readable.
- Exit code 2 sur
picarones comparesi régression CER détectée. - Workflow GitHub Actions
perf_regression.yml(Sprint A5 / M-14) — cron hebdomadaire + sur PR touchant le runner.
9. Reproductibilité et sécurité
9.1 Snapshots de reproductibilité (Sprint 27)
Chaque rapport HTML embarque un dict report_data["snapshots"]
qui contient :
- pricing — YAML brut intégral de
picarones/data/pricing.yamlutilisé. - glossary — entrées du glossaire effectivement référencées.
- normalization — profil sérialisé.
- environment — version Picarones, Python, plateforme, commit git, paquets installés (top 200).
Procédure complète de re-jeu d'un benchmark à 5 ans d'écart :
docs/reference/reproducibility-snapshots.md
(Sprint A8 / M-12).
9.2 Reproductibilité des builds
- Lock files
requirements.lock+requirements-dev.lockgénérés viauv pip compile(Sprint A8). - Image Docker épinglée à un patch précis via
ARG PYTHON_BASE_IMAGE(rotation trimestrielle). - Release pipeline GitHub Actions (Sprint A9) : tag
v*.*.*→ PyPI via OIDC trust + ghcr.io multi-arch + GitHub Release auto.
9.3 Sécurité institutionnelle
- Mode public (
PICARONES_PUBLIC_MODE=1) : refuse les moteurs cloud mutualisés et les pipelines LLM facturés à la clef serveur. - CSRF double-submit (
PICARONES_CSRF_REQUIRED=1) — Sprint A4. - XML défendu par
defusedxmlpartout (XXE / Billion Laughs). - Zip-slip prévenu par
Path(member.filename).name. - Validation Pillow systématique (CVE bombes de décompression).
- Rate limiting par IP + sémaphore de jobs concurrents.
- CSP + en-têtes durcis (X-Content-Type-Options, Referrer-Policy).
Voir SECURITY.md pour la procédure complète.
9.4 RGPD et rétention
Politique documentée dans
docs/operations/data-retention-rgpd.md
(Sprint A11 / M-8). Purge automatique des uploads anciens
configurable via PICARONES_UPLOAD_RETENTION_DAYS=7 par défaut.
10. Limites assumées et non-fonctionnalités
Cette section décrit explicitement ce que Picarones ne fait pas
et ne fera pas dans la lignée 0.x. Plusieurs items étaient
promis dans une itération antérieure de cette spec (SPECS v1, mars
2025) — leur abandon est un choix éditorial documenté ci-dessous,
pas un oubli. Les mentions « v1.0 », « v1.1 », « v1.2 » dans les
items ci-dessous renvoient à la roadmap historique de cette
spec, pas à des versions logicielles publiées.
Toutes les fonctionnalités listées ci-dessous étaient promises ou évoquées dans SPECS v1 (itération de spec) et sont explicitement abandonnées, non implémentées ou reportées dans l'itération de spec actuelle (qui couvre le logiciel
0.9.0). Le testtests/docs/test_specs_consistency.pydétecte cette section comme la déclaration officielle des non-fonctionnalités du projet.
10.1 Adapters OCR non livrés
- Kraken : prévu v1.0 dans SPECS v1, jamais implémenté. Choix :
ouverture en plugins externes via la politique de modules
contribués (Sprint 97), pas un adapter intégré au cœur. Un
utilisateur peut écrire son
KrakenEngine(BaseOCREngine)et l'exécuter via les pipelines composables. - AWS Textract : prévu v1.1, abandonné. Pas de DPA Amazon signé, et le périmètre patrimonial est mieux servi par les trois clouds déjà intégrés (Mistral OCR, Google Vision, Azure DI).
- Calamari : prévu v1.1, abandonné. Maintenance d'un adapter par moteur ≈ 50 PJ/an ; mieux vaut concentrer sur les 5 adapters livrés et ouvrir Calamari en plugin externe.
- OCRopus4 : prévu v1.2, abandonné — projet historique en fin de vie.
- Moteur custom YAML (
type: cli/type: api) : prévu en SPECS v1.0, abandonné. Refondu en pipelines composables (Sprint 63-70) qui permettent de brancher n'importe quel module via une spec YAML — plus puissant que la déclaration d'engine custom imaginée à l'origine.
10.2 Exports non livrés
- Export PDF du rapport. CSV + JSON + HTML autonome couvrent les usages observés. Reportable sur demande utilisateur si besoin tracé.
- Export ALTO XML des sorties OCR.
- Export PAGE XML des sorties OCR.
- Export images annotées (PNG avec zones d'erreur surlignées).
10.3 Fonctionnalités explicitement abandonnées
- Recommandation automatique « quel concurrent pour quel usage ». Promise dans SPECS v1 §7.1, abandonnée au profit du moteur narratif factuel (Sprint 19) et de la philosophie « Picarones mesure et classe — il ne tranche pas ». Les leviers d'amélioration (Sprint 51-82) restent factuels.
- Score de consensus / vote majoritaire / ensemble : Picarones livre l'oracle borné supérieur (Sprint 35) et le score de spécialisation inter-moteurs (Sprint 89) — observations factuelles. Pas de mécanisme de vote actif intégré ; au chercheur de combiner les sorties s'il le décide.
- Clustering automatique k-means des erreurs. Remplacé par la taxonomie discrète (Sprint 5) + co-occurrence Jaccard (Sprint 75) + heatmap intra-doc (Sprint 76).
- Annotations inline du paléographe exportées en JSON. Non implémentées.
- Badge SVG de qualité OCR pour CI.
picarones compareavec exit code 2 sur régression couvre l'usage CI ; un badge SVG reste nice-to-have, non priorisé. - Dataset de référence embarqué de 100 documents
patrimoniaux. Picarones est volontairement un banc d'essai
sur votre golden dataset — le 100-doc corpus de référence
imaginé en SPECS v1 §3.3 entrerait en concurrence avec les
corpus institutionnels existants (HTR-United, Esposalles,
IAM, RIMES, READ-BAD) et en fragmenterait l'écosystème. Les
5 documents synthétiques de Sprint A5 (
tests/fixtures/reference_corpus/) servent uniquement à l'anti-régression CER en CI, pas à la valeur scientifique.
10.4 Fonctionnalités scientifiques planifiées
À livrer dans des sprints futurs :
- CITATION.cff + DOI Zenodo + papier JOSS (Sprint A12 du plan institutionnel) — débloque la citation académique propre.
- Traçabilité des profils de normalisation aux standards éditoriaux (MUFI v4.0, TEI P5, DEAF) — Sprint A12.
- Citations primaires des méthodes statistiques dans les docstrings (Demšar 2006, Wilcoxon 1945, Efron 1979) — Sprint A12.
11. Roadmap d'évolution
Trois documents complémentaires pilotent l'évolution :
CHANGELOG.md— historique sprint par sprint, format Keep a Changelog.docs/roadmap/backlog.md— backlog vivant des chantiers post-0.9.0.docs/archive/— audits institutionnels, plans de remédiation pré-rewrite, roadmap historique (2026-roadmap/evolution.md), changelog pré-rewrite.
L'état du plan institutionnel au 2 mai 2026 :
| Phase | Sprints | Statut |
|---|---|---|
| Phase 0 — Garde-fous CI | A1, A2 | ✅ Terminée |
| Phase 1 — Hygiène architecturale | A3 | ✅ Terminée |
| Phase 2 — Robustesse runtime | A4, A5 | ✅ Terminée |
| Phase 3 — Accessibilité | A6, A7 | ✅ Terminée |
| Phase 4 — Reproductibilité ops | A8, A9 | ✅ Terminée |
| Phase 5 — Gouvernance | A10, A11 | ✅ Terminée |
| Phase 7 — Refonte doc produit | A13, A14 (ce document) | ✅ Terminée |
| Phase 6 — Publication scientifique | A12 | ⏳ Planifiée |
| Phase 8 — Validation externe | A15 | ⏳ Planifiée (calendrier externe) |
12. Migration des itérations de spec (v1 → v2) — annexe historique
Cette section trace l'évolution éditoriale du document de spécification entre son itération 1 (SPECS v1, mars 2025) et son itération 2 (le présent document). Les indices « v1.0 », « v1.1 » dans la colonne de gauche désignent la roadmap historique de SPECS v1, pas des versions logicielles publiées. Pour la politique de versionning du logiciel, voir
../explanation/versioning.md.
Pour les lecteurs qui avaient pris connaissance de SPECS v1.0 (mars 2025) ou de l'Addendum Sprints 16-30, voici la table de migration des promesses changées :
| SPECS v1 disait | SPECS itération 2 documente | Raison |
|---|---|---|
| Adapter Kraken (priorité v1.0) | Ouvert en plugin externe | Politique modules contribués Sprint 97 ; concentration sur 5 adapters cœur. |
| Adapter AWS Textract (v1.1) | Abandonné | Pas de DPA, périmètre couvert par 3 clouds existants. |
| Adapter Calamari (v1.1) | Abandonné | Maintenance par adapter ≈ 50 PJ/an ; mieux servi en plugin externe. |
| Adapter OCRopus4 (v1.2) | Abandonné | Projet historique en fin de vie. |
| Moteur custom YAML | Refondu en pipelines composables | Sprint 63-70 livre une infrastructure plus puissante. |
| Recommandation automatique | Remplacée par moteur narratif factuel | Pivot philosophique vers la neutralité éditoriale. |
| Export PDF | Abandonné | CSV + JSON + HTML couvrent les usages. |
| Export ALTO/PAGE/images annotées | Abandonné | Idem. |
picarones estimate (preview coût) |
Remplacé par vue Pareto post hoc | Sprint 20 livre la même information dans le rapport. |
| Score consensus / k-means | Remplacé par oracle borné + taxonomie discrète + Jaccard | Sprint 35, 5, 75 — équivalence fonctionnelle, formalisme différent. |
| Annotations inline JSON | Abandonné | Pas de demande utilisateur observée. |
| Badge SVG qualité OCR | Abandonné | picarones compare exit code 2 couvre la CI. |
| Dataset 100 docs embarqué | Abandonné | Banc d'essai sur votre golden dataset, pas un dataset de référence. |
| Prompt latin | Pas livré | Reportable sur demande. |
À l'inverse, ~25 modules majeurs ajoutés depuis Sprint 30 sont documentés dans la nouvelle SPECS aux §6 (NER, reading order F1, layout F1, recherchabilité fuzzy, séquences numériques, 6 modules philologiques transversaux, narrative engine, Friedman+Nemenyi+CDD, Pareto, glossaire, métriques inter-moteurs, absorption d'erreur, pipelines composables, registre typé, audit modules, comparaison de runs, stratification, calibration, longitudinal, throughput effectif, etc.) — invisibles dans SPECS v1.
Picarones est conçu pour devenir une référence open-source d'évaluation OCR/HTR dans le champ patrimonial — métriques adaptées aux documents historiques, pipelines composables, intégration des standards bibliothéconomiques (IIIF, ALTO XML, PAGE XML, HTR-United, eScriptorium, Gallica), rapport interactif exportable, snapshot de reproductibilité.
Dernière mise à jour : 23 mai 2026 (repositionnement SemVer pré-1.0,
couvre logiciel 0.9.0).