Claude commited on
Commit
18919b0
·
unverified ·
1 Parent(s): b70f12a

docs(handover): SESSION_HANDOVER.md + CLAUDE.md statut migration

Browse files

Préparation pour la transition entre sessions Claude Code.

Ajouts
------
- ``docs/migration/SESSION_HANDOVER.md`` (240 LOC) : guide
complet pour qu'une nouvelle session reprenne sans erreur :
- Sources de vérité (par ordre de priorité).
- Vérifications avant code (branche, working tree, tests, lint).
- 6 pièges connus (architecture des couches, pattern shim,
test_module_coverage, test_file_budgets, test_doc_paths,
README généré).
- Plan d'exécution détaillé de la prochaine sub-phase (7.B.2).
- Pièges anticipés pour 7.B.2 (sémantique inputs, calcul
junction_metrics, output_types partial, spec conversion).
- Commande de démarrage de la nouvelle session.

CLAUDE.md mis à jour
--------------------
- Section « Phase active » remplace l'ancien pointeur audit
institutionnel par le retrait complet du legacy stratégie 4.B.
- Sous-section « Pour reprendre dans une nouvelle session »
pointe vers SESSION_HANDOVER.md.
- Sous-section « Règles d'architecture critiques » liste les
contraintes apprises à la dure (whitelists des couches,
patterns shim, etc.).
- Sous-section « Apprentissages des phases précédentes »
capitalise les recettes répétitives (pattern shim, docstring,
budgets, etc.).
- Tableau « Statut migration au moment du handover » donne
l'état exact phase par phase (0-11) avec ✅/⏳/📋.
- Section « Contexte développement » : branche active mise à
jour ``claude/code-quality-audit-ACnhK`` →
``claude/repo-analysis-cukvm``.

Acceptance
----------
5033 tests passent, lint vert, architecture vérifiée.

Comment l'utilisateur démarre la prochaine session
--------------------------------------------------
Simplement :

Continue la sub-phase 7.B.2.

Claude Code lira automatiquement CLAUDE.md à l'init, qui
pointera vers SESSION_HANDOVER.md, et la procédure de
vérification de l'état initial évitera toute erreur.

https://claude.ai/code/session_011XQZNitg1rCgia8ZD1a2hP

Files changed (2) hide show
  1. CLAUDE.md +106 -6
  2. docs/migration/SESSION_HANDOVER.md +243 -0
CLAUDE.md CHANGED
@@ -192,12 +192,82 @@ chercher.
192
 
193
  Pour le travail courant, ce qui compte :
194
 
195
- - **Phase active** : audit institutionnel post-S57 vers la
196
- release 1.3.0 (cf. section [Unreleased] du CHANGELOG).
197
- - **Documents de référence** : docs/migration/rewrite-status-s46.md
198
- (état du rewrite), docs/audits/ (audits historiques figés),
 
 
 
 
 
 
 
 
199
  docs/roadmap/evolution-2026.md (plan stratégique).
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  ## Moteur narratif
202
 
203
  Le modèle de données (`Fact`, `FactType`, `FactImportance`,
@@ -242,8 +312,38 @@ détecte, arbitre, rend.
242
  ## Contexte développement
243
 
244
  - **Environnement** : GitHub Codespaces, Python 3.11+
245
- - **Tests** : `pytest tests/ -q` → ~5070 passed, 2 skipped, 0 failed.
 
246
  - **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
 
 
247
  - **Manifeste architecture** : [`docs/explanation/architecture.md`](docs/explanation/architecture.md).
248
  - **API publique stable** : [`docs/reference/api-stable.md`](docs/reference/api-stable.md).
249
- - **Branche active** : `claude/code-quality-audit-ACnhK`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  Pour le travail courant, ce qui compte :
194
 
195
+ - **Phase active** : retrait complet du legacy vers le rewrite,
196
+ stratégie 4.B (full migration, sans préservation API). Le
197
+ projet est en stand-by jusqu'à la fin de la migration
198
+ complète tests rouges acceptables temporairement, breaking
199
+ changes acceptés.
200
+ - **Plan maître** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md)
201
+ — cartographie complète des Phases 0-11 avec statut.
202
+ - **Sub-plan convergence pipeline** : [`docs/migration/pipeline-convergence-plan.md`](docs/migration/pipeline-convergence-plan.md)
203
+ — détail de Sub-phases 7.A-7.D (BaseModule → StepExecutor).
204
+ - **Documents de référence figés** :
205
+ docs/migration/rewrite-status-s46.md (état du rewrite),
206
+ docs/audits/ (audits historiques figés),
207
  docs/roadmap/evolution-2026.md (plan stratégique).
