diff --git a/_INDEX.md b/_INDEX.md index 56db45b..5abcdd9 100644 --- a/_INDEX.md +++ b/_INDEX.md @@ -205,3 +205,4 @@ - [hermes-tt/nyora-notes-tt-message-id-elem-id-volatile-08-08-2026.md](hermes-tt/nyora-notes-tt-message-id-elem-id-volatile-08-08-2026.md) -- Piste "message_id natif via elem_id OWA" FERMEE : elem_id (attribut id de ligne) s'est revele VOLATILE (GUID de rendu regenere a chaque appel -- test rigoureux 0/19 messages stables, ensembles disjoints, meme index -> id different). Un premier test a 1 seul message en position 0 sur appels rapproches l'avait faussement valide (DOM re-utilise). Decision : message_id reste le hash SHA256(subject|date|sender) STABLE ; conversation_id (data-convid, niveau THREAD, regex ciblee jamais split sur |) et fix retry /search count:0 transitoire CONSERVES. Garde-fou dedup verifie (message_id = cle de dedup ; 399 notes toutes en dossiers 'done' jamais re-scannes ; 0 note degradee inseree pendant la fenetre elem_id). Lecon SPA : tester un id DOM sur >=2 rendus reels et plusieurs messages (08/08/2026) - [common/guardrails-flotte-hermes-hard-stop-tirith-verificateur-12-08-2026.md](common/guardrails-flotte-hermes-hard-stop-tirith-verificateur-12-08-2026.md) -- hard_stop_enabled et tirith_enabled actives sur les 4 instances (etaient false), verificateur delegate_task croise (NAS genere DeepSeek/verifie Mimo V2.5, hermes-nabil inverse) ; faille provenance mail->RAG confirmee par lecture code mais pas corrigee (chantier a part) ; hermes-agent-tt trouve down 8h (mort non-propre, cause inconnue), hermes-workspace-perso bloque par port 3030 orphelin (12/08/2026) +- [hermes-tt/nyora-notes-tt-backfill-72h-perte-silencieuse-429-resync-error404-16-08-2026.md](hermes-tt/nyora-notes-tt-backfill-72h-perte-silencieuse-429-resync-error404-16-08-2026.md) -- Backfill mail 72h termine (643->4322 notes). Deux pieges : (1) 444 messages perdus en silence sur 63 dossiers (18%) -- 66% sur HTTP 429 embeddings jete au lieu de reessaye, reste sur raisonnement mimo-v2.5 tronquant le JSON (max_tokens partage) ; dossier passait 'done' quand meme, bilan ne comptait pas les echecs -- fix retries+backoff, max_tokens 2500->8000, compteur messages_ignores remonte au bilan (0 perte en tranche finale). (2) 122 error_404 mesuraient un resolveur de chemin perime (bugs C/D corriges le 10/08), pas des dossiers absents -- 105/122 resolubles apres confrontation normalisee a un /folders frais. Regle generale : tout pipeline lot-LLM doit exposer un compteur d'echecs a cote du compteur de succes (16/08/2026) diff --git a/hermes-tt/nyora-notes-tt-backfill-72h-perte-silencieuse-429-resync-error404-16-08-2026.md b/hermes-tt/nyora-notes-tt-backfill-72h-perte-silencieuse-429-resync-error404-16-08-2026.md new file mode 100644 index 0000000..c01005c --- /dev/null +++ b/hermes-tt/nyora-notes-tt-backfill-72h-perte-silencieuse-429-resync-error404-16-08-2026.md @@ -0,0 +1,87 @@ +# Backfill mail nyora-notes-tt (72h) — perte silencieuse 429 + faux 122 error_404 (16/08/2026) + +Fenêtre de backfill autonome sur `nyora-notes-tt` (5 tranches, 12→16/08/2026, supervision +Telegram). Résultat : 643 → 4322 notes. Deux pièges rencontrés en cours de route valent d'être +documentés séparément, parce que chacun aurait pu clôturer la fenêtre sur un état faussement +propre. + +## Piège 1 — un bilan « done » peut cacher 18% de messages perdus en silence + +**Symptôme** : les tranches 1 et 2 annonçaient leurs dossiers `done` sans anomalie visible. +Le comptage réel (lignes `WARNING ... ignore (extraction/embedding en echec)` dans le journal, +jamais agrégées) a révélé **444 messages perdus sur 63 dossiers**, soit ~18% du volume traité. +Invisible parce que : le dossier passe `done` malgré la perte, l'avertissement est noyé dans des +milliers de lignes `INFO`, et **le bilan de fin de tranche ne comptait pas ces lignes**. + +**Cause** : 66% des pertes = `HTTP 429 Too Many Requests` sur `/v1/embeddings` — le pipeline +enchaîne un embedding par message sans temporisation ; le code traitait un 429 comme une erreur +définitive et jetait le message. Le reste = `mimo-v2.5` (modèle à raisonnement) dont les +`reasoning_tokens` s'imputent sur le même `max_tokens` que la réponse JSON attendue (2500) — +un raisonnement long tronquait le JSON avant qu'il ne soit émis. + +**Fix** (`pipeline_processor.py`, dépôt Gitea `bolbol/nyora-notes-tt` commit `838f28d`) : +- `_appel_bifrost()` : réessais avec temporisation exponentielle (2s → 60s puis → 120s) sur + 429/5xx/erreur réseau, respect de l'en-tête `Retry-After`. Les 4xx hors 429 ne sont PAS + réessayés (une requête malformée le reste). Validé sur la tranche 4 : 8 réessais déclenchés, + jamais au-delà de la tentative 2/8 — **la profondeur suffit largement**, c'était son absence + qui posait problème, pas le principe. +- `max_tokens` 2500 → 8000 sur Mimo et DeepSeek + détection explicite de + `finish_reason == "length"` (erreur nommée au lieu d'un JSON silencieusement tronqué). +- Lecture du JSON dans les trois champs possibles (`content`, `reasoning`, `reasoning_content`) : + la position du raisonnement variait selon la configuration du fournisseur. +- **`messages_ignores` remonté dans le résultat de `process_folder` et dans le bilan de + tranche**, avec le taux et la liste des dossiers touchés (`backfill_tranche.py`). C'est le + changement qui compte le plus : sans lui, la perte reste invisible même si elle est corrigée + ailleurs. + +**Réparation** : les 63 dossiers amputés ont été repassés en `pending` — sans risque de doublon, +la dédup de ce projet est par COMPTAGE (N messages du scan vs M notes en base, ingère la +différence) et non par identification message à message. Résultat mesuré : `02 2024|⚖️ Cour des +Comptes` a rendu exactement 40 notes nouvelles sur 69 messages vus, 29 déjà représentés — les 40 +qui manquaient. Taux de perte : ~18% (tranche 1-2, avant fix) → 2,9% (tranche 3, retries à 5/60s) +→ **0% (tranche 4, retries à 8/120s)**. + +**Règle générale** (versée côté PROTOCOL-INFRA des 3 instances, cf `[[hermes-instances-knowledge]]`) : +tout pipeline qui appelle un LLM/embedding en boucle sur un lot doit exposer un compteur +d'échecs/ignorés À CÔTÉ du compteur de succès dans son bilan de fin de lot — un statut `done` +optimiste sur un lot n'est une preuve de rien tant que le delta réel (messages vus vs messages +ingérés) n'est pas vérifié explicitement. + +## Piège 2 — 122 dossiers "error_404" mesuraient un bug de résolution périmé, pas des dossiers absents + +**Symptôme** : au reprise de la fenêtre, le checkpoint listait 122 dossiers en `error_404`. Une +lecture rapide aurait pu conclure que 122 dossiers avaient disparu de la boîte et clôturer la +fenêtre sur ~60 dossiers traitables au lieu de 145. + +**Cause** : 121 de ces 122 `error_404` avaient été posés entre le 31/07 et le 02/08 — +**avant** les correctifs bugs C et D du 10/08 côté `hermes-mail-browser` +(`go_to_folder_path` : bug C, le 1er segment n'était cherché que sous la Boîte de réception ; +bug D, un dossier AYANT DES ENFANTS ne pouvait pas être sélectionné — 63 dossiers du compte +concernés). Les `error_404` mesuraient donc l'ancien résolveur, pas l'état réel de la boîte. + +**Méthode de vérification** : confronter le checkpoint à un `/folders` frais, en normalisant +casse + suffixe + préfixes emoji (les dossiers avaient été renommés `⏱️ Suivi`, `🤖 Veille`... +entre-temps) plutôt que de comparer des chaînes brutes. Sur cette confrontation normalisée, +105 des 122 `error_404` se sont révélés parfaitement résolubles. Signal d'alerte pendant le +diagnostic : des dossiers `done` (donc traités avec succès) ressortaient classés « absents » — +preuve que la comparaison était fautive, pas l'arbre. + +**Fix appliqué** : 121 des 122 déclassés en `pending` après vérification individuelle contre +l'arbre réel (script conservé sur le NAS : `nyora-notes-tt/backups/phase0_apply_resync.py`). +Sur les 12 réellement introuvables, 12 se sont confirmés disparus (dossiers `Notification` type +"Lot XX" devenus des feuilles sans enfant). + +**Règle générale** : un statut d'échec (`error_404`, `error_409`...) porte une date implicite — +celle du bug qui l'a produit. Après un correctif touchant la résolution/navigation, **ne jamais +supposer qu'un lot d'échecs anciens reflète l'état actuel** sans le reconfronter à une lecture +fraîche. Le coût de la vérification (un appel `/folders` + normalisation) est sans commune +mesure avec le coût d'abandonner ~90 dossiers valides. + +## Références + +- Dépôt Gitea `bolbol/nyora-notes-tt`, commit `838f28d` (correctifs pipeline_processor.py, + backfill_tranche.py, hermes_mail_client.py). +- Snapshots de frontière : `nyora-notes-tt/backups/nyora-notes-tt.db.FINAL-backfill-20260816` + et les snapshots intermédiaires `avant-correctif-mimo-20260814`, `fin-tranche3-20260816`, + `fin-tranche4-20260816`. +- Voir aussi [[hermes-mail-browser]], [[nyora-notes-tt-message-id-dedup-comptage-11-08-2026]].