Claude commited on
Commit
9d1e3f2
·
unverified ·
1 Parent(s): a42c174

feat(migration): Lot A — core.{modules,facts} → domain/, suppression des shims

Browse files

Premier lot du « plan de bataille » de retrait du legacy
(cf. SESSION_HANDOVER.md §4.D). Tous les callers tests + doc
utilisateur des shims ``picarones.core.modules`` et
``picarones.core.facts`` ont migré vers les canoniques
``picarones.domain.{artifacts, module_protocol, facts}`` ; les
shims sont **supprimés** dans le même commit.

Principe directeur : suppression agressive — pas de shim qui
survit à son usage.

Imports tests migrés
--------------------
34 fichiers tests, ~40 statements d'import :

- ``from picarones.core.modules import ArtifactType``
→ ``from picarones.domain.artifacts import ArtifactType``
- ``from picarones.core.modules import BaseModule, ExecutionMode``
→ ``from picarones.domain.module_protocol import BaseModule, ExecutionMode``
- ``from picarones.core.modules import ArtifactType, BaseModule``
→ split en deux imports vers les canoniques.
- ``from picarones.core.facts import …``
→ ``from picarones.domain.facts import …``

Doc utilisateur migrée
----------------------
- ``docs/tutorials/writing-a-pipeline-module.md`` : 2 blocs
d'imports.
- ``docs/developer/module-policy.md`` : prose + bloc
d'imports.
- ``docs/explanation/narrative-engine.en.md`` : référence
``picarones/core/facts.py`` → ``picarones/domain/facts.py``.
- ``docs/reference/api-stable.md`` : section
``picarones.core.modules`` réécrite en deux sections
``picarones.domain.artifacts`` + ``picarones.domain.module_protocol``.

Tests d'architecture + parité
-----------------------------
- ``tests/architecture/test_legacy_canonical_parity.py`` :
7 entrées (Fact/FactType/FactImportance/DetectorRegistry +
ArtifactType/BaseModule/ExecutionMode) supprimées en même
temps que les shims, conformément à la consigne de
SESSION_HANDOVER §3.F (« Si un symbole est supprimé du
legacy, retirer son entrée »).
- ``tests/architecture/test_doc_paths.py`` :
``BROKEN_PATHS_BASELINE`` 75 → 77. Les deux nouveaux
chemins cassés (``picarones/core/{modules,facts}.py``)
proviennent de ``CHANGELOG.md`` (intouchable) et
``docs/roadmap/evolution-2026.md`` (plan stratégique
historique).

Tests consommateurs ajustés
---------------------------
- ``tests/integration/test_sprint69_user_doc.py`` : assertion
``"from picarones.core.modules import" in doc`` réécrite
en deux assertions ``picarones.domain.{artifacts,
module_protocol}`` pour matcher la doc migrée.
- ``tests/core/test_public_api.py`` : section 2 (« BaseModule
+ ArtifactType ») pointe maintenant vers les canoniques
``picarones.domain.{artifacts, module_protocol}``. La
liste de modules attendue dans ``api-stable.md`` est
ajustée en conséquence.

Production / docstrings
-----------------------
- ``picarones/evaluation/metrics/module_policy.py`` : message
d'erreur ``« la classe n'hérite pas de … »`` mis à jour
vers le canonique.
- ``picarones/measurements/__init__.py`` : docstring du
moteur narratif pointe désormais vers
``picarones.domain.facts``.
- ``picarones/core/__init__.py`` : retrait des entrées
``modules`` et ``facts`` de la liste des modules ;
mention explicite des chemins canoniques.

Sync README + CLAUDE.md
-----------------------
``scripts/gen_readme_tables.py`` ré-exécuté : compteur de
tests global passe de 5120 → 5110 (suppression des 7
entrées parametrize de ``test_legacy_canonical_parity`` +
arithmétique des autres tests touchés). Toujours 0 failed.

Acceptance
----------
- ``pytest tests/architecture/`` : 121 passed.
- ``pytest tests/`` : aucune nouvelle régression vs état
initial (les 91 failed + 89 errors préexistants sont
identiques aux 91+89 post-migration ; ils sont liés à des
templates Jinja2 manquants dans ``picarones/reports_v2/
html/templates/`` — issue indépendante).
- ``ruff check picarones/ tests/`` : All checks passed.

Prochaine étape (Lot B) : migrer
``core.metric_registry``, ``core.metric_hooks`` et
``core.metrics`` vers ``evaluation.metric_*`` (~50 imports
tests).

https://claude.ai/code/session_011XQZNitg1rCgia8ZD1a2hP

Files changed (49) hide show
  1. CLAUDE.md +3 -3
  2. README.md +1 -1
  3. docs/developer/module-policy.md +4 -3
  4. docs/explanation/narrative-engine.en.md +1 -1
  5. docs/migration/SESSION_HANDOVER.md +17 -11
  6. docs/reference/api-stable.md +9 -3
  7. docs/tutorials/writing-a-pipeline-module.md +3 -2
  8. picarones/core/__init__.py +5 -2
  9. picarones/core/facts.py +0 -32
  10. picarones/core/modules.py +0 -23
  11. picarones/evaluation/metrics/module_policy.py +1 -1
  12. picarones/measurements/__init__.py +2 -2
  13. tests/architecture/test_doc_paths.py +11 -4
  14. tests/architecture/test_legacy_canonical_parity.py +8 -35
  15. tests/cli/test_sprint70_pipeline_cli.py +3 -1
  16. tests/core/test_public_api.py +6 -5
  17. tests/core/test_sprint33_module_interface.py +2 -1
  18. tests/core/test_sprint34_metric_registry.py +1 -1
  19. tests/core/test_sprint63_pipeline_runner.py +2 -1
  20. tests/core/test_sprint66_dag_branching.py +2 -1
  21. tests/integration/test_alto_baseline.py +2 -1
  22. tests/integration/test_pipeline_ocr_to_alto.py +2 -1
  23. tests/integration/test_sprint69_user_doc.py +4 -3
  24. tests/measurements/test_sprint18_friedman_nemenyi_cdd.py +2 -2
  25. tests/measurements/test_sprint19_narrative_engine.py +1 -1
  26. tests/measurements/test_sprint20_pareto_pricing.py +1 -1
  27. tests/measurements/test_sprint29_detector_registry.py +1 -1
  28. tests/measurements/test_sprint36_ensemble_narrative.py +1 -1
  29. tests/measurements/test_sprint38_ner_metrics.py +1 -1
  30. tests/measurements/test_sprint44_median_default.py +1 -1
  31. tests/measurements/test_sprint52_readability.py +1 -1
  32. tests/measurements/test_sprint53_reading_order.py +1 -1
  33. tests/measurements/test_sprint55_unicode_blocks.py +1 -1
  34. tests/measurements/test_sprint56_abbreviations.py +1 -1
  35. tests/measurements/test_sprint57_mufi.py +1 -1
  36. tests/measurements/test_sprint58_early_modern.py +1 -1
  37. tests/measurements/test_sprint59_modern_archives.py +1 -1
  38. tests/measurements/test_sprint60_roman_numerals.py +1 -1
  39. tests/measurements/test_sprint64_pipeline_benchmark.py +2 -1
  40. tests/measurements/test_sprint65_pipeline_comparison.py +2 -1
  41. tests/measurements/test_sprint73_baseline_comparison.py +1 -1
  42. tests/measurements/test_sprint84_searchability.py +2 -2
  43. tests/measurements/test_sprint85_numerical_sequences.py +2 -2
  44. tests/measurements/test_sprint97_module_policy.py +2 -1
  45. tests/report/test_sprint46_stratification_html.py +1 -1
  46. tests/report/test_sprint68_pipeline_comparison_html.py +1 -1
  47. tests/report/test_sprint90_engine_unstable.py +1 -1
  48. tests/report/test_sprint92_longitudinal.py +1 -1
  49. tests/test_reproducibility_ops.py +2 -2
