lifeOS en mode Pet
Plus qu'un animal de compagnie virtuel, mais les début dune AI globale au raisonnement flou pour m'accompagner au quotidien.
lifeOS-pet — Synthèse du projet
version: 1.0.0
"L'AI doit m'aider à faire les meilleurs choix, pas essayer de m'influencer."
— Postulat fondateur, Laurent
1. Vision en une phrase
Un système personnel qui capte tous les signaux de l'environnement numérique de Laurent (produits par lui, reçus de l'extérieur, contextuels passifs), les archive intelligemment, les score dynamiquement selon le contexte du moment, et délivre des synthèses utiles à la demande — sans empilement de notifications.
2. La thèse centrale
L'importance d'un signal n'est pas une propriété intrinsèque du signal, c'est une fonction du temps et du contexte qui l'entoure.
Une paire de chaussettes chauve-souris commandée début octobre vaut un score d'attention de 2/10. Le 12 octobre, quand un RDV Halloween apparaît dans le calendrier pour le 20 octobre, son score saute à 8/10 — non parce que la chaussette a changé, mais parce que le graphe de relations dans lequel elle vit a changé.
Conséquence directe : le scoring n'est jamais figé, il vit avec le quotidien. Le système est un graphe dont les nœuds sont stables mais les arêtes sont vivantes.
3. Les trois flux distincts
| Flux | Définition | Exemples | Traitement |
|---|---|---|---|
| Produit | Résulte d'une intention + un effort | Note, journal alimentaire, toot, commentaire YouTube réfléchi, achat consécutif à plusieurs recherches | Archive permanente, indexée, jamais purgée |
| Reçu | Vient de l'extérieur sans intention de Laurent | Mail Amazon, notif Netflix, recommandation Music, promo | Archive 6 mois glissants, sert au scoring contextuel |
| Contextuel | Données passives du quotidien | Météo, GPS, sommeil, scrobbles musique, agenda | Enrichit les deux premiers, TTL court (7-30j) |
Note : un même item peut changer de catégorie. Une wishlist devient "produit" si elle est suivie d'un achat. Un like sur YouTube reste "reçu" tant qu'il n'est pas accompagné d'un commentaire.
4. Architecture en trois couches
L'analogie qui structure tout le système : un système digestif.
Couche 1 — Bouche (capture brute)
Tout avaler, ne rien mâcher. Stockage tel quel dans inbox_raw avec timestamp, source, payload JSON. Aucune décision à ce stade.
Sources de capture identifiées :
- Mail (IMAP, parser dédié par expéditeur)
- Calendrier (CalDAV / EventKit)
- Notifs macOS (lecture de ~/Library/Group Containers/group.com.apple.usernoted/db2/db, démon Mac avec Full Disk Access, poller toutes les 2-5 min)
- Notes Apple (déjà branché via lifeOS-notes)
- Last.fm scrobbles (déjà branché)
- OwnTracks GPS (déjà branché)
- Health (Apple Health export ou app dédiée)
- Web (commentaires, toots, achats — via APIs ou scraping personnel)
- Journal alimentaire (DB du site existant)
Couche 2 — Estomac (parsing + classification + archivage)
Worker local sur Pi5 qui passe sur inbox_raw et :
1. Parse : extraction structurée selon la source (regex pour Amazon, LLM local pour notes, etc.)
2. Classifie dans une des trois catégories (produit / reçu / contextuel)
3. Tag : entités, catégorie sémantique, intention apparente
4. Score initial : base_importance 0-10
5. Bascule : devient un signal durable, alimente pending_actions si futur, ambient_signals si bruit
Modèles utilisés :
- Règles déterministes pour les sources structurées (mails templated, transactions bancaires)
- LLM local (Llama 3.1 8B ou Qwen 2.5 7B via Ollama, sur Pi5 ou Mac) pour les sources non structurées
- Pas de Claude API ici — coût prohibitif pour du parsing fil-de-l'eau
Couche 3 — Cerveau (synthèse à la demande)
Endpoint Flask sur Pi5 qui :
- Reçoit une question (manuelle via pet, ou auto pour digest matinal)
- Pioche dans les trois tables avec une fenêtre temporelle pertinente
- Construit un contexte
- Appelle Claude Sonnet (ou Opus pour graph reasoning lourd)
- Retourne la synthèse en streaming
Pas de notifs poussées par défaut. Le système est en pull, sauf cas critiques (santé, fenêtre temporelle critique).
5. Le scoring contextuel — cœur intellectuel du système
Deux jobs distincts à séparer
Job A — Parsing & tagging : LOCAL, fil de l'eau, coût quasi nul.
Job B — Scoring contextuel & graph reasoning : CLOUD (Claude API), batch nocturne sur les deltas, coût borné.
Principe de réactivité
On ne re-score pas tout en permanence. On re-score quand un événement déclencheur apparaît :
- Nouveau RDV calendrier → re-score les items pending dans la fenêtre temporelle
- Nouveau mail de livraison → re-score juste cet item et ses voisins de graphe
- Nouveau signal de manque répété → boost du score correspondant
Multiplication, pas addition
Un signal qui se répète sans résolution voit son score multiplié, pas additionné. 3 oublis ≠ score×3 ; 3 oublis = score×N où N croît, parce que l'absence de résolution est elle-même un signal négatif.
Le graphe émergent
Table signal_links où le worker écrit les relations détectées :
- temporal_proximity : deux signaux proches dans le temps
- semantic_match : deux signaux qui parlent du même sujet
- causal_likely : raisonnement Claude qui infère une relation causale
Le scoring devient alors : "ce signal a-t-il des voisins importants ?" plutôt que "ce signal est-il important ?". Beaucoup plus facile à raisonner pour un LLM.
6. Le pet — interface utilisateur
Deux modes
- Push quotidien : digest matinal préparé pendant la nuit. Signaux forts + tendances. Type "tu perds du poids et tu es fatigué, regarde tes apports en X."
- Pull contextuel : clic sur le pet → quelques secondes de patience explicite → synthèse situationnelle fraîche. Type "il te reste un épisode de Doctor Who à voir, tu commences tôt demain, un thé et au lit."
Auto-observation
Chaque clic sur le pet est lui-même un signal qui rentre dans inbox_raw avec son contexte (heure, état du moment). Le système s'observe pour mieux comprendre Laurent.
Mode prudence vs mode agressif
Démarrage en mode conservateur : le système propose, Laurent valide. Au fil des semaines, les catégories sans erreur basculent en mode agressif (action silencieuse avec undo 1h). Catégorie par catégorie.
7. La règle Rappels iOS — hybride asymétrique
Le pet est la source de vérité. Rappels est un miroir en lecture-écriture restreinte.
| Action | Effet |
|---|---|
| Pet crée pending_action confirmée | Pousse vers Rappels via EventKit |
| Laurent coche dans Rappels | Remonte au pet → résolution propagée |
| Laurent modifie dans Rappels (texte, trigger) | Ne remonte pas au pet |
| Laurent ajoute directement dans Rappels | Le pet ignore, c'est sa vie |
Liste Rappels dédiée Pet. Le démon ne touche jamais aux autres listes.
Voie technique retenue : EventKit (démon Swift sur Mac) plutôt que CalDAV iCloud, parce que les triggers géofencés sont au cœur du besoin et qu'EventKit les gère correctement.
8. La résolution magique (objectif v2)
Si Laurent achète le pain de mie au supermarché, le mail bancaire arrive le soir avec un débit Carrefour. Le worker parse → détecte achat alimentaire → match avec une pending_action shopping non-résolue dans la fenêtre temporelle → résolution silencieuse, le rappel disparaît automatiquement de l'iPhone.
Laurent n'a rien fait. C'est ce qui fait passer le système d'utile à magique.
Demande un parser bancaire fiable et de la logique de matching flou. Objectif v2, pas v1.
9. Phase transitoire vs cible long terme
| Composant | Phase transitoire | Cible long terme |
|---|---|---|
| Parsing local | Ollama sur Mac (mutualisé avec autre projets) | LLM dédié sur Pi5 |
| Scoring contextuel | Claude API (Sonnet, batch nocturne, ~30€/mois borné) | LLM local plus puissant quand le hardware le permettra |
| Stockage | MariaDB sur Pi4 (déjà en place) | Identique, monitoring + index optimisés |
| Démon Mac | Indispensable pour notifs + EventKit | Indispensable, c'est intrinsèque à macOS |
10. Principes de design non-négociables
- Capture exhaustive, intelligence paresseuse. L'archive est bête et complète, l'intelligence est à la demande.
- Silence par défaut. Pas de notif sauf demande explicite ou cas critique (santé, fenêtre temporelle).
- Friction à l'enlèvement, pas à l'ajout. Une suggestion auto qu'on retire est mieux qu'une question polie qu'on doit valider 50 fois par jour.
- Source de vérité unique. Pour chaque type de donnée, un seul endroit fait foi (ex: pet pour pending_actions, agenda pour événements).
- Le brut est compressible en sémantique. Mail Amazon de 50 Ko → fiche order de 200 octets. La purge du brut ne perd rien d'essentiel.
- Réactivité événementielle. Pas de re-scan complet, des updates ciblés au déclenchement.
- Auto-observabilité. Chaque action du système (et chaque clic du pet) est un signal qui retourne dans le système.
11. Ce qu'on ne fera JAMAIS
- Pousser des recommandations non sollicitées de produits / contenus.
- Faire la morale (équilibre des repas, durée d'écran, etc.).
- Notifier la résolution d'une action (silence sur les non-événements).
- Re-poser une question déjà tranchée.
- Empiler des notifs : si plusieurs choses émergent simultanément, on les agrège en une seule synthèse au prochain pull.
- Stocker des données chez des tiers de manière persistante. L'API Claude voit les données le temps du call, c'est tout.
12. Glossaire des termes du projet
- Signal : item parsé et structuré dans la table
signals. - Pending action : signal qui a une dimension future et mérite suivi.
- Ambient signal : bruit ambiant à TTL court, rarement utile seul.
- Score contextuel : score dynamique calculé en fonction du graphe de relations.
- Trigger composé : ensemble de conditions multi-critères (lieu + heure + jour + résolution).
- Résolution silencieuse : fermeture d'une pending_action sans notification.
- Repeat count : nombre de fois où un signal similaire a émergé sans résolution.
- Démon Mac : process Swift qui tourne sur le Mac pour notifs SQLite + EventKit.
- Pet : application client qui interroge le système (menu bar Mac + éventuellement iOS).
Document préparé en mai 2026 pour reprise après livraison des capteurs ESP32.
Resources
-
lifeOS-pet_cdc.md
18 KB
-
lifeOS-pet_cdc.pdf
331 KB