From 7dd4520ca6d1c791bcda339094d3ed699942fafa Mon Sep 17 00:00:00 2001 From: Antigravity Date: Wed, 9 Sep 2026 15:37:05 +0100 Subject: [PATCH] =?UTF-8?q?docs(nyora):=20capitalisation=20r=C3=A9g=C3=A9n?= =?UTF-8?q?=C3=A9ration=20DOCX=20et=20visual=20previews=207=20documents=20?= =?UTF-8?q?(ticket=20nyora-2026-09-034)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _INDEX.md | 1 + ...egeneration-docx-corpus-7docs-ticket034.md | 140 ++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 hermes-nyora/runbook-regeneration-docx-corpus-7docs-ticket034.md diff --git a/_INDEX.md b/_INDEX.md index 17a6bfa..59f1a15 100644 --- a/_INDEX.md +++ b/_INDEX.md @@ -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 | diff --git a/hermes-nyora/runbook-regeneration-docx-corpus-7docs-ticket034.md b/hermes-nyora/runbook-regeneration-docx-corpus-7docs-ticket034.md new file mode 100644 index 0000000..57024a2 --- /dev/null +++ b/hermes-nyora/runbook-regeneration-docx-corpus-7docs-ticket034.md @@ -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 (``). + +### 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 `` créées avec alignement correct. +- [x] **Tableaux & `\hline`** : Présence systématique des bordures `` 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 `.docx` vers `.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/.verified.md", + "output_docx_path": "/tmp/pack-mp1-test/verif_outputs/full_run/.docx", + "pdf_path": "/tmp/pack-mp1-test/.pdf", + "figures_manifest_path": "/tmp/pack-mp1-test/.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/.docx') as z: + xml = z.read('word/document.xml').decode('utf-8') +print('oMath:', len(re.findall(r'