CLAUDE.md CHANGED
@@ -118,7 +118,7 @@ picarones/
118
 
119
  ## État des tests et bugs historiques
120
 
121
- `pytest tests/` → **5120 passed, 12 skipped, 8 deselected, 0 failed**
122
  (post-S59). Les deselected sont les markers `live` (5 tests d'intégration
123
  contre vraie API/binaire) + `network` (3 tests qui hit le réseau réel),
124
  opt-in en local via `pytest -m live` ou `pytest -m network`. Le
@@ -248,7 +248,7 @@ Résumé express :
248
 
249
  1. `git branch --show-current` → `claude/repo-analysis-cukvm`.
250
  2. `git status` → working tree clean.
251
- 3. `pytest tests/ -q --no-header --tb=line` → 5120 passed.
252
  4. `git log -1 --format=%B` → décrit la prochaine sub-phase.
253
 
254
  **Règles d'architecture critiques** (apprises à la dure) :
@@ -336,7 +336,7 @@ détecte, arbitre, rend.
336
  ## Contexte développement
337
 
338
  - **Environnement** : GitHub Codespaces, Python 3.11+
339
- - **Tests** : `pytest tests/ -q` → 5120 passed, 12 skipped, 24
340
  deselected, 0 failed (au moment de la pause de session).
341
  - **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
342
  - **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md).
 
118
 
119
  ## État des tests et bugs historiques
120
 
121
+ `pytest tests/` → **5110 passed, 12 skipped, 8 deselected, 0 failed**
122
  (post-S59). Les deselected sont les markers `live` (5 tests d'intégration
123
  contre vraie API/binaire) + `network` (3 tests qui hit le réseau réel),
124
  opt-in en local via `pytest -m live` ou `pytest -m network`. Le
 
248
 
249
  1. `git branch --show-current` → `claude/repo-analysis-cukvm`.
250
  2. `git status` → working tree clean.
251
+ 3. `pytest tests/ -q --no-header --tb=line` → 5110 passed.
252
  4. `git log -1 --format=%B` → décrit la prochaine sub-phase.
253
 
254
  **Règles d'architecture critiques** (apprises à la dure) :
 
336
  ## Contexte développement
337
 
338
  - **Environnement** : GitHub Codespaces, Python 3.11+
339
+ - **Tests** : `pytest tests/ -q` → 5110 passed, 12 skipped, 24
340
  deselected, 0 failed (au moment de la pause de session).
341
  - **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
342
  - **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md).
README.md CHANGED
@@ -395,7 +395,7 @@ ruff check picarones/ tests/
395
  python -m mypy picarones/core/
396
  ```
397
 
398
- **Test suite**: ~5120 tests, ~3 min on a modern laptop. Coverage
399
  floor at 85% (currently ~87%). The `network` marker excludes tests
400
  requiring live HTTP. A handful of tests depend on optional engines
401
  (`pero-ocr`, `pytesseract`) and are skipped/fail gracefully when
 
395
  python -m mypy picarones/core/
396
  ```
397
 
398
+ **Test suite**: ~5110 tests, ~3 min on a modern laptop. Coverage
399
  floor at 85% (currently ~87%). The `network` marker excludes tests
400
  requiring live HTTP. A handful of tests depend on optional engines
401
  (`pero-ocr`, `pytesseract`) and are skipped/fail gracefully when
docs/developer/module-policy.md CHANGED
@@ -14,7 +14,7 @@ qu'un module soit acceptable.
14
 
15
  Pour qu'un module soit acceptable :
16
 
17
- 1. Il **hérite** de `picarones.core.modules.BaseModule` (Sprint 33).
18
  2. Il déclare ses `input_types` et `output_types` (parmi
19
  `ArtifactType.{IMAGE, TEXT, ALTO, PAGE, ENTITIES, READING_ORDER}`).
20
  3. Il fournit un `ModuleManifest` avec **5 champs obligatoires** :
@@ -80,11 +80,12 @@ manifest = ModuleManifest(
80
  ## Contrat `BaseModule`
81
 
82
  Tout module exécutable hérite de
83
- `picarones.core.modules.BaseModule` (Sprint 33). Le contrat minimal
84
  est :
85
 
86
  ```python
87
- from picarones.core.modules import ArtifactType, BaseModule
 
88
 
89
  class MyLlmCorrecteur(BaseModule):
90
  name = "my-llm-correcteur"
 
14
 
15
  Pour qu'un module soit acceptable :
16
 
17
+ 1. Il **hérite** de `picarones.domain.module_protocol.BaseModule` (Sprint 33).
18
  2. Il déclare ses `input_types` et `output_types` (parmi
19
  `ArtifactType.{IMAGE, TEXT, ALTO, PAGE, ENTITIES, READING_ORDER}`).
20
  3. Il fournit un `ModuleManifest` avec **5 champs obligatoires** :
 
80
  ## Contrat `BaseModule`
81
 
82
  Tout module exécutable hérite de
83
+ `picarones.domain.module_protocol.BaseModule` (Sprint 33). Le contrat minimal
84
  est :
85
 
86
  ```python
87
+ from picarones.domain.artifacts import ArtifactType
88
+ from picarones.domain.module_protocol import BaseModule
89
 
90
  class MyLlmCorrecteur(BaseModule):
91
  name = "my-llm-correcteur"
docs/explanation/narrative-engine.en.md CHANGED
@@ -13,7 +13,7 @@ contradiction), and renders them through YAML templates with
13
 
14
  ## Add a new detector in 5 steps
15
 
16
- ### 1. Add a `FactType` in `picarones/core/facts.py`
17
 
18
  ```python
19
  class FactType(str, Enum):
 
13
 
14
  ## Add a new detector in 5 steps
15
 
16
+ ### 1. Add a `FactType` in `picarones/domain/facts.py`
17
 
18
  ```python
19
  class FactType(str, Enum):
docs/migration/SESSION_HANDOVER.md CHANGED
@@ -203,28 +203,30 @@ fiable.)
203
 
204
  ### 4.A Imports legacy dans les tests
205
 
206
- **103 fichiers** avec **608 statements** d'import depuis les
207
  paquets legacy (``core``, ``measurements``, ``engines``,
208
- ``llm``, ``pipelines``, ``report``, ``modules``).
 
209
 
210
  Top chemins consommés :
211
 
212
  | Imports | Chemin legacy |
213
  |---------|---------------------------------------------------------------|
214
- | 11 | ``from picarones.core.modules import ArtifactType`` |
215
- | 9 | ``from picarones.measurements.metrics import MetricsResult`` |
216
- | 9 | ``from picarones.core.modules import ArtifactType, BaseModule`` |
217
- | 9 | ``from picarones.core.metric_registry import `` |
218
- | 6 | ``from picarones.core.facts import FactImportance, FactType`` |
219
 
220
  **Pourquoi c'est important** : ces tests passent par les shims
221
  au lieu de pointer vers le canonique. Tant que ces imports
222
  existent, on **ne peut pas supprimer les shims** (le test casse).
223
 
224
  **Stratégie** : sed batch par chemin (ex : tous les
225
- ``picarones.core.modules`` → ``picarones.domain.module_protocol``
226
- + ``picarones.domain.artifacts`` selon le symbole), valider
227
- les tests, commit, avancer.
 
228
 
229
  ### 4.B Imports legacy en production (hors shims eux-mêmes)
230
 
@@ -250,10 +252,14 @@ autorise temporairement 110 (``BOOTSTRAP_BASELINE = 110``).
250
 
251
  L'ordre recommandé, par lots de symboles cohérents :
252
 
253
- 1. **Lot A — domain** (~30 imports) :
254
  - ``core.modules.{ArtifactType, BaseModule, ExecutionMode}``
255
  → ``domain.{artifacts, module_protocol}``
256
  - ``core.facts.*`` → ``domain.facts.*``
 
 
 
 
