hermes-tt: 4 bugs extraction OWA (A+B corriges, C+D diagnostiques)

A - glyphe de zone privee Unicode seul en ligne 0 de raw_text decalant tout le
    decoupage positionnel : sender, subject ET date faux ensemble. 295/399 notes
    avaient un received_date qui n'est pas une date. 11 points de code PUA distincts
    recenses sur 40 dossiers, dont 7 hors de la plage Fluent UI habituelle -> retenir
    U+E000-U+F8FF. Correctif : nettoyage en amont du decoupage, date par motif,
    normalisation ISO 8601 au jour, message_id sur champs normalises + conversation_id
    comme discriminant. Corrige aussi checkpoint.last_processed_date (meme source).

B - search_folder() ne transmettait pas limit a /search -> plafond serveur silencieux
    a 20 items, dossier marque done comme s'il etait complet.

C - dossiers hors Reception inatteignables : 3 chemins de navigation, 3 defauts deja
    resolus ailleurs dans le meme fichier. Diagnostique, non corrige.

D - NON RESOLU, BLOQUANT BACKFILL : /search renvoie le contenu de la Boite de reception
    pour certains folder_path, en HTTP 200. Invalide la methode d'audit de completude
    et remet en question le classement des 399 notes existantes.

+ 3 regles generales dans PROTOCOL-INFRA.md (glyphe/emoji cassant tout matching de
texte naif sur OWA ; valeur par defaut serveur non transmise = troncature silencieuse ;
verifier la portee d'un resultat scope, pas seulement son code HTTP).
This commit is contained in:
2026-08-10 17:24:17 +01:00
parent ac2a1b641e
commit c5f25684f7
3 changed files with 308 additions and 0 deletions
+58
View File
@@ -240,3 +240,61 @@ est vide de facon inattendue, retry UNIQUE apres `time.sleep(4)` avant d'abandon
backoff). Piege de parsing associe : `attrs` (string pipe-delimitee) reinjecte `aria-label` en fin de
chaine (texte libre non echappe, `|` et sauts de ligne possibles) -> NE JAMAIS `split('|')` global ;
extraire par regex ciblee (`data-convid=([^|]+)`, base64 sans `|`). Detail : meme runbook ci-dessus.
## REGLE -- OWA : un glyphe d'icone (zone privee Unicode) ou un emoji casse tout matching de texte naif (2026-08-10)
Le texte rendu par OWA est fait pour l'oeil, pas pour servir de structure de donnees. OWA insere des
glyphes d'icone issus de la ZONE PRIVEE Unicode (lu/non-lu, importance, piece jointe) directement dans
le texte scrape -- et les libelles de dossiers portent des emoji. Ces caracteres ne sont PAS des
espaces : `.strip()` ne les retire pas et ils survivent a un filtre `if l.strip()`.
Le meme phenomene a maintenant casse TROIS surfaces differentes :
1. Parsing d'une ligne de message (`_parse_item`, nyora-notes-tt) : un glyphe seul sur la ligne 0 de
`raw_text`, present sur une partie seulement des messages, decale le decoupage positionnel d'un
cran -- expediteur, objet ET date faux ENSEMBLE. Resultat mesure : 295/399 notes avec un
`received_date` qui n'est pas une date (74%), dont 90 contenant un glyphe.
2. Clic sur le volet dossiers (`resolve_folder_treeitem`, hermes-mail-browser) : `inner_text()` peut
renvoyer vide ou reduit au seul glyphe d'icone -> aucun dossier ne matche.
3. Resolution de chemin de dossier (deja documente le 30-31/07/2026).
PLAGE A RETENIR : la PUA COMPLETE U+E000-U+F8FF. La plage "Fluent UI" habituelle (U+E700-U+ECFF) est
INSUFFISANTE -- `U+E1B7` a ete observe en production hors de cette plage, a cote de `U+E73E`.
REFLEXES :
- Lire des ATTRIBUTS STRUCTURES (`data-folder-name`, `data-convid`, `aria-*`) plutot que du texte rendu.
- Nettoyer la plage PUA AVANT tout decoupage, jamais champ par champ en aval (c'est un decalage
d'indice unique qui fausse tous les champs d'un coup).
- Ne jamais lire une donnee par POSITION dans du texte rendu : chercher par MOTIF, et prevoir une
sentinelle explicite si rien ne matche -- ne jamais retomber sur une ligne arbitraire.
Detail : hermes-tt/nyora-notes-tt-parsing-owa-pua-10-08-2026.md.
## REGLE -- une valeur par defaut cote serveur non transmise = troncature silencieuse (2026-08-10)
`hermes_mail_client.search_folder()` n'a jamais transmis `limit` a `/search` : il l'appliquait en
tranche cliente (`[:limit]`) sur une reponse DEJA tronquee. `hermes-mail-browser` plafonne `/search`
a 20 items par defaut, SANS erreur ni avertissement -- le dossier passe ensuite en statut `done`
comme s'il avait ete traite entierement. Temoin `00 2026|Veille` : 14 notes + 6 doublons = exactement
20 en base pour 37 messages reels.
REFLEXE : tout plafond cote serveur doit etre TRANSMIS EXPLICITEMENT, jamais laisse a sa valeur par
defaut. Une troncature silencieuse est indetectable en aval -- corollaire : quand un compteur colle
pile a une valeur ronde (20, 50, 100), suspecter un plafond avant de conclure que la source est vide.
Detail : meme runbook ci-dessus.
## REGLE -- verifier la PORTEE d'un resultat scope, pas seulement son code HTTP (2026-08-10)
`GET /search?folder_path=X` de hermes-mail-browser renvoie parfois le contenu de la BOITE DE
RECEPTION au lieu du dossier demande -- en HTTP 200, sans aucune erreur. Deux chemins differents
renvoyaient 77 items dont 63 communs, toutes les lignes portant le libelle "Boite de reception".
Deterministe et lie au chemin (un dossier connu-bon reteste apres un connu-mauvais redonne le bon
resultat) : ce n'est ni une derive d'etat ni de la contention. Cause probable : le segment est
trouve dans l'arbre mais le clic ne change pas reellement de dossier, et la recherche s'execute
alors dans la portee heritee -- `go_to_folder_path` ne leve une 404 que si un segment est
INTROUVABLE, jamais si la navigation echoue silencieusement apres un clic accepte.
REFLEXE : un 200 ne prouve pas que la portee demandee a ete respectee. Quand une API navigue avant
de lire, verifier dans la REPONSE une marque de la portee obtenue. Ici c'est gratuit : la derniere
ligne de `raw_text` porte le libelle du dossier du message -- s'il ne correspond pas au dossier
demande, la navigation a echoue. Corollaire : un audit de completude bati sur une source non
verifiee produit des chiffres qui ont l'air precis et ne veulent rien dire.
Detail : hermes-tt/nyora-notes-tt-parsing-owa-pua-10-08-2026.md (bug D).