Pipeline IA · V2.0 · Step 1

Extraction Schema

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.

CommandeExtract User Data
ÉtapeStep 1
ModèleFable
EntréeEntrées du Journal (nouvelles ou éditées depuis le dernier run)
SortieDonnées Exploitables → écran Données
TaglineTransforme les Entrées en Données Exploitables

Principe

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.

🧭Conventions transverses

Frontière de journée — du réveil au réveil suivant (CONFIRMÉ 06/07)

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.

Conflit entre déclarations — résolution par l'utilisateur

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é) :

Deux informations se contredisent — Heures de sommeil, nuit du 5 au 6 juillet
sam. 6 juil. · 08:12
« Couchée à 21 h, levée à 8 h, matinée tranquille »
sam. 6 juil. · 09:47
« Épuisée, nuit de 5 h à peine »
21 h → 8 h = 11 h au lit, incompatible avec « nuit de 5 h ». La donnée reste Non renseigné tant que le conflit n'est pas résolu.

Format JSON des Données Exploitables (délégué, conçu le 06/07)

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.

🌙Sommeil

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).

KPITypeSollicitéComment obtenu
Heure de coucherheure-horlogematin — si manquantextraite
Heure de réveilheure-horlogematin — si manquantextraite
Heures de sommeildurée (h:mm)matin — si manquantextraite si donnée, sinon réveil − coucher
Réveils nocturnesnombrematin — si manquantextraite
Sommeil réparateurbooléenmatin — toujoursextraite (subjectif)
En vractextenonextraite si présent (« rêves intenses », « ronflements »…)

Rendu dans l'écran Données

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.

🍽️Alimentation

L'occurrence ici = la prise alimentaire (chaque repas/snack = une ligne), avec des agrégats du jour au-dessus.

KPITypeSollicitéComment obtenu
Nombre de repas / journombrenondérivé = nombre de prises déclarées
Heure du dernier repasheure-horlogenondérivé = heure de la dernière prise du jour
Litres d'eau / journombre (L)non — défaut : 3 Lta 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éeta déclaration v3 : auto d'après le contenu
Détail des aliments (par prise)textenontranscrit si donné

Sollicitation Fadi / Didi — par prise

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.

🏃Activité

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…).

KPITypeSollicitéComment obtenu
Séances de sport (transpiration)nombrenon — défauts : 0 / Nondérivé = compte des activités classées « Sport »
Mouvementsbooléendanse, yoga, mouvement qui fait monter le cœur sans transpiration
Étirementsbooléenextraite

Sollicitation

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.

👥Social

KPITypeSollicitéComment obtenu
Vu des gensbooléennon — défaut : Nonextraite

🌡️Climat

Pour l'instant = ta déclaration v3 : météo automatique via localisation. Humidité retirée pour l'instant (06/07).

KPITypeSollicitéComment obtenu
Température ressentieordinal (Chaud | Neutre | Froid)14h — si videta déclaration

🩺Symptômes

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 »).

KPITypeSollicité
Envie de manger entre les repasbooléennon — valeur par défaut : Non (jamais vide)
Faim entre les repasbooléennon — défaut : Non
Fatiguéebooléen19h — si vide
Brain fogbooléennon — défaut : Non
Douleursbooléennon — défaut : Non
Paupières irritéesbooléennon — défaut : Non
Oreilles irritéesbooléennon — défaut : Non
Bouche sèchebooléennon — défaut : Non
Colon irritable le matinbooléennon — défaut : Non

🙂Humeur

KPITypeSollicitéComment obtenu
Humeurétiquette (Bonne | Pas bonne)19h — si videextraite

⚖️Poids

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).

KPITypeSollicitéComment obtenu
Variation de poids (Δ depuis jour 0)nombre (kg, 2 décimales)nonextraite — variation (« perdu 500 grammes » → −0,50) ou chiffre absolu (converti en Δ ; l'absolu n'est jamais affiché)

Rendu dans l'écran Données

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.

📖Règles de vocabulaire d'extraction

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 cibleMot / tournure entenduValeur 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 poidschiffre absolu (ex. « 62,4 kg »)converti en Δ vs jour 0 — l'absolu n'est jamais affiché

Règles générales

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.

Planning des sollicitations

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é.

Les trois niveaux du moteur de sollicitation

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.

Limite structurelle v2

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.