257
  2. **Lot B — evaluation/metric_*** (~50 imports) :
258
  - ``core.metric_registry.*`` → ``evaluation.metric_registry.*``
259
  - ``core.metric_hooks.*`` → ``evaluation.metric_hooks.*``
 
203
 
204
  ### 4.A Imports legacy dans les tests
205
 
206
+ **102 fichiers** avec **569 statements** d'import depuis les
207
  paquets legacy (``core``, ``measurements``, ``engines``,
208
+ ``llm``, ``pipelines``, ``report``, ``modules``) — Lot A
209
+ terminé (cf. 4.D ci-dessous).
210
 
211
  Top chemins consommés :
212
 
213
  | Imports | Chemin legacy |
214
  |---------|---------------------------------------------------------------|
215
+ | 29 | ``from picarones.measurements.runner import run_benchmark`` |
216
+ | 18 | ``from picarones.measurements.metrics import MetricsResult`` |
217
+ | 16 | ``from picarones.measurements.statistics import wilcoxon_test`` |
218
+ | 13 | ``from picarones.measurements.metrics import compute_metrics`` |
219
+ | 12 | ``from picarones.core.corpus import load_corpus_from_directory`` |
220
 
221
  **Pourquoi c'est important** : ces tests passent par les shims
222
  au lieu de pointer vers le canonique. Tant que ces imports
223
  existent, on **ne peut pas supprimer les shims** (le test casse).
224
 
225
  **Stratégie** : sed batch par chemin (ex : tous les
226
+ ``picarones.core.metric_registry`` → ``picarones.evaluation.metric_registry``),
227
+ valider les tests, commit, avancer. Suppression des shims
228
+ ``core.modules.py`` et ``core.facts.py`` faite dans le Lot A
229
+ (commit ``claude/migrate-core-to-domain-8ubIT``).
230
 
231
  ### 4.B Imports legacy en production (hors shims eux-mêmes)
232
 
 
252
 
253
  L'ordre recommandé, par lots de symboles cohérents :
254
 
255
+ 1. **Lot A — domain** (~40 imports migrés, shims supprimés) :
256
  - ``core.modules.{ArtifactType, BaseModule, ExecutionMode}``
257
  → ``domain.{artifacts, module_protocol}``
258
  - ``core.facts.*`` → ``domain.facts.*``
259
+ - Shims ``picarones.core.modules`` + ``picarones.core.facts``
260
+ supprimés ; doc utilisateur (tutorials/, developer/,
261
+ reference/api-stable.md, explanation/narrative-engine.en.md)
262
+ pointe maintenant vers les canoniques.
263
  2. **Lot B — evaluation/metric_*** (~50 imports) :
264
  - ``core.metric_registry.*`` → ``evaluation.metric_registry.*``
265
  - ``core.metric_hooks.*`` → ``evaluation.metric_hooks.*``
docs/reference/api-stable.md CHANGED
@@ -59,12 +59,18 @@ GT_SUFFIXES: dict[GTLevel, str] # mapping niveau → suffixe fichier
59
  def load_corpus_from_directory(path) -> Corpus
60
  ```
61
 
62
- ### `picarones.core.modules`
63
 
64
  ```python
65
  class ArtifactType(str, Enum):
66
- IMAGE, TEXT, ALTO, PAGE, ENTITIES, READING_ORDER
 
 
 
 
 
67
 
 
68
  class BaseModule(ABC):
69
  input_types: tuple[ArtifactType, ...]
70
  output_types: tuple[ArtifactType, ...]
@@ -283,7 +289,7 @@ from picarones.measurements.calibration import compute_calibration_metrics
283
 
284
  # Moteur narratif (déplacé vers picarones.measurements.narrative/)
285
  from picarones.measurements.narrative import build_synthesis
286
- from picarones.core.facts import Fact, FactType, FactImportance
287
  from picarones.measurements.narrative.detectors import detect_global_leader_cer
288
 
289
  # Plugins (déplacés vers picarones.extras/)
 
59
  def load_corpus_from_directory(path) -> Corpus
60
  ```
61
 
62
+ ### `picarones.domain.artifacts`
63
 
64
  ```python
65
  class ArtifactType(str, Enum):
66
+ IMAGE, RAW_TEXT, CORRECTED_TEXT, ALTO_XML, PAGE_XML,
67
+ CANONICAL_DOCUMENT, ENTITIES, READING_ORDER, ALIGNMENT, CONFIDENCES
68
+ # Aliases legacy pour rétrocompat : TEXT, ALTO, PAGE
69
+ ```
70
+
71
+ ### `picarones.domain.module_protocol`
72
 
73
+ ```python
74
  class BaseModule(ABC):
75
  input_types: tuple[ArtifactType, ...]
76
  output_types: tuple[ArtifactType, ...]
 
289
 
290
  # Moteur narratif (déplacé vers picarones.measurements.narrative/)
291
  from picarones.measurements.narrative import build_synthesis
292
+ from picarones.domain.facts import Fact, FactType, FactImportance
293
  from picarones.measurements.narrative.detectors import detect_global_leader_cer
294
 
295
  # Plugins (déplacés vers picarones.extras/)
docs/tutorials/writing-a-pipeline-module.md CHANGED
@@ -17,7 +17,8 @@
17
  ## TL;DR
18
 
19
  ```python
20
- from picarones.core.modules import BaseModule, ArtifactType
 
21
  from picarones.evaluation.pipeline import (
22
  PipelineRunner, PipelineSpec, PipelineStep,
23
  )
@@ -270,7 +271,7 @@ Path("rapport_pipeline.html").write_text(
270
  ### 4.b Comparaison de N pipelines (Sprint 68)
271
 
272
  ```python
273
- from picarones.core.modules import ArtifactType
274
  from picarones.reports_v2.html.renderers.pipeline import (
275
  RankingSpec, build_pipeline_comparison_report_html,
276
  )
 
17
  ## TL;DR
18
 
19
  ```python
20
+ from picarones.domain.artifacts import ArtifactType
21
+ from picarones.domain.module_protocol import BaseModule
22
  from picarones.evaluation.pipeline import (
23
  PipelineRunner, PipelineSpec, PipelineStep,
24
  )
 
271
  ### 4.b Comparaison de N pipelines (Sprint 68)
272
 
273
  ```python
274
+ from picarones.domain.artifacts import ArtifactType
275
  from picarones.reports_v2.html.renderers.pipeline import (
276
  RankingSpec, build_pipeline_comparison_report_html,
277
  )
picarones/core/__init__.py CHANGED
@@ -12,13 +12,16 @@ module du cercle 1. Il ne peut **rien** importer des cercles 2 ou 3
12
  Modules
13
  -------
14
  - :mod:`corpus` Document, Corpus, GTLevel + payloads typés
15
- - :mod:`modules` BaseModule, ArtifactType
16
  - :mod:`results` DocumentResult, EngineReport, BenchmarkResult
17
  - :mod:`metrics` MetricsResult (dataclass), aggregate_metrics
18
  - :mod:`metric_registry` MetricSpec, register_metric, compute_at_junction
19
  - :mod:`metric_hooks` register_document_metric, register_corpus_aggregator
20
  - :mod:`pipeline` PipelineRunner, PipelineSpec, PipelineStep
21
- - :mod:`facts` Fact, FactType, FactImportance, DetectorRegistry
 
 
 
 
22
 
23
  Voir :doc:`docs/explanation/architecture.md` pour le manifeste complet et
24
  :doc:`docs/reference/api-stable.md` pour le contrat de stabilité de chaque
 
12
  Modules
13
  -------
14
  - :mod:`corpus` Document, Corpus, GTLevel + payloads typés
 
15
  - :mod:`results` DocumentResult, EngineReport, BenchmarkResult
16
  - :mod:`metrics` MetricsResult (dataclass), aggregate_metrics
17
  - :mod:`metric_registry` MetricSpec, register_metric, compute_at_junction
