Spaces:
Sleeping
État du rewrite — Sprints A14-S46 puis S47-S57 (audit + remédiation)
Ce document synthétise l'état du rewrite du Picarones après les 20 sprints S27-S46 réalisés sur la directive « rewrite tout, le plus solide, sans dette technique », puis les 11 sprints S47-S57 d'audit/remédiation des 30 dettes identifiées en revue de fin de rewrite (audit 2026-05).
Statut réel — partial rewrite, pas full rewrite (S57, audit #21 + #24)
Le rewrite est fonctionnellement complet sur le périmètre des contrats
et de l'architecture cible (circles propres domain → formats → evaluation → pipeline → adapters → app → reports_v2 → interfaces,
services applicatifs, adapters natifs OCR/LLM/VLM, pipeline planner,
artifact store, web UI native). La formulation initiale « rewrite
fonctionnellement complet » était trop forte sur deux dimensions
relevées par l'audit :
Parité fonctionnelle non encore atteinte côté rendu rapport : le legacy
picarones/report/contient ~22 vues HTML thématiques (Pareto, narrative, glossary, case-studies, etc.) quereports_v2/ne reproduit pas intégralement. Les vues canoniques (TextView, AltoView, SearchView) sont en place ; les vues additionnelles seront portées une à une selon les besoins BnF, pas en bloc.Coexistence legacy + new world :
picarones/{cli,web,engines, llm,pipelines,report}/reste en place et exécutable. Un caller externe peut encore importer depuis n'importe lequel. Cette coexistence est volontaire (cf. Critères pour la suppression future du legacy plus bas) mais doit être tenue pour ce qu'elle est : un rewrite parallèle, pas un full rewrite. Les usages production sont à migrer caller par caller.Tests legacy non migrés : ~200+ tests legacy valident le comportement historique (
tests/web/,tests/measurements/,tests/cli/_workflows/,tests/integration/test_chantier*.py, etc.). Ils protègent le legacy contre les régressions le temps que la migration des callers s'achève ; les supprimer prématurément perdrait la couverture.
Inventaire des modules legacy
| Module | Statut | Nouvelle implémentation | Action S46 |
|---|---|---|---|
picarones/cli/ |
LEGACY | picarones/interfaces/cli/ (3 commandes) |
Conserver — features CLI manquantes |
picarones/web/ |
LEGACY | picarones/interfaces/web/ (skeleton + 3 routers + UI) |
Conserver — UI riche manquante |
picarones/engines/ |
LEGACY | picarones/adapters/ocr/ (5 natifs) |
Conserver — feature parité (confidences) |
picarones/llm/ |
RE-EXPORT | picarones/adapters/llm/ |
Déjà migré (re-export pur) |
picarones/pipelines/ |
LEGACY | (composition via pipeline DAG natif S6+) | Conserver — pas d'équivalent direct |
picarones/report/ |
LEGACY | picarones/reports_v2/{html,csv,json}/ |
Conserver — vues thématiques manquantes |
Ce qui est DÉFINITIVEMENT migré (S27-S45)
Sprints S27-S29 — Fondations architecturales
ProjectionEngine+EvaluationEngineséparés (S27)PipelinePlanner+ExecutionPlan(S28)ArtifactStoreavec hash multi-paramètres + persistance filesystem (S29)
Sprints S30-S34 — 5 OCR engines natifs (NO SHIM)
TesseractAdapter(S30)PeroOCRAdapter(S31)MistralOCRAdapter(S32)GoogleVisionAdapter(S33)AzureDocIntelAdapter(S34)
Tous héritent directement de BaseOCRAdapter (S26), pas du legacy
BaseOCREngine. Le legacy peut être supprimé une fois les confidences
migrées vers ConfidenceArtifact (sprint dédié).
Sprints S35-S38 — Web app native (NO SHIM)
- Skeleton FastAPI avec DI (
WebAppState,create_app) — S35 - Routers corpus + benchmark — S36
- JobStore SQLite + jobs router — S37
- UI Jinja2 + static + i18n FR/EN — S38
Sprints S39-S41 — Format YAML + domain cleanup
- RunSpec étendu (
inputs_from,preferred_text_output) — S39 PipelineSpecmigré dansdomain/— S40artifacts_index.jsonlséparé — S41
Sprints S42-S43 — Reports CSV + JSON
CsvReportRenderer— S42JsonReportRenderer— S43
Sprints S44-S45 — LLM/VLM nativement intégrés (NO SHIM)
- Les 4 LLM adapters (Anthropic, OpenAI, Mistral, Ollama) ont désormais
un
execute()natif compatibleStepExecutor— S44 - 4 VLM adapters dérivés via MRO multiple — S45
Critères pour la suppression future du legacy
Pour chaque module legacy à supprimer, il faut :
- Parité fonctionnelle : tout ce que fait le legacy doit avoir un équivalent dans le new world.
- Migration des tests : les tests legacy doivent soit migrer vers le new world, soit être identifiés comme supprimables.
- Migration des callers externes : si des callers externes
importent depuis
picarones.web.app(par ex. dans le HuggingFace Space), ils doivent être migrés en amont. - Autorisation utilisateur explicite : un commit qui supprime ~4000 lignes de code en production exige une revue formelle.
Statistiques globales du rewrite (S1-S57)
- Tests : ~4910 tests, 11 skipped, 0 failed au S46 (vs 4504 au
début du rewrite, S26). Sprint S57 (audit #23) : la formulation
« +406 nouveaux tests » concernait spécifiquement les nouveaux
tests écrits pour le new world sur S27-S45 (
tests/{adapters, pipeline,evaluation,reports_v2,app,interfaces}/) ; elle ne dit rien d'une supposée hausse de la couverture totale du repo. Les tests legacy (tests/{web,cli,engines,measurements,...}/) ont été conservés intacts — la couverture nette du rewrite est donc additive, pas substitutive. - Lint :
ruff check picarones/ tests/clean. - File budgets (audit #25) : la règle interne « tout fichier
≥ 400 lignes est budgété » est un garde-fou pragmatique, pas une
doctrine ; elle force à expliciter la justification lorsqu'un
module dépasse ce seuil (ex.
interfaces/web/app.py~480 lignes — composé de routes/handlers/middlewares groupés par cohérence fonctionnelle). Aucun fichier ne dépasse 800 lignes après S46. - Layer dependencies : domain → formats → evaluation → pipeline → adapters → app → reports_v2 → interfaces, vérifié par test d'architecture.
Sprints d'audit/remédiation S47-S57 (audit institutional readiness)
L'audit institutional readiness 2026-05 a identifié 30 dettes techniques résiduelles après le rewrite ciblé. Elles ont été adressées en 6 vagues (S47-S57) :
| Vague | Sprint | Issues | Thème |
|---|---|---|---|
| pré-audit | S47-S48 | #1, #2 | ArtifactStore wired, JobRunner threading |
| A | S49-S51 | #3-#7 | Web security middlewares, confidences sidecar, output paths |
| B | S52-S53 | #8-#11 | AdapterStepError hierarchy, Mistral routing strict, normalize_llm_content path |
| C | S54 | #6 | MRO guard __init_subclass__ BaseVLMAdapter |
| D | S55 | #14 | Live integration tests tests/integration/live/ |
| E | S56 | #12, #13, #17, #18, #19, #20, #22, #27, #28, #29 | JobStore schema_version, busy_timeout, model_dump(mode="json"), _infer_pipeline_name, etc. |
| F | S57 | #15, #16, #21, #23, #24, #25, #26, #30 | i18n prompts FR/EN/LA, DeprecationWarning legacy spec.py, doc rectifications |
Tous les 30 issues sont adressés au S57. Les détails sont dans
docs/audits/remediation-plan-2026-05.md.
Notes spécifiques (S57)
- #15 Lazy imports SDK tiers : les imports
mistralai,anthropic,openai,ollamasont intentionnellement à l'intérieur des méthodes (MistralOCRAdapter._call_chat_vision_api, etc.) plutôt qu'au top du module. Raison : ces SDK sont des dépendances optionnelles (extras[mistral],[anthropic]…) — un import top-level ferait planterimport picaronessur un environnement minimal. Le coût (re-exécution de l'import à chaque appel) est négligé par le cache d'imports Python. - #16 i18n prompts FR/EN/LA :
BaseLLMAdapter.DEFAULT_CORRECTION_PROMPTSetBaseVLMAdapter.DEFAULT_TRANSCRIPTION_PROMPTSsont desdict[str, str]indexés par code langue. Sélection : override explicite viaconfig["correction_prompt"]/["transcription_prompt"]config["lang"](fr/en/la) > fallback FR. - #26 Suppression du re-export
picarones.pipeline.spec: ce module re-export orphelin (aucun caller interne ni legacy) a été supprimé directement. Le chemin canonique unique estpicarones.domain.pipeline_spec, re-exporté au niveau__init__des packagespicarones.domainetpicarones.pipeline(API publique standard). - #30 Commit hygiene CER fix : la modification du seuil de régression CER en CI (de 0.10 à 0.20) est documentée dans le CHANGELOG sous « CER regression check threshold rationale » avec justification métier (corpus patrimoniaux ont des CER bruts qui peuvent légitimement varier de 5-15 points selon le tirage de validation).
Prochaines étapes possibles (post-rewrite)
- Confidences typées : créer un
ConfidenceArtifacttypé pour réutiliser proprement les confidences exposées par chaque OCR adapter, sans surchargerBaseOCRAdapter.execute(). - Vues HTML manquantes : porter Pareto, Narrative, Glossary du
legacy
report/versreports_v2/html/une vue à la fois. - CLI complète : porter les commandes manquantes (
history,compare,pipeline,diagnose, etc.) dansinterfaces/cli/. - Suppression effective du legacy : après obtention de la
parité ci-dessus, retirer
picarones/{web,engines,pipelines, report,cli}/(en gardantllm/re-export pour compatibilité historique).