208
 
209
+ ### Pour reprendre dans une nouvelle session
210
+
211
+ **Procédure complète** : lire d'abord
212
+ [`docs/migration/SESSION_HANDOVER.md`](docs/migration/SESSION_HANDOVER.md)
213
+ qui contient :
214
+
215
+ - Sources de vérité par ordre de priorité.
216
+ - Vérifications à faire avant de toucher au code (branche,
217
+ working tree, tests, lint).
218
+ - Pièges connus (architecture des couches, patterns shim,
219
+ test_module_coverage / test_file_budgets / test_doc_paths /
220
+ README généré).
221
+ - Plan d'exécution détaillé de la prochaine sub-phase.
222
+
223
+ Résumé express :
224
+
225
+ 1. `git branch --show-current` → `claude/repo-analysis-cukvm`.
226
+ 2. `git status` → working tree clean.
227
+ 3. `pytest tests/ -q --no-header --tb=line` → 5070 passed.
228
+ 4. `git log -1 --format=%B` → décrit la prochaine sub-phase.
229
+
230
+ **Règles d'architecture critiques** (apprises à la dure) :
231
+
232
+ - ``evaluation/`` whitelist externe : ``PIL, annotated_types,
233
+ jiwer, numpy, pydantic, rapidfuzz, scipy, spacy,
234
+ typing_extensions, yaml`` — **pas** ``pytesseract``,
235
+ ``mistralai``, ``azure``, ``google``, ``pero_ocr``. Tout code
236
+ qui importe ces libs externes va dans ``adapters/`` (qui
237
+ autorise les libs externes par design).
238
+ - ``evaluation/`` ne peut pas importer depuis ``pipeline/`` :
239
+ c'est le sens inverse de la dépendance. Si un module bridge
240
+ les deux contrats, il vit dans ``pipeline/``.
241
+ - ``reports_v2/`` ne peut pas importer depuis ``measurements/``
242
+ (legacy) ou ``core/`` (legacy). Les renderers consomment les
243
+ modules canoniques de ``evaluation/metrics/``.
244
+ - ``test_module_coverage::TEST_ONLY_BASELINE`` : ajouter à
245
+ cette frozenset dès qu'un shim ``measurements/X.py`` n'a
246
+ plus de consommateur production (cas typique : un renderer
247
+ est migré vers ``reports_v2/`` et importe directement le
248
+ canonique au lieu du shim).
249
+
250
+ ### Apprentissages des phases précédentes
251
+
252
+ - **Pattern shim** : pour chaque migration, le chemin legacy
253
+ devient un shim minimal (< 25 lignes) avec
254
+ ``from canonical_path import * # noqa: F401, F403`` +
255
+ ``DeprecationWarning`` à l'import. Les noms privés
256
+ (``_FORMATTERS``, ``_PYTESSERACT_AVAILABLE``, etc.) doivent
257
+ être importés explicitement en plus de ``import *`` car
258
+ ``*`` n'exporte pas les ``_`` privés.
259
+ - **Pattern docstring** : ajouter en tête du module canonique
260
+ un bloc ``Phase X — module relocalisé depuis Y vers Z``
261
+ avec mention de la suppression en 2.0.
262
+ - **Pattern test budgets** : si un fichier dépasse 400 LOC,
263
+ ajouter une entrée dans
264
+ ``tests/architecture/test_file_budgets.py::FILE_BUDGETS``
265
+ avec budget = LOC actuel + ~15 %.
266
+ - **Pattern docs paths** : si un sub-plan référence un futur
267
+ chemin Python qui n'existe pas encore (forward reference),
268
+ bumper ``BROKEN_PATHS_BASELINE`` du même montant et noter que la
269
+ référence sera résolue quand le fichier sera créé.
270
+
271
  ## Moteur narratif