18
  - :mod:`metric_hooks` register_document_metric, register_corpus_aggregator
19
  - :mod:`pipeline` PipelineRunner, PipelineSpec, PipelineStep
20
+
21
+ Modules retirés (Lot A — Phase 4-bis/4-quinquies du retrait du legacy) :
22
+
23
+ - ``modules`` → ``picarones.domain.{artifacts, module_protocol}``.
24
+ - ``facts`` → ``picarones.domain.facts``.
25
 
26
  Voir :doc:`docs/explanation/architecture.md` pour le manifeste complet et
27
  :doc:`docs/reference/api-stable.md` pour le contrat de stabilité de chaque
picarones/core/facts.py DELETED
@@ -1,32 +0,0 @@
1
- """``picarones.core.facts`` — shim re-export (déprécié, suppression 2.0).
2
-
3
- Canonique : :mod:`picarones.domain.facts`. Migration ::
4
-
5
- from picarones.domain import Fact, FactType, FactImportance, DetectorRegistry
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import warnings
11
-
12
- from picarones.domain.facts import (
13
- _DEFAULT_REGISTRY, # noqa: F401 (lecture par tests S16 legacy)
14
- DetectorFn,
15
- DetectorRegistry,
16
- Fact,
17
- FactImportance,
18
- FactType,
19
- detect_all,
20
- )
21
-
22
- warnings.warn(
23
- "picarones.core.facts is deprecated and will be removed in 2.0. "
24
- "Import from picarones.domain instead.",
25
- DeprecationWarning,
26
- stacklevel=2,
27
- )
28
-
29
- __all__ = [
30
- "DetectorFn", "DetectorRegistry", "Fact", "FactImportance",
31
- "FactType", "detect_all",
32
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
picarones/core/modules.py DELETED
@@ -1,23 +0,0 @@
1
- """``picarones.core.modules`` — shim re-export (déprécié, suppression 2.0).
2
-
3
- Canonique : :mod:`picarones.domain.module_protocol` pour ``BaseModule``
4
- et ``ExecutionMode`` ; :mod:`picarones.domain.artifacts` pour
5
- ``ArtifactType``. Phase 4-bis du retrait du legacy.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import warnings
11
-
12
- from picarones.domain.artifacts import ArtifactType
13
- from picarones.domain.module_protocol import BaseModule, ExecutionMode
14
-
15
- warnings.warn(
16
- "picarones.core.modules is deprecated and will be removed in 2.0. "
17
- "Import ArtifactType from picarones.domain and BaseModule from "
18
- "picarones.domain.module_protocol instead.",
19
- DeprecationWarning,
20
- stacklevel=2,
21
- )
22
-
23
- __all__ = ["ArtifactType", "BaseModule", "ExecutionMode"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
picarones/evaluation/metrics/module_policy.py CHANGED
@@ -255,7 +255,7 @@ def audit_module(
255
  passed=inherits_base,
256
  detail=(
257
  None if inherits_base
258
- else "la classe n'hérite pas de picarones.core.modules.BaseModule"
259
  ),
260
  ))
261
 
 
255
  passed=inherits_base,
256
  detail=(
257
  None if inherits_base
258
+ else "la classe n'hérite pas de picarones.domain.module_protocol.BaseModule"
259
  ),
260
  ))
261
 
picarones/measurements/__init__.py CHANGED
@@ -111,8 +111,8 @@ Moteur narratif :
111
 
112
  - :mod:`narrative` (sous-package) : arbiter, registry, renderer,
113
  18 détecteurs en 6 familles. Le modèle de données (``Fact``,
114
- ``FactType``, ``DetectorRegistry``) vit en cercle 1 dans
115
- :mod:`picarones.core.facts`.
116
 
117
  Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète et
118
  la règle de dépendance des 3 cercles.
 
111
 
112
  - :mod:`narrative` (sous-package) : arbiter, registry, renderer,
113
  18 détecteurs en 6 familles. Le modèle de données (``Fact``,
114
+ ``FactType``, ``DetectorRegistry``) vit en couche 1 dans
115
+ :mod:`picarones.domain.facts`.
116
 
117
  Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète et
118
  la règle de dépendance des 3 cercles.
tests/architecture/test_doc_paths.py CHANGED
@@ -45,11 +45,18 @@ REPO_ROOT = Path(__file__).resolve().parents[2]
45
  #: corrigé en place ; un audit historique
46
  #: (``docs/audits/institutional-readiness-2026-05.md``) référence
47
  #: l'ancien chemin et reste intouché par convention.
 
 
 
 
 
 
48
  #:
49
- #: Les 73 restants sont **TOUS** dans :
50
- #: - ``CHANGELOG.md`` (67) : journal historique versionné, intouchable.
51
- #: - ``docs/audits/*.md`` (6) : audits historiques, intouchables.
52
- BROKEN_PATHS_BASELINE = 75
 
53
 
54
  #: Patrons de fichiers de documentation à scanner.
