Consigne donnée au modèle pour la commande Extract User Data : lire les Entrées du Journal (texte, audio, image) avec leurs date & heure de saisie, et en ressortir des Données Exploitables structurées, rangées par catégorie.
Le modèle lit chaque Entrée et en extrait des valeurs typées, rangées par catégorie. Chaque catégorie définit des KPI canoniques — les informations attendues à intervalle régulier — plus un espace « en vrac » pour tout ce qui est dit mais ne rentre dans aucun KPI.
La journée J commence à ton réveil du matin J et se termine au réveil suivant. Toute donnée saisie dans cet intervalle appartient à J (l'eau bue à 23 h compte pour J ; la nuit qui suit est rattachée au matin J+1). Repli : si aucun réveil n'est déclaré, la journée est comptée à partir de 4 h du matin.
Quand deux déclarations du même KPI, la même journée, se contredisent (ex. « couchée 21 h, levée 8 h » puis « nuit de 5 h » : 11 h au lit ≠ 5 h déclarées), le moteur ne traite AUCUNE des deux — le KPI reste « Non renseigné » — et dépose une sollicitation de résolution dans l'onglet Journal (section Entrées sollicitées). Elle montre les deux entrées, leur date & heure de saisie, la contradiction en surbrillance, et propose d'éditer une ou les deux entrées. Le prochain Run retraite les entrées éditées et lève le conflit.
Exception : la règle validée « la durée déclarée l'emporte sur la durée calculée (réveil − coucher) » n'est PAS un conflit — c'est une priorité normale (le calcul mesure le temps au lit). Le conflit ne naît que de deux déclarations explicites incompatibles.
Maquette — encart de résolution (design proposé) :
Livrable exact de Extract User Data : le fichier derived_<id>.json. Une seule liste plate de relevés traçables ; la vue « par jour » est recalculée par l'app (déterministe) — on ne stocke jamais deux fois la même vérité.
{
"version": "2.0",
"meta": {
"lastRunAt": "2026-07-06T15:04:00Z", // date du Run (traçabilité)
"model": "claude-fable-5", // modèle réellement utilisé
"processedThrough": 1751790000000 // repère incrémental : entrées créées/éditées après → à retraiter
},
"releves": [
{ "id": "r_0001",
"kpi": "sleep.bedTime", // catégorie.KPI canonique (registre des KPI)
"value": "21:40", // typée selon le KPI : "HH:MM" | nombre | booléen | étiquette
"day": "2026-07-06", // journée d'affectation (frontière réveil→réveil)
"entryId": "e_123", // traçabilité boîte de verre
"quote": "couchée vers 21h40", // extrait exact du texte source
"confidence": 0.95 }
],
"vrac": [ // ce qui ne rentre dans aucun KPI
{ "id": "r_0002", "category": "sleep", "text": "rêves intenses",
"day": "2026-07-06", "entryId": "e_123", "quote": "des rêves intenses toute la nuit" }
],
"conflicts": [ // déclarations contradictoires → sollicitation de résolution
{ "kpi": "sleep.duration", "day": "2026-07-06",
"releveIds": ["r_0010", "r_0011"], "status": "pending" } // pending | resolved
],
"unusable": ["e_456"] // entrées photo/audio inexploitables, exclues des analyses
}
Notes : les KPI à valeur par défaut (ex. « Envie de manger entre les repas » = Non) ne génèrent pas de relevé — le défaut est appliqué par l'app à la lecture. Le Poids est stocké en Δ (jamais l'absolu). Les relevés impliqués dans un conflict pending sont ignorés par le Récap et les corrélations.
Photos & audio (09/07/2026) : les entrées peuvent porter une photo (scan, résultat d'analyse, assiette…) et/ou une note audio enregistrée dans l'app. Le Run les lit dans la mesure du possible : ce qui est extractible devient des relevés normaux (mêmes règles de KPI, quote = description de la source, ex. « [photo] tension 12/8 » ou transcription de l'audio). Si le média n'est pas exploitable (illisible, hors sujet, inaudible), l'id de l'entrée est ajouté à la liste unusable — le Journal affiche alors sur l'entrée « Donnée inexploitable, exclue des analyses » après le Run.
Cinq KPI attendus chaque nuit, plus les infos en vrac. Une nuit est rattachée au matin où elle se termine (clé = date du réveil).
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Heure de coucher | heure-horloge | matin — si manquant | extraite |
| Heure de réveil | heure-horloge | matin — si manquant | extraite |
| Heures de sommeil | durée (h:mm) | matin — si manquant | extraite si donnée, sinon réveil − coucher |
| Réveils nocturnes | nombre | matin — si manquant | extraite |
| Sommeil réparateur | booléen | matin — toujours | extraite (subjectif) |
| En vrac | texte | non | extraite si présent (« rêves intenses », « ronflements »…) |
La partie Sommeil affiche toujours les cinq lignes, avec la valeur du jour ou un « — » quand elle manque (le manque est visible = signal de complétude). Les infos « en vrac » sont listées en dessous.
L'occurrence ici = la prise alimentaire (chaque repas/snack = une ligne), avec des agrégats du jour au-dessus.
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Nombre de repas / jour | nombre | non | dérivé = nombre de prises déclarées |
| Heure du dernier repas | heure-horloge | non | dérivé = heure de la dernière prise du jour |
| Litres d'eau / jour | nombre (L) | non — défaut : 3 L | ta déclaration en fin de journée (non cumulé) ; sinon défaut 3 L |
| Fadi / Didi (par prise) | étiquette (Fadi | Didi) | oui — par prise non qualifiée | ta déclaration v3 : auto d'après le contenu |
| Détail des aliments (par prise) | texte | non | transcrit si donné |
Si une prise est loguée sans être qualifiée, la question « Fadi ou Didi ? » se pose pour cette prise précise et disparaît dès qu'elle est qualifiée.
Le modèle lit ta description et décide si l'activité compte comme Sport (avec transpiration) ou Mouvements (cœur qui monte sans transpirer : danse, yoga…).
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Séances de sport (transpiration) | nombre | non — défauts : 0 / Non | dérivé = compte des activités classées « Sport » |
| Mouvements | booléen | danse, yoga, mouvement qui fait monter le cœur sans transpiration | |
| Étirements | booléen | extraite |
MAJ 07/07 : plus de sollicitation — valeurs par défaut (Sport 0 · Mouvements Non · Étirements Non) : sans mention dans la journée, ces valeurs sont posées d'office.
Pour l'instant = ta déclaration v3 : météo automatique via localisation. Humidité retirée pour l'instant (06/07).
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Température ressentie | ordinal (Chaud | Neutre | Froid) | 14h — si vide | ta déclaration |
Tous en oui / non, du jour. Chaque symptôme = une sollicitation distincte, qui ne disparaît qu'une fois renseignée. Défaut = « Non renseigné » — jamais de « non » implicite. Synonymes déclarés : un booléen peut porter un vocabulaire qui mappe des mots vers oui/non — ex. Faim entre les repas : « faim » → oui · « pas faim », « satiété » → non (registre complet : § Vocabulaire). Valeur par défaut : un KPI peut en déclarer une (registre User Beliefs ; NA = aucune) — ex. « Envie de manger entre les repas » = Non par défaut. Absorbe l'ex-Énergie (« Fatiguée »), l'ex-Douleur (« Douleurs ») et l'ex-Brouillard mental (« Brain fog »).
| KPI | Type | Sollicité |
|---|---|---|
| Envie de manger entre les repas | booléen | non — valeur par défaut : Non (jamais vide) |
| Faim entre les repas | booléen | non — défaut : Non |
| Fatiguée | booléen | 19h — si vide |
| Brain fog | booléen | non — défaut : Non |
| Douleurs | booléen | non — défaut : Non |
| Paupières irritées | booléen | non — défaut : Non |
| Oreilles irritées | booléen | non — défaut : Non |
| Bouche sèche | booléen | non — défaut : Non |
| Colon irritable le matin | booléen | non — défaut : Non |
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Humeur | étiquette (Bonne | Pas bonne) | 19h — si vide | extraite |
Nouvelle catégorie v2. Discrétion : seules les variations depuis le jour 0 sont stockées et affichées (jamais de chiffre absolu à l'écran).
| KPI | Type | Sollicité | Comment obtenu |
|---|---|---|---|
| Variation de poids (Δ depuis jour 0) | nombre (kg, 2 décimales) | non | extraite — variation (« perdu 500 grammes » → −0,50) ou chiffre absolu (converti en Δ ; l'absolu n'est jamais affiché) |
Absent du Récap. Affiché en dernier dans la liste de l'onglet Données, en Δ cumulé (2 décimales, ex. −1,20 kg). Jour 0 = première déclaration = 0,00.
Registre des mappings mots → valeur typée que le modèle applique à chaque Run. Un KPI (booléen ou autre) peut porter des synonymes déclarés ; cette liste est injectée dans la consigne de chaque Extract User Data et s'enrichit au fil des validations (source des croyances : User Beliefs).
| KPI cible | Mot / tournure entendu | Valeur enregistrée |
|---|---|---|
| Faim entre les repas | « faim » | oui |
| Faim entre les repas | « pas faim » · « satiété » | non (la négation est un état réel, pas un mot ignoré) |
| Bouche sèche | « soif » · « soif intense » | oui |
| Fadi / Didi (par prise) | « fadi » (= facile à digérer) · « didi » (= difficile à digérer) | étiquette de la prise correspondante |
| Variation de poids | « perdu 500 grammes » | Δ −0,50 kg |
| Variation de poids | chiffre absolu (ex. « 62,4 kg ») | converti en Δ vs jour 0 — l'absolu n'est jamais affiché |
Mot-entier et contexte : un synonyme ne vaut que pour son KPI cible, dans son contexte (« pas faim » ne touche pas « Envie de manger entre les repas »).
Additif : toute nouvelle règle validée en curation s'ajoute ici — elle est rétroactive au prochain Run (les Runs relisent les entrées éditées) et ne supprime jamais une règle existante sans décision explicite.
Une sollicitation est posée tant que l'info est vide et disparaît une fois renseignée ; elle persiste tant qu'on est dans la journée, puis le trou reste visible dans Données sans être re-posé.
Vision : il n'y a pas de problème de données manquantes — l'outil demande à l'utilisateur les données clés dont il a besoin. La sollicitation n'est pas un questionnaire fixe : elle est pilotée par le moteur d'analyse. Trois niveaux, tous en v2.
Run All Correlations, le moteur sait ce qui lui manque (paires « données insuffisantes », règles candidates bloquées à petit n, facteurs dont les trous coûtent le plus d'analyses). Il produit, en plus de la base de corrélations, une liste de besoins : fichier data-needs_<id>.json, lu par l'app, affiché comme sollicitations priorisées par valeur d'information (ex. « il manque surtout Climat — 7 trous sur 14 j — ça bloque 12 analyses »).Les Runs étant manuels, la liste des besoins (niveaux 2 et 3) ne se rafraîchit qu'à chaque Run ; entre deux Runs, l'app applique la dernière liste connue. Acceptable pour un MVP — disparaîtra quand le moteur sera branché en ligne.
👥Social