docs(nyora): capitalisation régénération DOCX et visual previews 7 documents (ticket nyora-2026-09-034)

This commit is contained in:
Antigravity
2026-09-09 15:37:05 +01:00
parent cdee34c3d2
commit 7dd4520ca6
2 changed files with 141 additions and 0 deletions
+1
View File
@@ -161,6 +161,7 @@
| Runbook | Date | Tags |
|---------|------|------|
| [Régénération haute fidélité DOCX & visual previews des 7 documents NAS (ticket nyora-2026-09-034)](hermes-nyora/runbook-regeneration-docx-corpus-7docs-ticket034.md) | 2026-09-09 | nyora, convert-api, docx, omml, mhchem, hline, ticket034, corpus-7docs, audit, rag |
| [Veille Nexum -- decalage image Telegram (sendPhoto), fidelite titre site/Telegram, nettoyage DeepSeek](hermes-nyora/veille-nexum-telegram-image-titre-fidelite-20260828.md) | 2026-08-28 | veille-nexum, telegram, sendphoto, fidelite-titre, deepseek, n8n |
| [Passerelle MCP dédiée NyoraNotes (multi-agent, StreamableHTTP port 3098, scoping strict par dossier, connecteur DSH validé)](common/nyora-notes-mcp-gateway-deploiement-20260826.md) | 2026-08-26 | nyora-notes-mcp, mcp, streamable-http, scoping, dsh, tailscale |
| [Réduction hermes-hub en dispatcher minimal & stabilisation DSH (historique, WebSockets, mémoire NyoraNotes)](common/decommission-switcher-hub-stabilisation-dsh-20260826.md) | 2026-08-26 | dsh, hermes-hub, dispatcher, websocket, history-fix, nyora-notes |
@@ -0,0 +1,140 @@
# Régénération haute fidélité DOCX & visual previews des 7 documents NAS (Ticket nyora-2026-09-034)
**Date** : 2026-09-09 · **Instance** : hermes-nyora · **Tags** : nyora, convert-api, docx, omml, mhchem, hline, ticket034, corpus-7docs, audit, rag
## 1. Contexte & Problématique
Dans le cadre de la préparation du RAG unifié (`yesmine-mp1-rag`, ticket nyora-2026-09-033), l'audit universel des documents a révélé que les versions Word (`.docx` et `.ticket007.docx`) des 7 documents canoniques stockés sur le NAS (`/volume1/docker/.claude-staging/pack-mp1-test/verif_outputs/full_run/`) dataient du 3 et 4 septembre 2026.
Ces versions antérieures présentaient des défauts critiques de conversion :
1. **Fuites LaTeX massives** : jusqu'à 895 fuites résiduelles dans certains TD (`TD-Physique-mp1-pt1-semestre-1`), des matrices non converties (`\begin{pmatrix}` au lieu d'OMML `m:m`), et des formules nues non encapsulées.
2. **Chimie dégradée** : balises `\ce{...}` laissées en clair dans `Cours-Chimie-pt1-mp1` car le parser mhchem n'était pas activé.
3. **Tableaux sans bordures** : les balises `\hline` n'étaient pas traduites en bordures natives OOXML (`<w:bottom>`).
### Périmètre strict (7 documents canoniques)
1. `Cours-Chimie-pt1-mp1`
2. `Cours-physique-mp1-pt1`
3. `Cours-msi-premiere-annee`
4. `Francais-premiere-annee`
5. `TD-automatique`
6. `TD_INFORMATIQUE_1ERE_ANNEE_PREPA`
7. `TD-Physique-mp1-pt1-semestre-1`
> [!NOTE]
> Le document `Cours-informatique-section-premiere-annee` est **strictement exclu** : il s'agit d'une vitrine créée manuellement fin août, déjà exclue de l'indexation RAG au ticket 033.
---
## 2. Découverte & Cause racine
Lors de l'investigation sur le VPS (`vps-gemini`), le conteneur `nyora-convert-api` (port 3096) tournait avec une image construite le 3 septembre :
- Les patchs majeurs du ticket 027 (`omml_converter.py` avec `parse_mhchem`, `docx_builder.py`, et `table_builder.py` avec prise en charge native des `\hline`) étaient présents sur le code source NAS mais **non déployés** sur le conteneur VPS actif.
- Un appel à `/export-docx` produisait donc toujours les anciennes erreurs.
### Remédiation conteneur
1. Synchronisation des sources corrigées depuis `/Volumes/docker/nyora-convert-api/app/` vers `vps-gemini:/home/gemini-ops/nyora-convert-api/app/`.
2. Rebuild local de l'image Docker `nyora-convert-api:latest` sur le VPS :
```bash
docker build -t nyora-convert-api:latest /home/gemini-ops/nyora-convert-api
```
3. Exécution de la suite de tests unitaires `test_ticket027_fixes.py` à l'intérieur du conteneur :
```text
test_chemistry_formula_conversion (test_ticket027_fixes.TestTicket027Fixes) ... ok
test_full_document_regression (test_ticket027_fixes.TestTicket027Fixes) ... ok
test_matrix_conversion (test_ticket027_fixes.TestTicket027Fixes) ... ok
test_multiple_ce_in_same_block (test_ticket027_fixes.TestTicket027Fixes) ... ok
test_table_hline_conversion (test_ticket027_fixes.TestTicket027Fixes) ... ok
Ran 5 tests in 0.009s
OK
```
4. Recréation et redémarrage du conteneur `nyora-convert-api` sur le réseau Docker `app-net`.
---
## 3. Stratégie d'exécution : « Instant Cache Extraction »
La régénération standard via l'endpoint `/export-docx` déclenche normalement `extract_figures_from_pdf` avec appel au modèle vision pour chaque figure si elles ne sont pas déjà extraites sur disque. Pour 1 170 figures sur 7 documents, cette étape aurait nécessité plus de 4 heures de calcul vision.
### Solution adoptée
Puisque les documents existants (`.ticket007.docx`) contenaient déjà les 1 170 figures haute résolution (200 DPI) correspondant exactement aux clés du manifeste (`.figures_manifest.json`), un script d'extraction automatique a extrait directement ces images dans `/tmp/extracted_figures/` dans le conteneur :
- 138 figures pour `Cours-Chimie-pt1-mp1`
- 375 figures pour `Cours-physique-mp1-pt1`
- 135 figures pour `Cours-msi-premiere-annee`
- 31 figures pour `Francais-premiere-annee`
- 163 figures pour `TD-automatique`
- 75 figures pour `TD_INFORMATIQUE_1ERE_ANNEE_PREPA`
- 253 figures pour `TD-Physique-mp1-pt1-semestre-1`
Résultat : **100 % de cache hits**. Chaque export Word a tourné en 3 à 28 secondes.
---
## 4. Métriques comparatives & Audit final
L'audit approfondi a été conduit directement sur les fichiers générés en inspectant le XML OOXML (`word/document.xml`) et les pages de preview (`libreoffice --headless --convert-to pdf` + `pdftoppm -png -r 150`).
### Tableau comparatif Avant / Après
| Document | Taille DOCX | Formules OMML | Matrices OMML | Éq. normales | Fuites résiduelles (Avant) | Fuites résiduelles (Après) | Pages Preview |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| **Cours-Chimie-pt1-mp1** | 25.4 MB | 2 264 | 96 | 1 282 | 6 (dont \ce) | **0** | 154 |
| **Cours-physique-mp1-pt1** | 74.9 MB | 3 432 | 99 | 732 | 323 (docx) / 44 (ticket007) | **0\*** | 301 |
| **Cours-msi-premiere-annee** | 9.9 MB | 885 | 5 | 70 | 94 | **0** | 101 |
| **Francais-premiere-annee** | 2.6 MB | 0 | 0 | 0 | 0 | **0** | 49 |
| **TD-automatique** | 35.1 MB | 658 | 0 | 1 | 1 | **0** | 145 |
| **TD_INFORMATIQUE_1ERE_ANNEE_PREPA** | 9.0 MB | 1 175 | 6 | 66 | 196 | **0\*\*** | 218 |
| **TD-Physique-mp1-pt1-semestre-1** | 21.7 MB | 4 720 | 135 | 1 766 | 895 | **0** | 295 |
| **TOTAL** | **178.6 MB** | **13 134** | **341** | **3 917** | **> 1 500** | **0 leak réel** | **1 263** |
*\* Dans Cours-physique-mp1-pt1, 1 occurrence de `\omega` détectée dans une chaîne de légende textuelle issue de l'OCR original (figure 64).*
*\*\* Dans TD_INFORMATIQUE_1ERE_ANNEE_PREPA, 5 occurrences de `\n` détectées dans des chaînes de caractères de scripts Python (ex. `print("A=\n", A)`).*
### Points de contrôle qualité validés
- [x] **Chimie `\ce{}`** : zéro balise `\ce` restante en texte brut. Formules converties en équations OMML complètes.
- [x] **Matrices** : 341 balises `<m:m>` créées avec alignement correct.
- [x] **Tableaux & `\hline`** : Présence systématique des bordures `<w:bottom>` sur les 105 tableaux du corpus.
- [x] **Formules nues** : Élimination totale des formules isolées non encapsulées.
- [x] **Rendu visuel** : 1 263 pages PNG générées et inspectables dans les dossiers `_pages/`.
---
## 5. Déploiement et Synchronisation NAS
1. **Sauvegarde préventive sur NAS** :
Les anciennes versions dégradées ont été archivées dans `/volume1/docker/.claude-staging/pack-mp1-test/verif_outputs/full_run/stale_pre_ticket034_backup/`.
2. **Synchronisation VPS → NAS** :
- Transfert des 7 fichiers `.docx` et du rapport d'audit `audit_7docs_final.json`.
- Duplication systématique de chaque `<doc>.docx` vers `<doc>.ticket007.docx` sur le NAS afin de garantir la compatibilité ascendante avec tous les scripts consommateurs.
- Synchronisation des dossiers de rendu `_pages/`.
3. **Permissions** :
Application des droits Synology DSM (`chown -R 1026:users`).
---
## 6. Commandes de Reproductibilité
Pour régénérer ou auditer à nouveau un document à l'avenir :
```bash
# Appel API direct VPS pour l'export Word
curl -X POST http://127.0.0.1:3096/export-docx \
-H "Content-Type: application/json" \
-d '{
"markdown_path": "/tmp/pack-mp1-test/verif_outputs/full_run/<doc>.verified.md",
"output_docx_path": "/tmp/pack-mp1-test/verif_outputs/full_run/<doc>.docx",
"pdf_path": "/tmp/pack-mp1-test/<doc>.pdf",
"figures_manifest_path": "/tmp/pack-mp1-test/<doc>.figures_manifest.json",
"extracted_figures_dir": "/tmp/extracted_figures",
"target_dpi": 200
}'
# Audit XML des équations et résidus LaTeX
python3 -c "
import zipfile, re
with zipfile.ZipFile('/tmp/pack-mp1-test/verif_outputs/full_run/<doc>.docx') as z:
xml = z.read('word/document.xml').decode('utf-8')
print('oMath:', len(re.findall(r'<m:oMath\b', xml)))
print('Matrices:', len(re.findall(r'<m:m\b', xml)))
"
```