hermes-tt: pilote post-fix D -- message_id instable (bloquant backfill/n8n), concurrence SQLite, debit mesure

This commit is contained in:
Claude (hermes-perso)
2026-08-11 07:10:14 +01:00
parent 3f232b44f6
commit 32812c1172
@@ -174,3 +174,67 @@ Corollaire tiré du bug E : quand un garde-fou doit trancher sur des données br
« je ne peux pas conclure » mérite d'être mesuré avant d'être traité comme inoffensif**. Ici il « je ne peux pas conclure » mérite d'être mesuré avant d'être traité comme inoffensif**. Ici il
recouvrait un second mode de corruption, et la politique permissive choisie par prudence était recouvrait un second mode de corruption, et la politique permissive choisie par prudence était
précisément ce qui l'aurait laissé passer. précisément ce qui l'aurait laissé passer.
---
## Suite du 10/08 au soir — pilote, et le blocage qui reste
### Ce que le pilote a validé
Ingestion réelle sur la Boîte de réception : **25 notes, portée 25/25 correcte**. Le fix D/C est
donc validé au-delà de la lecture — le pipeline classe bien au bon endroit.
### BLOQUANT — `message_id` n'est PAS stable dans le temps
Le prérequis considéré comme « levé par le fix A » ne l'est pas. Lot pilote de 10 dossiers, avec
re-scan volontaire d'un dossier déjà ingéré : **4 notes créées au lieu de 0** (~5 %).
Cause : `message_id` est dérivé des champs normalisés **dont `received_date`**, et la date n'est
pas extraite de façon déterministe d'un passage à l'autre :
| Message | 1er passage | 2e passage |
|---|---|---|
| « Veille marché du 10 Août 2026 » | `2026-08-10` | **`date_inconnue`** |
| « Veille marché du 07 Août 2026 » | **`date_inconnue`** | `2026-08-07` |
| « Veille marché du 09 Juin 2026 » | `2026-06-10` | `2026-06-09` (30 s d'écart, même passage) |
Le fix A a bien supprimé le décalage positionnel dû au glyphe PUA, mais la **reconnaissance de
motif de date** reste non déterministe sur certains rendus OWA (le troisième cas, à un jour
d'écart, sent le fuseau ou la date relative).
**Piste de correctif retenue : sortir `received_date` du calcul du `message_id`.** Fiabiliser le
parsing de date ne ferait que déplacer le problème — un identifiant de déduplication ne doit pas
dépendre du champ le plus fragile de la chaîne. Tant que ce n'est pas fait, le workflow n8n
récurrent ferait gonfler la base à chaque passage.
### Concurrence SQLite — deux pipelines, un seul fichier
Le pilote s'est heurté à des `database is locked`. Deux causes cumulées :
1. **Régression n8n** : `Q6ZAXgd8HYoQbk9K` (auto-sync OneDrive) tournait **toutes les 10 min au
lieu de 2 h depuis le 07/08** — le correctif avait été *enregistré mais jamais publié*, la
version active gardant `minutesInterval: 10` et le paramètre imbriqué parasite. Corrigé en
republiant. Piège déjà listé dans PROTOCOL-INFRA (« une modif écrite n'est pas une modif live »).
2. **Connexion zombie** : le verrou survit à la fin des exécutions et n'a cédé qu'à un
`docker restart` — des fonctions de `mcp_server` ne ferment pas leur connexion sur exception.
Le commentaire du code (« verrou dédié `onedrive_sync_lock` […] aucune raison qu'ils se bloquent
mutuellement ») est **faux au niveau SQLite** : des verrous applicatifs distincts ne changent rien
au fait que les deux pipelines écrivent dans le même fichier, donc se disputent le même verrou.
### Débit mesuré
**~49 s par message** (79 messages en 64 min), dominé par Mimo + embedding. Après ce gros dossier,
`hermes-mail-browser` a renvoyé deux HTTP 503 et 7 dossiers ont échoué en timeout à 300 s. Un
backfill de ~3 500 messages se dimensionne donc **en dizaines d'heures**, et doit être découpé et
espacé plutôt que lancé d'un bloc.
### Divers
`pipeline_lock` contenait 4 lignes violant sa contrainte `CHECK (id = 1)`, ce qui faisait échouer
`PRAGMA integrity_check`. Supprimées → `integrity_check: ok`. **Aucun code du dépôt ne fait
d'`INSERT` sur cette table** (uniquement `UPDATE … WHERE id = 1`) : origine non élucidée, à
surveiller.
État de la base à la clôture : **468 notes / 468 vecteurs, `integrity_check: ok`**, checkpoints
54 `done` / 128 `error_404` / 7 `error` / 5 `error_409` / 10 `pending` / 1 `in_progress`.