272
 
273
  Le modèle de données (`Fact`, `FactType`, `FactImportance`,
 
312
  ## Contexte développement
313
 
314
  - **Environnement** : GitHub Codespaces, Python 3.11+
315
+ - **Tests** : `pytest tests/ -q` → 5070 passed, 12 skipped, 24
316
+ deselected, 0 failed (au moment de la pause de session).
317
  - **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
318
+ - **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md).
319
+ - **Sub-plan convergence pipeline** : [`docs/migration/pipeline-convergence-plan.md`](docs/migration/pipeline-convergence-plan.md).
320
  - **Manifeste architecture** : [`docs/explanation/architecture.md`](docs/explanation/architecture.md).
321
  - **API publique stable** : [`docs/reference/api-stable.md`](docs/reference/api-stable.md).
322
+ - **Branche active** : `claude/repo-analysis-cukvm`.
323
+
324
+ ### Statut migration au moment du handover
325
+
326
+ | Phase | Statut | Détails |
327
+ |---------|-----------|------------------------------------------------------------|
328
+ | 0-3 | ✅ terminée | Foundation, statistics, narrative engine |
329
+ | 4 | ✅ terminée | 35 mesures legacy → ``evaluation/metrics/`` |
330
+ | 4-bis | ✅ terminée | ``ArtifactType`` migration + 22 callers |
331
+ | 4-ter | ✅ terminée | core/{metric_registry,metric_hooks,metrics,results} → eval |
332
+ | 4-quater | ✅ terminée | core/corpus → evaluation/corpus |
333
+ | 5.A | ✅ terminée | helpers + glossary + i18n → reports_v2/ |
334
+ | 5.B | ✅ terminée | (intégré dans 5.A) |
335
+ | 5.C | ✅ terminée | 29 renderers + 5 modules pré-requis → reports_v2/ |
336
+ | 5.D | ✅ terminée | 5 vues thématiques → reports_v2/html/views/ |
337
+ | 5.E | ✅ terminée | generator + comparison + snapshot + data + templates |
338
+ | 7.A | ✅ terminée | engines/ + modules/ → adapters/legacy_*/ |
339
+ | 7.B.1 | ✅ terminée | _BaseModuleAdapter + _PayloadRegistry (commit b70f12a) |
340
+ | 7.B.2 | ⏳ EN COURS | PipelineRunner.run délègue à PipelineExecutor |
341
+ | 7.B.3 | 📋 à venir | pipeline_benchmark/comparison via canonique |
342
+ | 7.C | 📋 à venir | Refactor 7 tests axe B (mocks BaseModule → StepExecutor) |
343
+ | 7.D | 📋 à venir | Suppression BaseModule + PipelineRunner + shims core/ |
344
+ | 6, 8-11 | 📋 à venir | pipelines/, importers, web, cli, retirement final |
345
+
346
+ **Prochaine sub-phase à exécuter** : 7.B.2 (refactor du corps
347
+ de ``PipelineRunner.run`` dans ``evaluation/pipeline.py`` pour
348
+ qu'il délègue à ``PipelineExecutor`` via le wrapper
349
+ ``_BaseModuleAdapter`` créé en 7.B.1).
docs/migration/SESSION_HANDOVER.md ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Handover entre sessions Claude Code
2
+
3
+ > Ce document est lu en premier par chaque nouvelle session pour
4
+ > reprendre le travail sans se tromper. Il pointe vers les
5
+ > sources de vérité, signale les pièges connus, et donne la
6
+ > prochaine action concrète.
7
+
8
+ ---
9
+
10
+ ## 1. Sources de vérité (par ordre de priorité)
11
+
12
+ 1. **[`legacy-retirement-plan.md`](legacy-retirement-plan.md)** —
13
+ plan maître des Phases 0-11 du retrait du legacy. Chaque
14
+ phase a un statut explicite (✅ terminée / ⏳ en cours / 📋 à
15
+ venir).
16
+ 2. **[`pipeline-convergence-plan.md`](pipeline-convergence-plan.md)** —
17
+ sous-plan détaillé de la convergence ``BaseModule`` /
18
+ ``PipelineRunner`` → ``StepExecutor`` / ``PipelineExecutor``
19
+ (Sub-phases 7.A-7.D).
20
+ 3. **[`../../CLAUDE.md`](../../CLAUDE.md)** — règles d'architecture
21
+ à respecter, statut de la migration, et liens vers le reste.
22
+ 4. **`git log --oneline -10`** — les 10 derniers commits
23
+ donnent l'état réel. Le dernier commit message décrit
24
+ souvent la prochaine sub-phase à exécuter.
25
+
26
+ ---
27
+
28
+ ## 2. Vérifications avant de toucher au code
29
+
30
+ ```bash
31
+ # 1. Bonne branche ?
32
+ git branch --show-current
33
+ # → doit retourner: claude/repo-analysis-cukvm
34
+
35
+ # 2. Working tree propre ?
36
+ git status
37
+ # → doit retourner: nothing to commit, working tree clean
38
+
39
+ # 3. Tests verts à l'état initial ?
40
+ python -m pytest tests/ -q --no-header --tb=line
41
+ # → doit retourner: 5070 passed (au moment de la pause de session)
42
+
43
+ # 4. Lint vert ?
44
+ ruff check picarones/ tests/
45
+ # → doit retourner: All checks passed!
46
+ ```
47
+
48
+ Si l'une de ces vérifications échoue : **NE PAS** continuer le
49
+ sprint. Investiguer d'abord pourquoi l'état initial diverge de
50
+ celui annoncé dans CLAUDE.md.
51
+
52
+ ---
53
+
54
+ ## 3. Pièges connus (apprentissages des phases précédentes)
55
+
56
+ ### 3.A Architecture des couches
57
+
58
+ Voir CLAUDE.md section « Règles d'architecture critiques ».
59
+ Résumé :
60
+
61
+ - ``evaluation/`` ne peut pas importer ``pipeline.types`` —
62
+ c'est l'autre sens.
63
+ - ``evaluation/`` whitelist limitée : pas de pytesseract /
64
+ mistralai / azure / google / pero_ocr. Ces libs externes
65
+ vont dans ``adapters/``.
66
+ - ``reports_v2/`` ne peut importer que les canoniques
67
+ (``evaluation/metrics/``), pas les shims legacy
68
+ (``measurements/X.py``).
69
+
70
+ ### 3.B Pattern shim
71
+
72
+ Pour un shim minimal :
73
+
74
+ ```python
75
+ """``picarones.X.Y`` — shim re-export (déprécié, suppression 2.0).
76
+
77
+ Canonique : :mod:`picarones.canonical.path`. Phase X.Y du
78
+ retrait du legacy.
79
+ """
80
+
81
+ from __future__ import annotations
82
+
83
+ import warnings
84
+
85
+ from picarones.canonical.path import * # noqa: F401, F403
86
+ # Si des callers consomment des noms privés (_FOO, etc.),
87
+ # les ré-exporter explicitement :
88
+ from picarones.canonical.path import _FOO # noqa: F401
89
+
90
+ warnings.warn(
91
+ "picarones.X.Y is deprecated and will be removed in 2.0. "
92
+ "Import from picarones.canonical.path instead.",
93
+ DeprecationWarning,
94
+ stacklevel=2,
95
+ )
96
+ ```
97
+
98
+ ### 3.C ``test_module_coverage::TEST_ONLY_BASELINE``
99
+
100
+ Quand un shim ``measurements/X.py`` n'a plus de consommateur
101
+ production (parce qu'un renderer a migré vers le canonique
102
+ direct), ajouter ``"X"`` à ``TEST_ONLY_BASELINE`` dans
103
+ ``tests/architecture/test_module_coverage.py``. Sinon le test
104
+ ``test_no_new_test_only_modules`` échoue.
105
+
106
+ ### 3.D ``test_file_budgets``
107
+
108
+ Tout fichier ≥ 400 LOC doit avoir une entrée dans
109
+ ``FILE_BUDGETS`` avec budget = LOC actuel + ~15 %. Quand on
110
+ relocalise un fichier, retirer l'entrée du chemin legacy et
111
+ en créer une au chemin canonique avec le même budget.
112
+
113
+ ### 3.E ``test_doc_paths::BROKEN_PATHS_BASELINE``
114
+
115
+ Si un sub-plan ou doc référence un futur chemin Python
116
+ (``picarones/X/Y.py``) qui n'existe pas encore, le test
117
+ ``test_broken_doc_paths_below_baseline`` détecte la
118
+ référence cassée. Soit :
119
+
120
+ - Bumper ``BROKEN_PATHS_BASELINE`` du même montant.
121
+ - Ou reformuler la référence en code/backticks pour échapper
122
+ au pattern (``picarones/X/Y.py``).
123
+
124
+ Quand le fichier sera créé en réalité, abaisser
125
+ ``BROKEN_PATHS_BASELINE``.
126
+
127
+ ### 3.F README généré
128
+
129
+ Le compteur de tests dans `README.md` et `CLAUDE.md` est
130
+ synchronisé par `scripts/gen_readme_tables.py`. À chaque
131
+ fois que le nombre de tests change (ajout/retrait), lancer :
132
+
133
+ ```bash
134
+ python scripts/gen_readme_tables.py
135
+ ```
136
+
137
+ Sinon le test ``test_readme_tables_consistent_with_code``
138
+ échoue.
139
+
140
+ ---
141
+
142
+ ## 4. Prochaine sub-phase à exécuter
143
+
144
+ **Sub-phase 7.B.2** — refactoriser le corps de
145
+ ``PipelineRunner.run`` dans
146
+ ``picarones/evaluation/pipeline.py`` (lignes 384-590) pour
147
+ qu'il délègue au canonique ``PipelineExecutor`` via le
148
+ wrapper ``_BaseModuleAdapter`` créé en 7.B.1.
149
+
150
+ ### Plan d'exécution
151
+
152
+ 1. **Lire** ``picarones/evaluation/pipeline.py:PipelineRunner.run``
153
+ en entier pour comprendre la logique actuelle (résolution
154
+ d'inputs versionnés, exécution chronométrée, capture
155
+ d'erreur, évaluation auto vs GT, conversion outputs).
156
+
157
+ 2. **Lire** ``picarones/pipeline/_legacy_module_adapter.py``
158
+ en entier pour comprendre les outils disponibles
159
+ (``_BaseModuleAdapter``, ``_PayloadRegistry``,
160
+ ``wrap_initial_inputs``).
161
+
162
+ 3. **Écrire** un nouveau corps de ``PipelineRunner.run`` qui :
163
+ - Crée un ``_PayloadRegistry`` par appel.
164
+ - Wrappe les ``initial_inputs`` legacy via
165
+ ``wrap_initial_inputs(...)``.
166
+ - Convertit la ``PipelineSpec`` legacy en ``PipelineSpec``
167
+ canonique (``picarones.domain.pipeline_spec.PipelineSpec``).
168
+ Chaque ``PipelineStep.module: BaseModule`` devient un
169
+ ``adapter_name: str``, et l'adapter est
170
+ ``_BaseModuleAdapter(module, registry)``.
171
+ - Construit un ``adapter_resolver`` qui retourne le
172
+ wrapper de chaque module.
173
+ - Construit un ``RunContext``.
174
+ - Convertit le ``Document`` legacy en ``DocumentRef``.
175
+ - Invoque ``PipelineExecutor.run(canonical_spec,
176
+ document_ref, canonical_inputs, context)``.
177
+ - Reconvertit le ``PipelineResult`` canonique en
178
+ ``PipelineResult`` legacy.
179
+ - Calcule ``junction_metrics`` en post-étape (parcourt
180
+ les ``StepResult.produced_artifacts``, lit le payload
181
+ du registre, appelle ``compute_at_junction`` contre la
182
+ GT du document si ``GTLevel`` correspond).
183
+
184
+ 4. **Tester** : tous les tests existants doivent toujours
185
+ passer (les 7 fichiers axe B + ``test_sprint63_pipeline_runner``,
186
+ etc.). C'est l'invariant de la sub-phase 7.B.2.
187
+
188
+ 5. **Lint** : ``ruff check picarones/ tests/``.
189
+
190
+ 6. **Commit + push** avec message décrivant ce qui a été
191
+ fait + pointer vers la sub-phase 7.B.3 comme prochaine
192
+ étape.
193
+
194
+ ### Pièges anticipés pour 7.B.2
195
+
196
+ - **Sémantique différente des inputs entre legacy et canonique** :
197
+ le legacy passe ``Document.image_path`` comme un string
198
+ pur dans ``initial_inputs[ArtifactType.IMAGE]`` ; le canonique
199
+ attend un ``Artifact(uri=...)``. ``wrap_initial_inputs``
200
+ fait la conversion mais il faut s'assurer que les modules
201
+ consomment bien le ``uri`` côté `_BaseModuleAdapter`.
202
+
203
+ - **``junction_metrics`` calcul** : le legacy
204
+ ``PipelineRunner.run`` calcule ``junction_metrics`` à
205
+ chaque step (cf. ligne 519-540 actuellement). Le canonique
206
+ ``PipelineExecutor`` ne le fait pas. Il faut donc faire
207
+ ce calcul **après** l'exécution canonique, en parcourant
208
+ les artefacts produits et en lisant les payloads via le
209
+ registre.
210
+
211
+ - **``output_types`` partial** : si un module produit un
212
+ output type non déclaré, le legacy le tolère (on remplit
213
+ ``StepResult.output_types`` avec ce qui est effectivement
214
+ produit, pas ce qui est déclaré). Le canonique
215
+ ``PipelineExecutor`` rejette en ``error="missing_output: ..."``.
216
+ Vérifier la sémantique attendue par les tests.
217
+
218
+ - **Spec conversion** : ``PipelineStep`` legacy a
219
+ ``inputs_from: dict[ArtifactType, str]`` (mapping
220
+ type→step_name). ``PipelineStep`` canonique a
221
+ ``inputs_from: tuple[InputBinding, ...]``. Conversion
222
+ attentive nécessaire.
223
+
224
+ ---
225
+
226
+ ## 5. Commande de démarrage de la nouvelle session
227
+
228
+ Le user envoie simplement :
229
+
230
+ ```
231
+ Reprends la migration. Lis docs/migration/SESSION_HANDOVER.md
232
+ en entier d'abord, puis commence par les vérifications de la
233
+ section 2.
234
+ ```
235
+
236
+ Ou pour aller direct à l'action :
237
+
238
+ ```
239
+ Continue la sub-phase 7.B.2.
240
+ ```
241
+
242
+ (Claude Code va automatiquement lire CLAUDE.md à l'init, qui
243
+ pointera vers ce SESSION_HANDOVER.md et les plans détaillés.)