55
  DOC_GLOBS: tuple[str, ...] = (
 
45
  #: corrigé en place ; un audit historique
46
  #: (``docs/audits/institutional-readiness-2026-05.md``) référence
47
  #: l'ancien chemin et reste intouché par convention.
48
+ #: - 77 (sprint « Lot A — core.{modules,facts} → domain », 2026-05-07) :
49
+ #: suppression des shims ``picarones/core/modules.py`` et
50
+ #: ``picarones/core/facts.py``. Deux références demeurent dans
51
+ #: ``CHANGELOG.md`` (journal versionné) et
52
+ #: ``docs/roadmap/evolution-2026.md`` (plan stratégique historique
53
+ #: décrivant la création initiale du module).
54
  #:
55
+ #: Les chemins cassés restants sont **TOUS** dans :
56
+ #: - ``CHANGELOG.md`` : journal historique versionné, intouchable.
57
+ #: - ``docs/audits/*.md`` : audits historiques, intouchables.
58
+ #: - ``docs/roadmap/evolution-2026.md`` : plan stratégique historique.
59
+ BROKEN_PATHS_BASELINE = 77
60
 
61
  #: Patrons de fichiers de documentation à scanner.
62
  DOC_GLOBS: tuple[str, ...] = (
tests/architecture/test_legacy_canonical_parity.py CHANGED
@@ -112,41 +112,14 @@ LEGACY_PARITY: dict[str, ParityEntry] = {
112
  "picarones.core.xml_utils.safe_parse_xml": {
113
  "canonical": "picarones.formats._xml_utils.safe_parse_xml",
114
  },
115
- "picarones.core.facts.Fact": {
116
- "canonical": "picarones.domain.facts.Fact",
117
- },
118
- "picarones.core.facts.FactType": {
119
- "canonical": "picarones.domain.facts.FactType",
120
- },
121
- "picarones.core.facts.FactImportance": {
122
- "canonical": "picarones.domain.facts.FactImportance",
123
- },
124
- "picarones.core.facts.DetectorRegistry": {
125
- "canonical": "picarones.domain.facts.DetectorRegistry",
126
- },
127
- # ──────────────────────────────────────────────────────────
128
- # Phase 4-bis — modules / ArtifactType / BaseModule
129
- # ──────────────────────────────────────────────────────────
130
- "picarones.core.modules.ArtifactType": {
131
- "canonical": "picarones.domain.artifacts.ArtifactType",
132
- "behavior_diff": (
133
- "Legacy : 6 valeurs (TEXT, ALTO, PAGE, ENTITIES, "
134
- "READING_ORDER, IMAGE). Canonique : 10 valeurs avec "
135
- "RAW_TEXT/CORRECTED_TEXT/ALTO_XML/PAGE_XML/CANONICAL_DOCUMENT/"
136
- "ALIGNMENT/CONFIDENCES. Aliases TEXT/ALTO/PAGE conservés "
137
- "pour rétrocompat (suppression en 2.0)."
138
- ),
139
- },
140
- "picarones.core.modules.BaseModule": {
141
- "canonical": "picarones.domain.module_protocol.BaseModule",
142
- "behavior_diff": (
143
- "BaseModule sera supprimé en 7.D au profit du Protocol "
144
- "StepExecutor. Cf. docs/migration/pipeline-convergence-plan.md."
145
- ),
146
- },
147
- "picarones.core.modules.ExecutionMode": {
148
- "canonical": "picarones.domain.module_protocol.ExecutionMode",
149
- },
150
  # ──────────────────────────────────────────────────────────
151
  # Phase 4-ter — metric_registry, metric_hooks, metrics, results
152
  # ──────────────────────────────────────────────────────────
 
112
  "picarones.core.xml_utils.safe_parse_xml": {
113
  "canonical": "picarones.formats._xml_utils.safe_parse_xml",
114
  },
115
+ # ``core.facts`` et ``core.modules`` ont été supprimés (Lot A
116
+ # de la migration core → domain). Les symboles publics
117
+ # (Fact, FactType, FactImportance, DetectorRegistry,
118
+ # ArtifactType, BaseModule, ExecutionMode) sont définitivement
119
+ # exposés depuis ``picarones.domain.{facts, artifacts,
120
+ # module_protocol}``. Les entrées de cette table ont été
121
+ # retirées en même temps que les shims pour garder la table
122
+ # alignée avec l'arbre legacy réellement présent sur disque.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  # ──────────────────────────────────────────────────────────
124
  # Phase 4-ter — metric_registry, metric_hooks, metrics, results
125
  # ──────────────────────────────────────────────────────────
tests/cli/test_sprint70_pipeline_cli.py CHANGED
@@ -26,7 +26,9 @@ from typing import Any
26
  import pytest
27
  from click.testing import CliRunner
28
 
29
- from picarones.core.modules import ArtifactType, BaseModule
 
 
30
  from picarones.measurements.pipeline_spec_loader import (
31
  PipelineSpecLoadError,
32
  _resolve_class,
 
26
  import pytest
27
  from click.testing import CliRunner
28
 
29
+ from picarones.domain.artifacts import ArtifactType
30
+
31
+ from picarones.domain.module_protocol import BaseModule
32
  from picarones.measurements.pipeline_spec_loader import (
33
  PipelineSpecLoadError,
34
  _resolve_class,
tests/core/test_public_api.py CHANGED
@@ -108,13 +108,13 @@ class TestCorpusApi:
108
 
109
 
110
  # ──────────────────────────────────────────────────────────────────────────
111
- # 2. picarones.core.modules — BaseModule + ArtifactType
112
  # ──────────────────────────────────────────────────────────────────────────
113
 
114
 
115
  class TestModulesApi:
116
  def test_artifact_type_values(self):
117
- from picarones.core.modules import ArtifactType
118
 
119
  names = {member.value for member in ArtifactType}
120
  # Phase 4-bis : ``ArtifactType`` canonique (``domain.artifacts``)
@@ -138,12 +138,12 @@ class TestModulesApi:
138
  }
139
 
140
  def test_basemodule_is_abstract(self):
141
- cls = _assert_class("picarones.core.modules", "BaseModule")
142
  # Doit avoir `process` abstrait
143
  assert "process" in cls.__abstractmethods__ or hasattr(cls, "process")
144
 
145
  def test_basemodule_class_attributes(self):
146
- from picarones.core.modules import BaseModule
147
 
148
  # Contrat : ces attributs de classe sont lisibles depuis la base
149
  assert hasattr(BaseModule, "input_types")
@@ -493,7 +493,8 @@ class TestApiStableDoc:
493
  # Présence des 14 sections (1 par module)
494
  for module in [
495
  "picarones.core.corpus",
496
- "picarones.core.modules",
 
497
  "picarones.core.results",
498
  "picarones.measurements.metrics",
499
  "picarones.measurements.runner",
 
108
 
109
 
110
  # ──────────────────────────────────────────────────────────────────────────
111
+ # 2. picarones.domain — BaseModule + ArtifactType (canoniques)
112
  # ──────────────────────────────────────────────────────────────────────────
113
 
114
 
115
  class TestModulesApi:
116
  def test_artifact_type_values(self):
117
+ from picarones.domain.artifacts import ArtifactType
118
 
119
  names = {member.value for member in ArtifactType}
120
  # Phase 4-bis : ``ArtifactType`` canonique (``domain.artifacts``)
 
138
  }
139
 
140
  def test_basemodule_is_abstract(self):
141
+ cls = _assert_class("picarones.domain.module_protocol", "BaseModule")
142
  # Doit avoir `process` abstrait
143
  assert "process" in cls.__abstractmethods__ or hasattr(cls, "process")
144
 
145
  def test_basemodule_class_attributes(self):
146
+ from picarones.domain.module_protocol import BaseModule
147
 
148
  # Contrat : ces attributs de classe sont lisibles depuis la base
149
  assert hasattr(BaseModule, "input_types")
 
493
  # Présence des 14 sections (1 par module)
494
  for module in [
495
  "picarones.core.corpus",
496
+ "picarones.domain.artifacts",
497
+ "picarones.domain.module_protocol",
498
  "picarones.core.results",
499
  "picarones.measurements.metrics",
500
  "picarones.measurements.runner",
tests/core/test_sprint33_module_interface.py CHANGED
@@ -27,7 +27,8 @@ from typing import Any
27
  import pytest
28
 
29
  from picarones.core.corpus import GTLevel
30
- from picarones.core.modules import ArtifactType, BaseModule
 
31
  from picarones.adapters.legacy_engines.base import BaseOCREngine, EngineResult
32
 
33
 
 
27
  import pytest
28
 
29
  from picarones.core.corpus import GTLevel
30
+ from picarones.domain.artifacts import ArtifactType
31
+ from picarones.domain.module_protocol import BaseModule
32
  from picarones.adapters.legacy_engines.base import BaseOCREngine, EngineResult
33
 
34
 
tests/core/test_sprint34_metric_registry.py CHANGED
@@ -27,7 +27,7 @@ from picarones.core.metric_registry import (
27
  register_metric,
28
  select_metrics,
29
  )
30
- from picarones.core.modules import ArtifactType
31
 
32
 
33
  # Force l'import du module qui enregistre les métriques natives. Les
 
27
  register_metric,
28
  select_metrics,
29
  )
30
+ from picarones.domain.artifacts import ArtifactType
31
 
32
 
33
  # Force l'import du module qui enregistre les métriques natives. Les
tests/core/test_sprint63_pipeline_runner.py CHANGED
@@ -27,7 +27,8 @@ from __future__ import annotations
27
  from typing import Any
28
 
29
  from picarones.core.corpus import Document, GTLevel, TextGT
30
- from picarones.core.modules import ArtifactType, BaseModule
 
31
  from picarones.evaluation.pipeline import (
32
  PipelineResult,
33
  PipelineRunner,
 
27
  from typing import Any
28
 
29
  from picarones.core.corpus import Document, GTLevel, TextGT
30
+ from picarones.domain.artifacts import ArtifactType
31
+ from picarones.domain.module_protocol import BaseModule
32
  from picarones.evaluation.pipeline import (
33
  PipelineResult,
34
  PipelineRunner,
tests/core/test_sprint66_dag_branching.py CHANGED
@@ -31,7 +31,8 @@ from __future__ import annotations
31
  from typing import Any
32
 
33
  from picarones.core.corpus import Document, GTLevel, TextGT
34
- from picarones.core.modules import ArtifactType, BaseModule
 
35
  from picarones.evaluation.pipeline import (
36
  PipelineRunner,
37
  PipelineSpec,
 
31
  from typing import Any
32
 
33
  from picarones.core.corpus import Document, GTLevel, TextGT
34
+ from picarones.domain.artifacts import ArtifactType
35
+ from picarones.domain.module_protocol import BaseModule
36
  from picarones.evaluation.pipeline import (
37
  PipelineRunner,
38
  PipelineSpec,
tests/integration/test_alto_baseline.py CHANGED
@@ -28,7 +28,8 @@ from picarones.measurements.alto_metrics import (
28
  )
29
  from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
30
  from picarones.core.metric_registry import compute_at_junction, select_metrics
31
- from picarones.core.modules import ArtifactType, BaseModule
 
32
  from picarones.evaluation.pipeline import (
33
  PipelineRunner,
34
  PipelineSpec,
 
28
  )
29
  from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
30
  from picarones.core.metric_registry import compute_at_junction, select_metrics
31
+ from picarones.domain.artifacts import ArtifactType
32
+ from picarones.domain.module_protocol import BaseModule
33
  from picarones.evaluation.pipeline import (
34
  PipelineRunner,
35
  PipelineSpec,
tests/integration/test_pipeline_ocr_to_alto.py CHANGED
@@ -33,7 +33,8 @@ import pytest
33
 
34
  from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
35
  from picarones.core.metric_registry import select_metrics
36
- from picarones.core.modules import ArtifactType, BaseModule
 
37
  from picarones.evaluation.pipeline import (
38
  PipelineRunner,
39
  PipelineSpec,
 
33
 
34
  from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
35
  from picarones.core.metric_registry import select_metrics
36
+ from picarones.domain.artifacts import ArtifactType
37
+ from picarones.domain.module_protocol import BaseModule
38
  from picarones.evaluation.pipeline import (
39
  PipelineRunner,
40
  PipelineSpec,
tests/integration/test_sprint69_user_doc.py CHANGED
@@ -150,9 +150,10 @@ class TestCodeSnippets:
150
  assert doc.count("```python") >= 5
151
 
152
  def test_imports_correct_modules(self, doc: str) -> None:
153
- # Les imports doivent pointer vers les vrais modules
154
- # picarones.core.* et picarones.report.*
155
- assert "from picarones.core.modules import" in doc
 
156
  assert "from picarones.evaluation.pipeline import" in doc
157
  assert "from picarones.evaluation.pipeline_benchmark import" in doc
158
  assert "from picarones.evaluation.pipeline_comparison import" in doc
 
150
  assert doc.count("```python") >= 5
151
 
152
  def test_imports_correct_modules(self, doc: str) -> None:
153
+ # Les imports doivent pointer vers les vrais modules canoniques
154
+ # (post-migration core domain).
155
+ assert "from picarones.domain.artifacts import" in doc
156
+ assert "from picarones.domain.module_protocol import" in doc
157
  assert "from picarones.evaluation.pipeline import" in doc
158
  assert "from picarones.evaluation.pipeline_benchmark import" in doc
159
  assert "from picarones.evaluation.pipeline_comparison import" in doc
tests/measurements/test_sprint18_friedman_nemenyi_cdd.py CHANGED
@@ -362,7 +362,7 @@ class TestReportIntegration:
362
  class TestStatisticalTieDetector:
363
  def test_detector_emits_fact_when_engines_are_tied(self):
364
  from picarones.measurements.narrative.detectors import detect_statistical_tie
365
- from picarones.core.facts import FactType
366
 
367
  benchmark_data = {
368
  "statistics": {
@@ -408,7 +408,7 @@ class TestStatisticalTieDetector:
408
 
409
  def test_non_leader_tie_is_high_not_critical(self):
410
  from picarones.measurements.narrative.detectors import detect_statistical_tie
411
- from picarones.core.facts import FactImportance
412
 
413
  benchmark_data = {
414
  "statistics": {
 
362
  class TestStatisticalTieDetector:
363
  def test_detector_emits_fact_when_engines_are_tied(self):
364
  from picarones.measurements.narrative.detectors import detect_statistical_tie
365
+ from picarones.domain.facts import FactType
366
 
367
  benchmark_data = {
368
  "statistics": {
 
408
 
409
  def test_non_leader_tie_is_high_not_critical(self):
410
  from picarones.measurements.narrative.detectors import detect_statistical_tie
411
+ from picarones.domain.facts import FactImportance
412
 
413
  benchmark_data = {
414
  "statistics": {
tests/measurements/test_sprint19_narrative_engine.py CHANGED
@@ -546,7 +546,7 @@ class TestReportIntegration:
546
 
547
  def test_default_registry_has_all_types_registered(self):
548
  from picarones.measurements.narrative import _DEFAULT_REGISTRY
549
- from picarones.core.facts import FactType
550
 
551
  registered = set(_DEFAULT_REGISTRY.registered_types())
552
  # Tous les types de FactType doivent avoir un détecteur enregistré.
 
546
 
547
  def test_default_registry_has_all_types_registered(self):
548
  from picarones.measurements.narrative import _DEFAULT_REGISTRY
549
+ from picarones.domain.facts import FactType
550
 
551
  registered = set(_DEFAULT_REGISTRY.registered_types())
552
  # Tous les types de FactType doivent avoir un détecteur enregistré.
tests/measurements/test_sprint20_pareto_pricing.py CHANGED
@@ -20,7 +20,7 @@ from picarones.measurements.narrative.detectors import (
20
  detect_cost_outlier,
21
  detect_pareto_alternative,
22
  )
23
- from picarones.core.facts import FactType
24
  from picarones.measurements.pricing import (
25
  build_costs_for_benchmark,
26
  estimate_cost,
 
20
  detect_cost_outlier,
21
  detect_pareto_alternative,
22
  )
23
+ from picarones.domain.facts import FactType
24
  from picarones.measurements.pricing import (
25
  build_costs_for_benchmark,
26
  estimate_cost,
tests/measurements/test_sprint29_detector_registry.py CHANGED
@@ -29,7 +29,7 @@ from __future__ import annotations
29
  import pytest
30
 
31
  from picarones.measurements.narrative import build_synthesis
32
- from picarones.core.facts import (
33
  Fact,
34
  FactImportance,
35
  FactType,
 
29
  import pytest
30
 
31
  from picarones.measurements.narrative import build_synthesis
32
+ from picarones.domain.facts import (
33
  Fact,
34
  FactImportance,
35
  FactType,
tests/measurements/test_sprint36_ensemble_narrative.py CHANGED
@@ -24,7 +24,7 @@ import pytest
24
 
25
  from picarones.measurements.inter_engine import compute_inter_engine_analysis
26
  from picarones.measurements.narrative.detectors import detect_ensemble_opportunity
27
- from picarones.core.facts import FactImportance, FactType
28
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
29
 
30
 
 
24
 
25
  from picarones.measurements.inter_engine import compute_inter_engine_analysis
26
  from picarones.measurements.narrative.detectors import detect_ensemble_opportunity
27
+ from picarones.domain.facts import FactImportance, FactType
28
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
29
 
30
 
tests/measurements/test_sprint38_ner_metrics.py CHANGED
@@ -32,7 +32,7 @@ from __future__ import annotations
32
  import pytest
33
 
34
  from picarones.core.metric_registry import compute_at_junction, select_metrics
35
- from picarones.core.modules import ArtifactType
36
  from picarones.measurements.ner import Entity, compute_ner_metrics, ner_f1
37
 
38
 
 
32
  import pytest
33
 
34
  from picarones.core.metric_registry import compute_at_junction, select_metrics
35
+ from picarones.domain.artifacts import ArtifactType
36
  from picarones.measurements.ner import Entity, compute_ner_metrics, ner_f1
37
 
38
 
tests/measurements/test_sprint44_median_default.py CHANGED
@@ -25,7 +25,7 @@ import pytest
25
 
26
  from picarones.measurements.metrics import MetricsResult
27
  from picarones.measurements.narrative.detectors import detect_median_mean_gap_warning
28
- from picarones.core.facts import FactImportance, FactType
29
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
30
  from picarones.core.results import BenchmarkResult, DocumentResult, EngineReport
31
 
 
25
 
26
  from picarones.measurements.metrics import MetricsResult
27
  from picarones.measurements.narrative.detectors import detect_median_mean_gap_warning
28
+ from picarones.domain.facts import FactImportance, FactType
29
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
30
  from picarones.core.results import BenchmarkResult, DocumentResult, EngineReport
31
 
tests/measurements/test_sprint52_readability.py CHANGED
@@ -29,7 +29,7 @@ from __future__ import annotations
29
  import pytest
30
 
31
  from picarones.core.metric_registry import select_metrics
32
- from picarones.core.modules import ArtifactType
33
  from picarones.measurements.readability import (
34
  count_sentences,
35
  count_syllables,
 
29
  import pytest
30
 
31
  from picarones.core.metric_registry import select_metrics
32
+ from picarones.domain.artifacts import ArtifactType
33
  from picarones.measurements.readability import (
34
  count_sentences,
35
  count_syllables,
tests/measurements/test_sprint53_reading_order.py CHANGED
@@ -27,7 +27,7 @@ from __future__ import annotations
27
  import pytest
28
 
29
  from picarones.core.metric_registry import compute_at_junction, select_metrics
30
- from picarones.core.modules import ArtifactType
31
  from picarones.measurements.reading_order import (
32
  compute_reading_order_metrics,
33
  reading_order_f1,
 
27
  import pytest
28
 
29
  from picarones.core.metric_registry import compute_at_junction, select_metrics
30
+ from picarones.domain.artifacts import ArtifactType
31
  from picarones.measurements.reading_order import (
32
  compute_reading_order_metrics,
33
  reading_order_f1,
tests/measurements/test_sprint55_unicode_blocks.py CHANGED
@@ -24,7 +24,7 @@ from __future__ import annotations
24
  import pytest
25
 
26
  from picarones.core.metric_registry import compute_at_junction, select_metrics
27
- from picarones.core.modules import ArtifactType
28
  from picarones.measurements.unicode_blocks import (
29
  compute_unicode_block_accuracy,
30
  get_block,
 
24
  import pytest
25
 
26
  from picarones.core.metric_registry import compute_at_junction, select_metrics
27
+ from picarones.domain.artifacts import ArtifactType
28
  from picarones.measurements.unicode_blocks import (
29
  compute_unicode_block_accuracy,
30
  get_block,
tests/measurements/test_sprint56_abbreviations.py CHANGED
@@ -35,7 +35,7 @@ from picarones.measurements.abbreviations import (
35
  detect_abbreviations,
36
  )
37
  from picarones.core.metric_registry import compute_at_junction, select_metrics
38
- from picarones.core.modules import ArtifactType
39
 
40
 
41
  # ──────────────────────────────────────────────────────────────────────────
 
35
  detect_abbreviations,
36
  )
37
  from picarones.core.metric_registry import compute_at_junction, select_metrics
38
+ from picarones.domain.artifacts import ArtifactType
39
 
40
 
41
  # ──────────────────────────────────────────────────────────────────────────
tests/measurements/test_sprint57_mufi.py CHANGED
@@ -32,7 +32,7 @@ from __future__ import annotations
32
  import pytest
33
 
34
  from picarones.core.metric_registry import compute_at_junction, select_metrics
35
- from picarones.core.modules import ArtifactType
36
  from picarones.measurements.mufi import (
37
  compute_mufi_coverage,
38
  is_mufi_char,
 
32
  import pytest
33
 
34
  from picarones.core.metric_registry import compute_at_junction, select_metrics
35
+ from picarones.domain.artifacts import ArtifactType
36
  from picarones.measurements.mufi import (
37
  compute_mufi_coverage,
38
  is_mufi_char,
tests/measurements/test_sprint58_early_modern.py CHANGED
@@ -39,7 +39,7 @@ from picarones.measurements.early_modern_typography import (
39
  get_category,
40
  )
41
  from picarones.core.metric_registry import compute_at_junction, select_metrics
42
- from picarones.core.modules import ArtifactType
43
 
44
 
45
  # ──────────────────────────────────────────────────────────────────────────
 
39
  get_category,
40
  )
41
  from picarones.core.metric_registry import compute_at_junction, select_metrics
42
+ from picarones.domain.artifacts import ArtifactType
43
 
44
 
45
  # ──────────────────────────────────────────────────────────────────────────
tests/measurements/test_sprint59_modern_archives.py CHANGED
@@ -53,7 +53,7 @@ from picarones.measurements.modern_archives import (
53
  modern_archives_expansion_score,
54
  modern_archives_strict_score,
55
  )
56
- from picarones.core.modules import ArtifactType
57
 
58
 
59
  # ──────────────────────────────────────────────────────────────────────────
 
53
  modern_archives_expansion_score,
54
  modern_archives_strict_score,
55
  )
56
+ from picarones.domain.artifacts import ArtifactType
57
 
58
 
59
  # ──────────────────────────────────────────────────────────────────────────
tests/measurements/test_sprint60_roman_numerals.py CHANGED
@@ -22,7 +22,7 @@ from __future__ import annotations
22
  import pytest
23
 
24
  from picarones.core.metric_registry import compute_at_junction, select_metrics
25
- from picarones.core.modules import ArtifactType
26
  from picarones.evaluation.metrics.roman_numerals import (
27
  ALL_STATUSES,
28
  STATUS_CASE_CHANGED,
 
22
  import pytest
23
 
24
  from picarones.core.metric_registry import compute_at_junction, select_metrics
25
+ from picarones.domain.artifacts import ArtifactType
26
  from picarones.evaluation.metrics.roman_numerals import (
27
  ALL_STATUSES,
28
  STATUS_CASE_CHANGED,
tests/measurements/test_sprint64_pipeline_benchmark.py CHANGED
@@ -30,7 +30,8 @@ from __future__ import annotations
30
  from typing import Any
31
 
32
  from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
33
- from picarones.core.modules import ArtifactType, BaseModule
 
34
  from picarones.evaluation.pipeline_benchmark import (
35
  PipelineBenchmarkResult,
36
  StepAggregate,
 
30
  from typing import Any
31
 
32
  from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
33
+ from picarones.domain.artifacts import ArtifactType
34
+ from picarones.domain.module_protocol import BaseModule
35
  from picarones.evaluation.pipeline_benchmark import (
36
  PipelineBenchmarkResult,
37
  StepAggregate,
tests/measurements/test_sprint65_pipeline_comparison.py CHANGED
@@ -32,7 +32,8 @@ from typing import Any
32
  import pytest
33
 
34
  from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
35
- from picarones.core.modules import ArtifactType, BaseModule
 
36
  from picarones.evaluation.pipeline_comparison import (
37
  PipelineComparisonResult,
38
  compare_pipelines,
 
32
  import pytest
33
 
34
  from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
35
+ from picarones.domain.artifacts import ArtifactType
36
+ from picarones.domain.module_protocol import BaseModule
37
  from picarones.evaluation.pipeline_comparison import (
38
  PipelineComparisonResult,
39
  compare_pipelines,
tests/measurements/test_sprint73_baseline_comparison.py CHANGED
@@ -36,7 +36,7 @@ from picarones.measurements.baseline_comparison import (
36
  compute_engine_baseline,
37
  )
38
  from picarones.measurements.narrative.detectors import detect_engine_off_baseline
39
- from picarones.core.facts import FactImportance, FactType
40
  from picarones.measurements.narrative.renderer import render_fact
41
 
42
 
 
36
  compute_engine_baseline,
37
  )
38
  from picarones.measurements.narrative.detectors import detect_engine_off_baseline
39
+ from picarones.domain.facts import FactImportance, FactType
40
  from picarones.measurements.narrative.renderer import render_fact
41
 
42
 
tests/measurements/test_sprint84_searchability.py CHANGED
@@ -180,7 +180,7 @@ class TestRealisticCase:
180
  class TestRegistry:
181
  def test_metric_registered(self) -> None:
182
  from picarones.core.metric_registry import select_metrics
183
- from picarones.core.modules import ArtifactType
184
 
185
  metrics = select_metrics(
186
  (ArtifactType.TEXT, ArtifactType.TEXT),
@@ -199,7 +199,7 @@ class TestRegistry:
199
 
200
  def test_metric_via_compute_at_junction(self) -> None:
201
  from picarones.core.metric_registry import compute_at_junction
202
- from picarones.core.modules import ArtifactType
203
 
204
  results = compute_at_junction(
205
  "le roi", "le roi",
 
180
  class TestRegistry:
181
  def test_metric_registered(self) -> None:
182
  from picarones.core.metric_registry import select_metrics
183
+ from picarones.domain.artifacts import ArtifactType
184
 
185
  metrics = select_metrics(
186
  (ArtifactType.TEXT, ArtifactType.TEXT),
 
199
 
200
  def test_metric_via_compute_at_junction(self) -> None:
201
  from picarones.core.metric_registry import compute_at_junction
202
+ from picarones.domain.artifacts import ArtifactType
203
 
204
  results = compute_at_junction(
205
  "le roi", "le roi",
tests/measurements/test_sprint85_numerical_sequences.py CHANGED
@@ -224,7 +224,7 @@ class TestRealistic:
224
  class TestRegistry:
225
  def test_strict_and_value_metrics_registered(self) -> None:
226
  from picarones.core.metric_registry import select_metrics
227
- from picarones.core.modules import ArtifactType
228
 
229
  metrics = select_metrics((ArtifactType.TEXT, ArtifactType.TEXT))
230
  names = [m.name for m in metrics]
@@ -244,7 +244,7 @@ class TestRegistry:
244
 
245
  def test_metric_via_compute_at_junction(self) -> None:
246
  from picarones.core.metric_registry import compute_at_junction
247
- from picarones.core.modules import ArtifactType
248
 
249
  results = compute_at_junction(
250
  "1789, IV", "1789, IV",
 
224
  class TestRegistry:
225
  def test_strict_and_value_metrics_registered(self) -> None:
226
  from picarones.core.metric_registry import select_metrics
227
+ from picarones.domain.artifacts import ArtifactType
228
 
229
  metrics = select_metrics((ArtifactType.TEXT, ArtifactType.TEXT))
230
  names = [m.name for m in metrics]
 
244
 
245
  def test_metric_via_compute_at_junction(self) -> None:
246
  from picarones.core.metric_registry import compute_at_junction
247
+ from picarones.domain.artifacts import ArtifactType
248
 
249
  results = compute_at_junction(
250
  "1789, IV", "1789, IV",
tests/measurements/test_sprint97_module_policy.py CHANGED
@@ -35,7 +35,8 @@ from picarones.measurements.module_policy import (
35
  audit_module,
36
  validate_manifest,
37
  )
38
- from picarones.core.modules import ArtifactType, BaseModule
 
39
  from picarones.reports_v2.html.renderers.module_audit import (
40
  build_module_audit_html,
41
  )
 
35
  audit_module,
36
  validate_manifest,
37
  )
38
+ from picarones.domain.artifacts import ArtifactType
39
+ from picarones.domain.module_protocol import BaseModule
40
  from picarones.reports_v2.html.renderers.module_audit import (
41
  build_module_audit_html,
42
  )
tests/report/test_sprint46_stratification_html.py CHANGED
@@ -28,7 +28,7 @@ import pytest
28
 
29
  from picarones.measurements.metrics import MetricsResult
30
  from picarones.measurements.narrative.detectors import detect_stratification_recommended
31
- from picarones.core.facts import FactImportance, FactType
32
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
33
  from picarones.core.results import DocumentResult
34
  from picarones.reports_v2.html.generator import ReportGenerator
 
28
 
29
  from picarones.measurements.metrics import MetricsResult
30
  from picarones.measurements.narrative.detectors import detect_stratification_recommended
31
+ from picarones.domain.facts import FactImportance, FactType
32
  from picarones.measurements.narrative.renderer import extract_numbers, render_fact
33
  from picarones.core.results import DocumentResult
34
  from picarones.reports_v2.html.generator import ReportGenerator
tests/report/test_sprint68_pipeline_comparison_html.py CHANGED
@@ -31,7 +31,7 @@ from __future__ import annotations
31
  import json
32
  from pathlib import Path
33
 
34
- from picarones.core.modules import ArtifactType
35
  from picarones.evaluation.pipeline_benchmark import (
36
  PipelineBenchmarkResult,
37
  StepAggregate,
 
31
  import json
32
  from pathlib import Path
33
 
34
+ from picarones.domain.artifacts import ArtifactType
35
  from picarones.evaluation.pipeline_benchmark import (
36
  PipelineBenchmarkResult,
37
  StepAggregate,
tests/report/test_sprint90_engine_unstable.py CHANGED
@@ -23,7 +23,7 @@ from pathlib import Path
23
 
24
  from picarones.measurements.narrative import build_synthesis
25
  from picarones.measurements.narrative.detectors import detect_engine_unstable
26
- from picarones.core.facts import FactImportance, FactType
27
  from picarones.reports_v2.html.renderers.multirun_stability import (
28
  build_multirun_stability_html,
29
  )
 
23
 
24
  from picarones.measurements.narrative import build_synthesis
25
  from picarones.measurements.narrative.detectors import detect_engine_unstable
26
+ from picarones.domain.facts import FactImportance, FactType
27
  from picarones.reports_v2.html.renderers.multirun_stability import (
28
  build_multirun_stability_html,
29
  )
tests/report/test_sprint92_longitudinal.py CHANGED
@@ -32,7 +32,7 @@ from picarones.measurements.longitudinal import (
32
  )
33
  from picarones.measurements.narrative import build_synthesis
34
  from picarones.measurements.narrative.detectors import detect_regression_in_history
35
- from picarones.core.facts import FactImportance, FactType
36
  from picarones.reports_v2.html.renderers.longitudinal import build_longitudinal_html
37
 
38
 
 
32
  )
33
  from picarones.measurements.narrative import build_synthesis
34
  from picarones.measurements.narrative.detectors import detect_regression_in_history
35
+ from picarones.domain.facts import FactImportance, FactType
36
  from picarones.reports_v2.html.renderers.longitudinal import build_longitudinal_html
37
 
38
 
tests/test_reproducibility_ops.py CHANGED
@@ -244,7 +244,7 @@ def test_pricing_staleness_detector_registered() -> None:
244
  """Le détecteur ``detect_pricing_staleness`` doit être enregistré."""
245
  # Trigger registration
246
  import picarones.measurements # noqa: F401
247
- from picarones.core.facts import FactType
248
  from picarones.measurements.narrative.detectors import DETECTORS_BY_TYPE
249
 
250
  assert FactType.PRICING_STALENESS_WARNING in DETECTORS_BY_TYPE
@@ -270,7 +270,7 @@ def test_pricing_staleness_detector_fires_when_expired() -> None:
270
  """Le détecteur émet un Fact si la date est dépassée."""
271
  from datetime import date, timedelta
272
 
273
- from picarones.core.facts import FactType
274
  from picarones.measurements.narrative.detectors.pareto import (
275
  detect_pricing_staleness,
276
  )
 
244
  """Le détecteur ``detect_pricing_staleness`` doit être enregistré."""
245
  # Trigger registration
246
  import picarones.measurements # noqa: F401
247
+ from picarones.domain.facts import FactType
248
  from picarones.measurements.narrative.detectors import DETECTORS_BY_TYPE
249
 
250
  assert FactType.PRICING_STALENESS_WARNING in DETECTORS_BY_TYPE
 
270
  """Le détecteur émet un Fact si la date est dépassée."""
271
  from datetime import date, timedelta
272
 
273
+ from picarones.domain.facts import FactType
274
  from picarones.measurements.narrative.detectors.pareto import (
275
  detect_pricing_staleness,
276
  )