Gmail Phase E/F + HANDOFF global + cleanup cron/root
- Réécriture HANDOFF.md dashboard multi-domaines - Mise à jour MEMORY.md / TOOLS.md / AGENTS.md - Cleanup fichiers cron obsolètes + fichiers root - Gmail Phase E : audit, 18 filtres natifs, labels Promos/Dev-Tools/Social - Gmail Phase F : archive Philippot + Ulys terminée
This commit is contained in:
328
handoffs/HANDOFF-2026-06-09-GMAIL.md
Normal file
328
handoffs/HANDOFF-2026-06-09-GMAIL.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# Handoff — OpenClaw / Gmail Housekeeping
|
||||
|
||||
> _Document de reprise pour une nouvelle session (humain ou agent IA)._
|
||||
> _Dernière mise à jour : 9 juin 2026._
|
||||
> _Mainteneur : Thierry Tallagrand._
|
||||
|
||||
---
|
||||
|
||||
## 🎯 TL;DR (à lire en premier)
|
||||
|
||||
Le projet **OpenClaw** est un orchestrateur multi-agents tournant sur Synology NAS
|
||||
(ARCHIVE3) qui pilote des comptes Google de Thierry via gateway gog.
|
||||
|
||||
**État actuel** : **Phase D Gmail housekeeping ✅ TERMINÉE** le 6 juin 2026.
|
||||
12 401 mails trashés en 6 vagues. Boîte 12 703 → ~4 600.
|
||||
|
||||
**Prochaines phases prévues** :
|
||||
- Phase E : filtres Gmail natifs (auto-trash à l'arrivée)
|
||||
- Phase F : Vague 2 (archive Philippot + Ulys + labels)
|
||||
- Phase G : 2ème passe Q8 (longue traîne newsletters tech)
|
||||
- Phase H : digest VE (parsing Jeep uconnect)
|
||||
|
||||
---
|
||||
|
||||
## ⏰ Dates critiques
|
||||
Date Événement Action
|
||||
6 juillet 2026 Auto-purge Gmail Trash (30j) des mails Phase D Restaurer AVANT cette date si erreur
|
||||
12 juin 2026 Token OAuth gmail.modify expire (Testing GCP, 7j) gog auth add --gmail-scope=full --manual --force-consent
|
||||
9 juin 2026 Aujourd'hui — reprise après pause Vérifier gmail-doubts.md si existant
|
||||
|
||||
Export as CSV
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
### Hôte
|
||||
- Synology ARCHIVE3 (DSM, hostname `ARCHIVE3`)
|
||||
- Filesystem : `/volume1/docker/openclaw-data/workspace/`
|
||||
- User : 1000:1000 (Thierry)
|
||||
- TZ : Europe/Paris
|
||||
|
||||
### Containers Docker
|
||||
- openclaw-gateway (daemon principal, expose gog CLI)
|
||||
- openclaw-cli, openclaw-plugins, openclaw-dockerproxy
|
||||
- gitea (versioning local), openvpn2 (VPN)
|
||||
|
||||
### Compte Google authentifié
|
||||
- Email : tallagrand.thierry@gmail.com
|
||||
- Project GCP : 666305633659 (test users mode = refresh tokens 7j)
|
||||
- Scopes : gmail.modify + gmail.settings.basic + gmail.settings.sharing + userinfo.email + openid
|
||||
- Token expire : **12 juin 2026**
|
||||
|
||||
### Infrastructure mail historique (3 NAS Synology)
|
||||
- ARCHIVE → `[10.10.10.50]` (originel, IP locale)
|
||||
- ARCHIVE2 → `[www.airtria.net]`
|
||||
- ARCHIVE3 → `[www.airtria.pro]` (NAS actuel)
|
||||
|
||||
---
|
||||
|
||||
## 📂 Fichiers clés
|
||||
Fichier Rôle
|
||||
workspace/AGENTS.md Rules globales (NEVER/ALWAYS Gmail+WhatsApp, Heartbeats)
|
||||
workspace/MEMORY.md Mémoire persistante session par session
|
||||
workspace/gmail-audit.md Audit initial 3000 threads (Phase B)
|
||||
workspace/gmail-rules.md Règles trash/archive/whitelist (Phase C, source de vérité)
|
||||
workspace/gmail-housekeeping.md Log append-only actions Gmail (Phase D)
|
||||
workspace/handoff.md Ce fichier
|
||||
workspace/scripts/gmail_trash_v1.sh Vague 1 (>1y)
|
||||
workspace/scripts/gmail_trash_v1_6m.sh Vague 1bis (6m→1y)
|
||||
workspace/scripts/gmail_trash_v1ter.sh Vague 1ter (30j→6m)
|
||||
workspace/scripts/gmail_trash_v1quinquies.sh Vague 1quinquies (7j→30j) + 4 nouvelles règles
|
||||
workspace/scripts/gmail_trash_synology.sh Synology .net
|
||||
workspace/scripts/gmail_trash_synology_all.sh Synology .pro + IP10 + .net
|
||||
|
||||
Export as CSV
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 📊 Bilan Phase D (5-6 juin 2026)
|
||||
Vague Filtre temporel Trashed
|
||||
Vague 1 older_than:1y 5 335
|
||||
Vague 1bis 6m → 1y 1 647
|
||||
Vague 1ter 30j → 6m 1 871
|
||||
Synology .net toutes périodes 1 160
|
||||
Synology .pro+IP10 toutes périodes 2 099
|
||||
Vague 1quinquies 7j → 30j 289
|
||||
TOTAL 12 401
|
||||
|
||||
Export as CSV
|
||||
|
||||
|
||||
Boîte 12 703 → ~4 600 (-64%). Hits rate-limit : 0.
|
||||
|
||||
### Top performers
|
||||
- LinkedIn (3 règles) : 3 502+
|
||||
- Synology auto-notifs (3 variants) : 4 419
|
||||
- Quora : 1 436+
|
||||
- AliExpress : 469
|
||||
- TAAFT : 418
|
||||
- Rustica : 351
|
||||
- Facebook : 365
|
||||
- Cdiscount : 276
|
||||
- Carrefour : 257
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Whitelist absolue (NE JAMAIS toucher)
|
||||
|
||||
Source de vérité : gmail-rules.md.
|
||||
|
||||
### Banques
|
||||
@cic.fr, @e-cic.fr, @bpgo.fr, @cmb.fr
|
||||
|
||||
### Admin & légal
|
||||
@impots.gouv.fr, @dgfip.finances.gouv.fr, @digiposte.fr, @ameli.fr
|
||||
|
||||
### Telco perso
|
||||
@orange.com, @orange.fr, @neuf.fr
|
||||
|
||||
### Véhicules
|
||||
@vwfs.com, @volkswagen.fr, @jeep.com (cf. règle V01 digest VE),
|
||||
@ze-watt.fr/.com, @zeromotorcycles.com, r.clientele@vwfs.com
|
||||
|
||||
### Plongée
|
||||
@gissacg.fr, @lists.gissacg.fr, president@gissacg.fr, @arimair.fr
|
||||
|
||||
### AIRTRIA
|
||||
@airtria.net, @airtria.fr, @laboutique-solaire-pro.com
|
||||
|
||||
### Identités personnelles
|
||||
tallagrand.thierry@gmail.com, thierry.tallagrand@me.com,
|
||||
Frederic Tallagrand (famille)
|
||||
|
||||
### Synology infrastructure (CRITIQUE — alertes opérationnelles)
|
||||
- sns@synologynotification.com (Active Insight - alertes disque/storage)
|
||||
- noreply@c2.synology.com (C2 backup subscription)
|
||||
|
||||
### Finance
|
||||
- noreply@amundi-esr.com (épargne salariale PEE/PERCO)
|
||||
|
||||
### Labels système Gmail protégés
|
||||
IMPORTANT, STARRED, SENT, DRAFT, Personal, Travail, Achats, Receipts, Notes
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Hard constraints opérationnels
|
||||
|
||||
### NEVER
|
||||
1. messages.delete permanent (toujours messages.trash)
|
||||
2. Toucher la whitelist (abort silencieux si match)
|
||||
3. >200 actions par batch Gmail (en pratique 300 OK)
|
||||
4. >2000 actions par jour sans confirmation humaine
|
||||
5. Modifier labels système (INBOX retirable mais pas SENT/DRAFT/IMPORTANT)
|
||||
6. Lancer une vague sans dry-run préalable validé
|
||||
|
||||
### ALWAYS
|
||||
1. Dry-run obligatoire avant toute action en masse
|
||||
2. Logger chaque batch dans gmail-housekeeping.md
|
||||
3. Respecter gmail-rules.md comme source de vérité unique
|
||||
4. Vérifier la whitelist au runtime (pas seulement au design)
|
||||
5. Pause 5s entre 2 batchs gog gmail trash/archive
|
||||
6. En cas de doute : laisser dans inbox + log dans gmail-doubts.md
|
||||
|
||||
### Limites runtime utilisées (Phase D)
|
||||
- maxBatchSize: 300
|
||||
- pauseBetweenBatchesMs: 5000
|
||||
- Détection auto rate-limit 403 + retry 60s
|
||||
- Hits rate-limit observés : 0 sur 12 401 actions
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Patterns gog éprouvés
|
||||
|
||||
Recherche read-only :
|
||||
sudo docker exec openclaw-gateway gog gmail search "QUERY" -a tallagrand.thierry@gmail.com --max 500 -j
|
||||
|
||||
Trash avec query + cap :
|
||||
sudo docker exec openclaw-gateway gog gmail trash -a tallagrand.thierry@gmail.com --query "QUERY" --max 300 --force
|
||||
|
||||
Re-auth OAuth :
|
||||
sudo docker exec openclaw-gateway gog auth remove tallagrand.thierry@gmail.com
|
||||
sudo docker exec -it openclaw-gateway gog auth add tallagrand.thierry@gmail.com --services=gmail --gmail-scope=full --manual --force-consent
|
||||
|
||||
Vérification auth :
|
||||
sudo docker exec openclaw-gateway gog auth list
|
||||
sudo docker exec openclaw-gateway gog gmail labels list -a tallagrand.thierry@gmail.com
|
||||
|
||||
---
|
||||
|
||||
## 🟣 Cas spécial — Jeep uconnect (digest VE)
|
||||
|
||||
from:uconnectservices@jeep.com (~400 mails) :
|
||||
- Phase D : aucune action (laissés en inbox)
|
||||
- Phase H : agent quotidien parse les mails, génère charge-vehicule.md + notif WhatsApp synthèse, archive auto avec label Charge-VE
|
||||
|
||||
---
|
||||
|
||||
## 🟡 Phase F (Vague 2 — à faire)
|
||||
|
||||
Archive + label, pas de destruction :
|
||||
ID Source Action Volume estimé
|
||||
V2.01 florian.philippot@les-patriotes.fr Archive + label Newsletters ~30
|
||||
V2.02 info@clients.ulys.com Archive + label Receipts ~50
|
||||
|
||||
Export as CSV
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🔵 Phase E (filtres Gmail natifs — à faire)
|
||||
|
||||
Objectif : plus jamais d'accumulation. Filtres Gmail qui trashent automatiquement les mails matchant nos 23 règles V1 dès l'arrivée.
|
||||
|
||||
Approches possibles :
|
||||
1. gog filters create (à explorer via gog gmail filters --help)
|
||||
2. Gmail API directe : users.settings.filters.create (Python)
|
||||
3. Gmail UI web : 23 clics manuels (lent mais sûr)
|
||||
|
||||
Pré-requis : Phase D doit avoir tourné 30 jours sans regret.
|
||||
|
||||
---
|
||||
|
||||
## 🟠 Phase G (2ème passe Q8 — longue traîne)
|
||||
|
||||
Identifier expéditeurs hors top 30 actuels (Medium, Substack, Frandroid, dev.to, mailchimp génériques).
|
||||
|
||||
Audit longue traîne :
|
||||
sudo docker exec openclaw-gateway gog gmail search "category:promotions OR category:updates older_than:6m" -a tallagrand.thierry@gmail.com --max 5000 -j > /tmp/longue-traine.json
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Quirks / pièges connus
|
||||
|
||||
### Horloge système
|
||||
Le serveur expose un current_time parfois bloqué ou avec coquille UTCUTC.
|
||||
Source de vérité = horloge système host (date sur ARCHIVE3) ou contexte conversationnel.
|
||||
|
||||
### Bug KeyError 'subject' dans gog gmail search
|
||||
Certains threads n'ont pas de subject. Toujours utiliser t.get('subject', '').
|
||||
|
||||
### from:me ne fonctionne pas dans gog
|
||||
Utiliser l'email complet à la place.
|
||||
|
||||
### Compteurs Gmail web vs API
|
||||
- Compteur "Boîte de réception" gauche = fiable
|
||||
- Compteur "1-50 sur N" en haut = inclut SENT en vue Principale
|
||||
- Compteurs catégories (Promotions/Notifications/etc.) = INCLUENT TRASH, jamais représentatifs.
|
||||
|
||||
### Dry-run gog gmail trash
|
||||
Le --dry-run ne pré-fetch PAS les message_ids. Pour validation, faire un gog gmail search séparé avec la même query.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Checklist de reprise (pour nouvelle session)
|
||||
|
||||
[ ] Vérifier date système : date sur ARCHIVE3
|
||||
[ ] Vérifier état token : gog auth list (si expire <24h, relancer flow OAuth)
|
||||
[ ] Lire gmail-housekeeping.md (dernières actions)
|
||||
[ ] Lire MEMORY.md (état général)
|
||||
[ ] Vérifier gmail-doubts.md (mails à relire)
|
||||
[ ] Vérifier inbox count : gog gmail search "in:inbox" --max=1 -j
|
||||
[ ] Décider phase suivante : E, F, G ou H
|
||||
[ ] Si action destructive → dry-run d'abord, valider, puis exécuter
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Liens / refs
|
||||
|
||||
- gog CLI : gog gmail {search|trash|archive|labels} --help
|
||||
- Gmail search syntax : https://support.google.com/mail/answer/7190
|
||||
- Gmail API quotas : https://developers.google.com/gmail/api/reference/quota
|
||||
- GCP project : 666305633659 (mode Testing, refresh 7j)
|
||||
|
||||
---
|
||||
## 10 juin 2026 ~01:00-01:35 UTC+2 — Auth Gmail re-faite + persistance
|
||||
|
||||
### Contexte
|
||||
Token OAuth expirant 12/6/2026. Découverte que le keyring vivait dans
|
||||
/home/node/.local/share/gogcli/ (couche writable container) = perdu à chaque
|
||||
compose down/up.
|
||||
|
||||
### Actions
|
||||
- Re-auth gog complète via `gog auth add tallagrand.thierry@gmail.com
|
||||
--services=gmail --manual --gmail-scope=full --force-consent`
|
||||
- Ajout de GOG_HOME=/home/node/.openclaw/gogcli dans compose.yaml (env)
|
||||
- Migration credentials.json + keyring/ vers gogcli/data/
|
||||
- Permissions 1000:1000, files 600, dirs 700
|
||||
- Test ULTIME compose down+up : auth survit ✅
|
||||
|
||||
### Garanties acquises
|
||||
- Refresh token persisté dans /volume1/docker/openclaw-data/gogcli/data/keyring/
|
||||
- Survit aux compose restart, stop+start, down+up, --force-recreate
|
||||
- GOG_KEYRING_PASSWORD doit rester identique (sinon keyring illisible)
|
||||
|
||||
### TODO
|
||||
- Investiguer config.path warning (non critique, gog créera /gogcli/config/
|
||||
à la prochaine écriture config)
|
||||
- Mettre à jour scripts/generate_gmail_token.sh (référence à `gog auth
|
||||
generate-token` qui n'existe pas — la vraie commande est `gog auth add ... --manual`)
|
||||
- Référencer la nouvelle syntaxe gog dans MEMORY.md (procédure compacte
|
||||
~1100 chars proposée plus haut, à appliquer une fois reposé)
|
||||
|
||||
## ✅ Validation finale 10 juin 2026 ~02:13-02:18 UTC+2
|
||||
|
||||
Test fonctionnel complet via WhatsApp DM (session fraîche post-/new) :
|
||||
|
||||
### Questions/réponses
|
||||
| Question | Comportement | Latence |
|
||||
|---|---|---|
|
||||
| "Combien de mails aujourd'hui ?" | 1 appel gog gmail search → "2 messages" | ~1min |
|
||||
| "et hier ?" | Réutilise contexte + 1 appel | ~5s |
|
||||
| "donne la liste" | Format structuré avec dates + étiquettes | ~30s |
|
||||
| "et liste des mails de lundi" | Recherche multi-jours, format détaillé | ~1min |
|
||||
|
||||
### Test dashboard
|
||||
"fait un classement par catégorie des mails depuis le 1juin 2026 et le 10 juin 2026"
|
||||
→ Réponse multi-section (Newsletters/Actualités/Réseaux/Personnel/Systèmes/Autres)
|
||||
→ Classification sémantique propre, ~30 mails listés
|
||||
→ Aucune boucle, aucune saturation
|
||||
|
||||
### Conclusion
|
||||
- Phase D bilan classement Gmail : **PHASE LECTURE COMPLÈTEMENT OPÉRATIONNELLE**
|
||||
- Phase E (mutations en masse) : prête à être lancée, syntaxe validée par l'agent
|
||||
- Aucune intervention manuelle nécessaire pour les questions Gmail standard
|
||||
|
||||
552
handoffs/HANDOFF-2026-06-09.md
Normal file
552
handoffs/HANDOFF-2026-06-09.md
Normal file
@@ -0,0 +1,552 @@
|
||||
# HANDOFF — OpenClaw + Qwen3-VL Production
|
||||
**Dernière mise à jour : 2026-06-09 ~17:45 UTC+2** (post-debug session WhatsApp DM stalled)
|
||||
|
||||
> Document de transition entre sessions de production. À lire en premier dans toute
|
||||
> nouvelle session de travail. Stocké hors workspace pour ne pas polluer le bootstrap.
|
||||
|
||||
---
|
||||
|
||||
## 1. Stack actuelle (état stable)
|
||||
|
||||
### Infrastructure
|
||||
- **DGX Spark (10.10.10.8)** : vLLM Qwen3-VL-30B-A3B-Instruct-FP8 sur port 8000, Watchtower DÉSACTIVÉ
|
||||
- **NAS ARCHIVE3 (192.168.144.2)** : OpenClaw 2026.6.1 sur port 18789, image `openclaw-custom:latest` (build local)
|
||||
- **NAS ARCHIVE2** : sandbox stoppée, en attente
|
||||
|
||||
### OpenClaw (ARCHIVE3)
|
||||
- Compose : `/volume1/docker/openclaw/compose.yaml`
|
||||
- Volume bind : `/volume1/docker/openclaw-data` → `/home/node/.openclaw` (container)
|
||||
- Container WORKDIR : `/app` (le `dist/index.js` est à `/app/dist/index.js`)
|
||||
- Dashboard : http://192.168.144.2:18789/ (paired, 2 devices)
|
||||
- Container uid : `1000:1000` (`node`) — **tout fichier écrit en root sera invisible côté agent**
|
||||
|
||||
### Modèles configurés
|
||||
- `vllm/qwen3-vl` (primary) — 200k ctx déclaré, mais sessions plafonnées à 66k pour la plupart
|
||||
- `vllm/qwen3.6` (fallback / legacy)
|
||||
|
||||
### Multimodal WhatsApp
|
||||
- Activé via `tools.media.image.enabled = true` (config set + restart gateway)
|
||||
- AUCUNE modification de models.json nécessaire pour l'activer
|
||||
- Pipeline : WhatsApp inbound → resize auto → tool-images → Qwen3-VL → réponse
|
||||
- Latences mesurées : cron text-only 14-21s, multimodal photo 5-13s, DM text simple ~30s
|
||||
- Tests OK historiques : Bernard-l'ermite, Hippocampe ×2 photos
|
||||
- Limite identifiée : Qwen3-VL imprécis en taxonomie spécialisée (crabe → Euphausiidae au lieu de Majidae)
|
||||
|
||||
---
|
||||
|
||||
## 2. Cron jobs Orange (production)
|
||||
|
||||
| ID | Nom | Horaire | Action | Notification |
|
||||
|---|---|---|---|---|
|
||||
| `d1f3041c` | orange-ouverture | 09:10 | Mesure d'ouverture | WhatsApp +33607148216 |
|
||||
| `8cd988b1` | orange-intraday | 10:00→17:00 (8x) | Mesure horaire silencieuse | Aucune |
|
||||
| `1a0d98b7` | orange-cloture | 17:40 | Mesure de clôture | WhatsApp +33607148216 |
|
||||
| `7d4bbd3d` | orange-chart-update | 17:45 | Génère le SVG du jour | Aucune |
|
||||
|
||||
Tous : modèle `vllm/qwen3-vl`, runtime `OpenClaw Default` (light-context), jours mardi→vendredi.
|
||||
|
||||
Source données : Yahoo Finance via `curl + jq` (cf. AGENTS.md). Premier cycle complet : 4 juin 2026.
|
||||
|
||||
---
|
||||
|
||||
## 3. Outils créés par l'utilisateur (NE PAS recréer ni modifier)
|
||||
|
||||
### `generate_chart.py` (alias `gen_chart.py`)
|
||||
- Localisation : `/home/node/.openclaw/workspace/scripts/generate_chart.py`
|
||||
- Rôle : génère `orange_chart.svg` à partir de `orange-bourse.md`
|
||||
- Stack : Python stdlib uniquement (PAS matplotlib, PAS yfinance)
|
||||
- Validé en production le 4/6/2026
|
||||
- Règles d'usage dans **TOOLS.md** + **AGENTS.md** (HARD CONSTRAINTS)
|
||||
|
||||
### Pattern global
|
||||
> "Agent pour la sémantique, script pour la mécanique"
|
||||
- L'agent : récup données via `curl`, lecture HEARTBEAT, formatage, décision WhatsApp
|
||||
- Les scripts : génération SVG, parsing Gmail, calculs déterministes
|
||||
|
||||
---
|
||||
|
||||
## 4. Décisions techniques notables
|
||||
|
||||
- **Heartbeat désactivé** (`agents.defaults.heartbeat.every = "0"`) — évite la dérive de fréquence (voulait 1h, recevait 30 min). **Conséquence acceptée** : pas de recovery auto en cas de stall (cf. §6 TODO).
|
||||
- **NODE_OPTIONS** = `--max-old-space-size=1536` (à passer à 4096 après upgrade RAM 20GB)
|
||||
- **mem_limit** = 2g, **mem_reservation** = 512m (à passer à 6g/1g après upgrade)
|
||||
- **Provider timeout** : 300s, **Job timeout** : 600s
|
||||
- **Hard constraints renforcés** dans AGENTS.md suite à incident où l'agent a tenté matplotlib + yfinance + scraping Yahoo en parallèle au lieu de `generate_chart.py` (47% du contexte consommé en cascade d'outils).
|
||||
|
||||
---
|
||||
|
||||
## 5. Backups
|
||||
- `/volume1/backups/openclaw/YYYYMMDD-HHMM/` (à créer **manuellement**, aucun cron orchestre actuellement)
|
||||
- `/volume1/docker/openclaw-data/openclaw.json.last-good` (auto par OpenClaw)
|
||||
- `/volume1/docker/openclaw-data/openclaw.json.bak` (auto par OpenClaw)
|
||||
- `/volume1/docker/openclaw-data/workspace/MEMORY.md.bak-2026-06-09` (snapshot avant split du 9/6, 21117 chars)
|
||||
- `/volume1/docker/openclaw-data/workspace/*.bak-20260604-*` (snapshots du round précédent du 4/6)
|
||||
|
||||
---
|
||||
|
||||
## 6. Bug du 2026-06-09 — Session WhatsApp DM stalled (RÉSOLU)
|
||||
|
||||
### Symptôme
|
||||
Session `agent:main:whatsapp:direct:+33607148216` (id `cfb27376-d71a-4406-80aa-4a3e9ed5ced5`)
|
||||
en state=processing, `lastProgressAge` ~6h43, aucune réponse aux messages WhatsApp.
|
||||
|
||||
### Cause racine identifiée
|
||||
`MEMORY.md` = 21117 chars > `bootstrapMaxChars` = 20000 (défaut)
|
||||
→ troncature côté bootstrap (`per-file-limit`)
|
||||
→ silent fail de l'`embedded_run` sans réponse modèle ni delivery
|
||||
→ état `processing` non libéré, payload contenant un champ string `undefined`
|
||||
(qui faisait crasher `sessions tail` sur `.trim()` of undefined)
|
||||
|
||||
### Méthodologie de diagnostic appliquée
|
||||
1. `sessions list` + `sessions tail` + `health` → 3 sources concordantes
|
||||
2. **Aucune commande mutative sans avoir lu son `--help`** (règle d'or — à conserver)
|
||||
3. `doctor --lint --json` → finding `core/doctor/bootstrap-size` confirmant la cause
|
||||
4. Inspection du payload JSONL → `truncated: true` sur MEMORY.md confirmé
|
||||
|
||||
### Fix appliqué (sans restart gateway)
|
||||
1. Backup : `cp MEMORY.md MEMORY.md.bak-2026-06-09`
|
||||
2. Split MEMORY.md en :
|
||||
- `MEMORY.md` réduit à **7453 chars** (essentiel always-in-prompt : outils, workflows, config, prefs user, runbook bref)
|
||||
- `memory/2026-06-09.md` (**871 chars** : note du jour avec multimodal + bug stalled)
|
||||
3. Suppression d'une duplication CONFIG-PRODUCTION qui s'était infiltrée
|
||||
4. Vérification ownership `1000:1000` sur les 2 fichiers (sinon agent ne peut pas lire)
|
||||
5. `doctor --lint --only core/doctor/bootstrap-size` → `{"ok":true,"findings":[]}`
|
||||
6. **Test WhatsApp réel** : "Test post-fix" envoyé à 17:39:29 → "OK" reçu à 17:40:01 (32s, normal)
|
||||
|
||||
### Tailles bootstrap finales
|
||||
| Fichier | Chars | Limite |
|
||||
|---|---|---|
|
||||
| MEMORY.md | 7453 | 20000 |
|
||||
| AGENTS.md | 12259 | 20000 |
|
||||
| TOOLS.md | 7522 | 20000 |
|
||||
| SOUL.md | 1806 | 20000 |
|
||||
| USER.md | 1489 | 20000 |
|
||||
| IDENTITY.md | 1341 | 20000 |
|
||||
| HEARTBEAT.md | 344 | 20000 |
|
||||
| **Total bootstrap** | **40995** (+ workspace `.md` minuscules) | **60000** |
|
||||
|
||||
---
|
||||
|
||||
## 7. TODO / Différé
|
||||
|
||||
### Priorité haute
|
||||
- [ ] **Décision OAuth Gmail** avant 12/6/2026 (token `gmail.modify` expire) :
|
||||
Publish OAuth app GCP **vs** re-auth weekly via cron
|
||||
- [ ] Phase E Gmail reportée : filtres natifs, vague 2 (Archive Philippot+Ulys), 2ème passe Q8 newsletters tech
|
||||
|
||||
### Priorité moyenne
|
||||
- [ ] **Investiguer fichiers `gmail-audit.md` / `gmail-housekeeping.md`** créés en `root:root` mode 600
|
||||
→ l'agent (uid 1000) ne peut pas les lire
|
||||
→ probablement un cron-host qui `docker exec` en root au lieu d'un cron OpenClaw natif
|
||||
- [ ] **`orange-chart-update` du 4/6 17h45** = `error` dans `cron list` → vérifier la cause
|
||||
- [ ] **Activer `memorySearch`** (différé faute de provider d'embeddings local) :
|
||||
- Pas d'Ollama installé sur ARCHIVE3 (curl localhost:11434 → no answer)
|
||||
- Pas de `.gguf` dans `workspace/tools/models/`
|
||||
- vLLM actuel sert le chat Qwen3-VL, pas les embeddings
|
||||
- 3 options à arbitrer : (a) installer Ollama+nomic-embed-text, (b) ajouter endpoint
|
||||
embedding sur DGX, (c) télécharger un .gguf local. Aucune urgente.
|
||||
|
||||
### Priorité basse
|
||||
- [ ] **Pollution workspace** : fichiers parasites `-a`, `--max`, `--force`, `--query` à supprimer
|
||||
(créés par flags shell mal échappés en sessions précédentes)
|
||||
- [ ] **Backups OpenClaw** : aucune orchestration en place malgré la mention dans MEMORY.md
|
||||
→ créer un cron host hebdo qui copie `/volume1/docker/openclaw-data/*` vers
|
||||
`/volume1/backups/openclaw/$(date +%Y%m%d-%H%M)/`
|
||||
- [ ] **Fragilité structurelle** : `Heartbeat disabled` empêche toute recovery auto.
|
||||
Toute future panne d'un `embedded_run` (coupure WhatsApp, crash modèle, etc.) reproduira
|
||||
le pattern stalled. Pas un bug en soi, mais à documenter pour la prochaine fois.
|
||||
|
||||
---
|
||||
|
||||
## 8. Préférences utilisateur (à respecter par l'agent et les sessions IA)
|
||||
|
||||
- L'utilisateur travaille **en vacances** → temps disponible pour expérimenter
|
||||
(sinon sessions nocturnes courtes)
|
||||
- Préfère la **transparence** : "tu as raison" plutôt que justifier une erreur
|
||||
- N'aime PAS les solutions cloud payantes (Claude API, OpenAI, Groq) → **tout doit rester local**
|
||||
- A tendance à **attaquer avant de lire** → être bref et structuré, ordre clair des actions
|
||||
- Aime **challenger** les propositions : on lit toujours `--help` ou `config schema` avant
|
||||
de proposer une commande mutative
|
||||
- Convention de communication établie : ne pas inventer de référence externe sans recherche
|
||||
vérifiable, préférer raisonner sur les sorties locales réelles
|
||||
|
||||
---
|
||||
|
||||
## 9. Convention pour la prochaine session
|
||||
|
||||
### Reprise de production
|
||||
1. Lire ce HANDOFF en entier
|
||||
2. `sudo docker exec openclaw-gateway node /app/dist/index.js health` (état général)
|
||||
3. `sudo docker exec openclaw-gateway node /app/dist/index.js sessions list | head -10` (sessions actives)
|
||||
4. `sudo docker exec openclaw-gateway node /app/dist/index.js doctor --lint --json` (findings)
|
||||
|
||||
### Si nouveau debug
|
||||
- **Aucune commande mutative sans `--help` lu au préalable**
|
||||
- **Lire toujours d'abord** : `health`, `sessions list`, `doctor --lint --json`
|
||||
- Pour mutation config : `config patch --stdin --dry-run` puis sans `--dry-run`
|
||||
- Pour cleanup sessions : `cleanup --dry-run` puis `cleanup --enforce`
|
||||
- Penser à `chown 1000:1000` après tout `sudo tee`/`sudo cp` dans workspace
|
||||
|
||||
### Append-only sur ce HANDOFF
|
||||
À chaque session significative, ajouter une entrée dans **§6** (sous forme de nouvelle
|
||||
sous-section "Bug du YYYY-MM-DD" ou "Évolution du YYYY-MM-DD") plutôt que d'écraser.
|
||||
|
||||
---
|
||||
|
||||
_Fin du HANDOFF — 2026-06-09 17:45 UTC+2_
|
||||
|
||||
|
||||
## 10 juin 2026 ~01:00-01:45 UTC+2 — Persistance OAuth gog (pattern réutilisable)
|
||||
|
||||
### Contexte général
|
||||
Découverte que les tools CLI (gog, et probablement d'autres) stockent leurs
|
||||
credentials/tokens dans la couche writable du container par défaut, donc PERDUS à
|
||||
chaque `compose down/up` ou `--force-recreate`. Pattern à corriger pour tout outil
|
||||
qui aura besoin d'auth persistée (gog, future MCP avec OAuth, etc.).
|
||||
|
||||
### Modification compose.yaml (mutation #1 infra)
|
||||
Ajout dans la section `environment:` du service openclaw-gateway :
|
||||
|
||||
GOG_HOME: /home/node/.openclaw/gogcli
|
||||
|
||||
→ Redirige toute l'arborescence gog (credentials + keyring + config + cache) sous
|
||||
le volume Synology persisté `/volume1/docker/openclaw-data:/home/node/.openclaw`.
|
||||
→ Pattern applicable à d'autres outils via leur env var équivalente (XDG_DATA_HOME,
|
||||
HOME custom, ou env-var-spécifique).
|
||||
|
||||
### Migration manuelle des fichiers gog (one-shot)
|
||||
Structure attendue par gog avec GOG_HOME :
|
||||
$GOG_HOME/data/credentials.json
|
||||
$GOG_HOME/data/keyring/_gogcli_key_v1_<base64>...
|
||||
$GOG_HOME/config/config.json (créé à la demande)
|
||||
|
||||
Migration chronologique :
|
||||
1. mkdir /volume1/docker/openclaw-data/gogcli (uid 1000, mode 700)
|
||||
2. compose up -d → gog crée data/keyring/.lock
|
||||
3. mv credentials.json + keyring/ vers data/ (préservation des 4 _gogcli_key_v1_*)
|
||||
4. chown -R 1000:1000, find -type f -exec chmod 600, dirs chmod 700
|
||||
|
||||
### Test de persistance validé
|
||||
- `compose down` puis `compose up -d` (recreate complet container) — 60s
|
||||
- Container Up healthy après ~60s (start_period: 120s dans healthcheck)
|
||||
- `gog auth list` : compte tallagrand.thierry@gmail.com survit ✅
|
||||
- `gog gmail labels list` : retourne INBOX/SENT/IMPORTANT/CHAT comme avant ✅
|
||||
- OpenClaw `health` : WhatsApp linked (auth age 1m), 33 sessions store
|
||||
|
||||
### Sessions store état après nuit
|
||||
- 33 entries (vs 32 avant purge cfb27376 + 1 nouvelle session WhatsApp + 1 dashboard)
|
||||
- Plus de session ruinée à 87% saturation
|
||||
- Compaction `mode=safeguard, reserveTokens=8192` actif (cf. config patch précédent)
|
||||
|
||||
### Backups préservés (à purger après ~2 semaines de stabilité)
|
||||
- /volume1/docker/openclaw/compose.yaml.bak-pre-goghome-20260610-*
|
||||
- /volume1/docker/openclaw-data/gogcli.bak-pre-mv-20260610-0132/
|
||||
- /volume1/docker/openclaw-data/agents/main/sessions/sessions.json.bak-pre-purge-*
|
||||
- /volume1/docker/openclaw-data/openclaw.json.bak-pre-restart-20260609
|
||||
|
||||
### TODO infra (reportés, non critiques)
|
||||
- Pattern XDG_*_HOME pour autres outils CLI futurs (réflexe à appliquer
|
||||
systématiquement pour tout outil qui stocke des credentials)
|
||||
- Investiguer warning gog `config.path missing` (gogcli/config/config.json)
|
||||
- Mettre à jour scripts/generate_gmail_token.sh (la commande `gog auth generate-token`
|
||||
utilisée n'existe pas — la vraie procédure est `gog auth credentials set` puis
|
||||
`gog auth add ... --manual --gmail-scope=full --force-consent`)
|
||||
- Surveiller latence cron Orange après tuning compaction (potentiel impact +overhead
|
||||
via `mode=safeguard`)
|
||||
- Bug Qwen3-VL boucle de répétition sur prompts longs : reproduit en prod, pas en
|
||||
API directe ≤300 tokens. Cause suspectée : tool catalog volumineux + tool error
|
||||
qui dégrade attention. Mitigations à explorer : réduire AGENTS.md de 12259 chars,
|
||||
désactiver dir_list sur runtime dashboard, ou repetition_penalty (non exposé en
|
||||
config OpenClaw 2026.6.1)
|
||||
|
||||
### Changement comportemental notable
|
||||
Avant cette session, l'agent ne pouvait pas répondre aux questions Gmail via
|
||||
WhatsApp ou dashboard (auth absente → tool errors → boucle Qwen3). Maintenant :
|
||||
- Gmail accessible via gog gmail search/trash/archive/labels
|
||||
- Doc syntaxe + hard constraints dans MEMORY.md (section "Gmail (gog CLI v0.21.0)")
|
||||
- Référence au HANDOFF Gmail pour la doc opérationnelle complète
|
||||
|
||||
|
||||
## Validation 10 juin 2026 ~02:13 UTC+2 — Découvertes
|
||||
|
||||
### Commande /new dans WhatsApp DM
|
||||
Le plugin OpenClaw WhatsApp supporte la commande slash /new qui crée une nouvelle
|
||||
session sans toucher à l'ancienne. **C'est la méthode privilégiée** pour
|
||||
redémarrer une conversation WhatsApp DM saturée — préférable à la purge manuelle
|
||||
de sessions.json pour les cas non corrompus.
|
||||
|
||||
Quand utiliser :
|
||||
- Session WhatsApp DM avec context overflow (> 60k tokens)
|
||||
- Bouclage suspect après plusieurs heures de discussion
|
||||
- Reset volontaire pour démarrer un nouveau sujet
|
||||
|
||||
Quand NE PAS utiliser (préférer purge manuelle) :
|
||||
- JSONL corrompu (assistant content: [] empty array)
|
||||
- Session avec compactionCheckpoints=7+ (irrécupérable)
|
||||
- abortedLastRun=true persistant
|
||||
|
||||
### Hot-reload config compaction validé
|
||||
agents.defaults.compaction.* est correctement hot-reloaded après compose restart.
|
||||
Pas besoin de docker compose down/up pour ces changements.
|
||||
|
||||
### Bug observable mais sans gravité
|
||||
effectiveReserveTokens plafonne à 16384 même avec reserveTokensFloor configuré
|
||||
à 20000. Le système gère via fallback compaction multiple. À reporter upstream
|
||||
OpenClaw si récurrent.
|
||||
|
||||
## 10/6/2026 mercredi ~15:00-15:03 UTC+2 — Fix bug "OK au lieu du cours" cron orange-intraday
|
||||
|
||||
### Cause racine
|
||||
Le cron `orange-intraday` (id `8cd988b1-d91e-4ecb-8719-c1c72efb0d87`) :
|
||||
- prompt terminait par "Réponds par 'OK' une fois fini. PAS de WhatsApp pour l'intraday."
|
||||
- delivery configuré en mode=announce, channel=whatsapp, to=+33607148216
|
||||
- → l'agent répondait "OK" en signal de fin, et le mode `announce` envoyait
|
||||
systématiquement la dernière réponse à WhatsApp = donc "OK" partait à chaque heure.
|
||||
- L'instruction "PAS de WhatsApp pour l'intraday" dans le prompt était ignorée
|
||||
(delivery est piloté par config, pas par prompt).
|
||||
|
||||
### Fix appliqué
|
||||
Édition du prompt via :
|
||||
`cron edit 8cd988b1-... --message "<nouveau prompt>"`
|
||||
Remplacement final :
|
||||
AVANT : "Réponds par 'OK' une fois fini. PAS de WhatsApp pour l'intraday."
|
||||
APRÈS : "Une fois fini, réponds avec UNIQUEMENT cette ligne au format strict :
|
||||
'ORA.PA : <prix>€ (<variation>%)' OU 'ORA.PA : indisponible'
|
||||
PAS de 'OK', PAS d'autre texte, PAS de tableau, PAS de commentaire."
|
||||
|
||||
### Validation
|
||||
- 15:00 : cron horaire avec ancien prompt → envoi "OK" (état pré-fix)
|
||||
- 15:03 : `cron run` manuel avec nouveau prompt → envoi "ORA.PA : 17,83€ (+0,99%)" ✅
|
||||
- ✅ format conforme, valeur cohérente (vendredi 6/6 clôture 17,66 → +0,99% = 17,83 OK)
|
||||
- À surveiller : prochains crons auto 16:00 et 17:00 mercredi
|
||||
|
||||
### Backup
|
||||
/volume1/docker/openclaw-data/handoffs/cron-orange-intraday-before-20260610-0303.json
|
||||
|
||||
### Apprentissages
|
||||
- `cron edit <id> --message "<text>"` est la méthode propre pour modifier un prompt
|
||||
- `cron run <id>` permet un test immédiat (debug, ne respecte pas le schedule)
|
||||
- Le delivery mode `announce` envoie automatiquement la dernière réponse de l'agent
|
||||
→ écrire le prompt pour que la dernière réponse soit le format souhaité
|
||||
- Les autres cron Orange (orange-cloture, orange-ouverture) utilisent un pattern
|
||||
similaire, à monitorer mais pas à modifier (semblent OK structurellement)
|
||||
|
||||
|
||||
## 10/6/2026 nuit (~22:00-23:48 Paris) — Session marathon résolution amnésie agent
|
||||
|
||||
### Phases réussies
|
||||
- A. Audit complet (versions, dette technique, ressources)
|
||||
- B. Backup pré-MAJ (156 MB préservés, image pre-maj-20260610-2237)
|
||||
- C. MAJ OpenClaw 2026.6.1 → 2026.6.5 (sans régression)
|
||||
- D. Tests baseline 6/6 pass
|
||||
- F. TOOLS.md + MEMORY.md complets avec convention exec
|
||||
|
||||
### Découverte majeure — Bug structurel résolu
|
||||
Le bug "amnésie Gmail" n'était PAS une vraie amnésie LLM.
|
||||
L'agent essayait d'invoquer `gog` comme tool natif (10 fois !).
|
||||
La cause : TOOLS.md documentait `gog gmail send --to ...` sans préciser
|
||||
que `gog` doit passer par le tool natif `exec` (ou `bash`).
|
||||
|
||||
Fix : ajout section 1.0 dans TOOLS.md + section 7 hard constraint :
|
||||
"Toute commande CLI (gog, python3, curl, jq, git, node) DOIT être
|
||||
invoquée via `exec` ou `bash`."
|
||||
|
||||
### Test validation 23:46 ✅
|
||||
Question : "Envoie un mail à tallagrand.thierry@gmail.com..."
|
||||
Agent : appelle `tool=exec` avec `gog gmail send -a ... --to ... --subject ... --body ...`
|
||||
Résultat : Mail reçu (ID 19eb38051276d01e), agent confirme avec détails.
|
||||
|
||||
### Pattern réutilisable (à appliquer aux futures capacités)
|
||||
1. Identifier la commande exacte (--help)
|
||||
2. Documenter EXPLICITEMENT que ça passe par exec
|
||||
3. Donner un exemple concret avec arguments
|
||||
4. Mapping question→action
|
||||
5. Hard constraint anti-amnésie
|
||||
6. Test immédiat après modification
|
||||
|
||||
### Reste pour Phase E (en cours dans la nuit)
|
||||
- E.1 Refactor generate_chart.py (PNG + tri chronologique)
|
||||
- E.2 Reconstruction orange-bourse.md propre
|
||||
- E.3-E.5 Test pipeline + cron + WhatsApp PNG
|
||||
|
||||
### Backups préservés
|
||||
- /volume1/docker/openclaw-backups-pre-maj-20260610-2237/ (compose + data)
|
||||
- Image Docker openclaw-gateway:pre-maj-20260610-2237 (rollback ULTIME)
|
||||
- TOOLS.md.bak-pre-skills-fix-* (avant tee)
|
||||
- TOOLS.md.bak-pre-exec-fix-* (avant section 1.0)
|
||||
- MEMORY.md.bak-pre-skills-fix-*
|
||||
|
||||
## 11/6/2026 nuit (~00:30-01:45 Paris) — Phase E pipeline PNG complet
|
||||
|
||||
### Phase E.1 (infra cairosvg) ✅
|
||||
- Dockerfile patché : ajout libcairo2/libpango/libgdk-pixbuf/libffi-dev/shared-mime-info + cairosvg==2.7.1
|
||||
- Build OK (~33s) → openclaw-custom:latest sha256:8164c3ae04793...
|
||||
- Container UP healthy 5 min après recreate
|
||||
- Test cairosvg : PNG 15933 bytes généré
|
||||
- Test gog auth list : tallagrand.thierry@gmail.com préservé (3e validation persistance)
|
||||
- Patch generate_chart.py : conversion SVG→PNG + horodatage charts/ora-YYYY-MM-DD-HHMM.png + symlink ora-latest.png
|
||||
|
||||
### Phase E.2 (reconstruction orange-bourse.md) ✅
|
||||
- Script clean_bourse_md.py créé (parse + dédup + tri + retire pollution YAML)
|
||||
- Avant : 44 lignes, 5 sections désordonnées avec double 06-05, 10 polluants YAML
|
||||
- Après : 34 lignes propres, 4 sections triées (06-05, 06-07, 06-09, 06-10), 0 pollution
|
||||
- Régénération graphe 06-10 : 10 mesures, courbe LISSE chronologique (vs zigzag avant)
|
||||
- Visualisation PNG validée : 46519 bytes, charte graphique Orange parfaite
|
||||
|
||||
### Reste pour Phase E (demain en condition réelle)
|
||||
- E.4 : Update prompt cron orange-intraday (ajouter étape send WhatsApp + image PNG)
|
||||
- E.5 : Test cron run + validation WhatsApp avec image attachée
|
||||
|
||||
### Fichiers ajoutés cette nuit
|
||||
- /workspace/scripts/clean_bourse_md.py (nouveau, ~140 lignes)
|
||||
- /workspace/charts/ (nouveau dossier)
|
||||
- /workspace/charts/ora-2026-06-11-0143.png + symlink ora-latest.png
|
||||
|
||||
### Backups préservés
|
||||
- Dockerfile.bak-pre-cairosvg-20260611-0014
|
||||
- generate_chart.py.bak-pre-png-patch-20260611-XXXX
|
||||
- orange-bourse.md.bak-pre-clean-20260611-0140
|
||||
- orange-bourse.md.bak-pre-apply-20260611-XXXX
|
||||
|
||||
## 11/6/2026 (~01:55-02:10 Paris) — Phase E.4 prompt cron mis à jour
|
||||
|
||||
### Cron run manuel à 01:55 — preuve que ancien prompt fonctionne
|
||||
- Run "ok" 31.5s, WhatsApp delivered "ORA.PA : 18,02€ (+2,07%)" (capture validée)
|
||||
- Note : Yahoo retourne le last close + variation hors séance, normal
|
||||
|
||||
### Phase E.4 — Update prompt cron orange-intraday
|
||||
- Backup pré-E4 : cron-orange-intraday-pre-E4-XXXX.json
|
||||
- Nouveau prompt : 4 étapes (ajout étape 4 message+attachment PNG)
|
||||
- Précisions : heure Paris explicite, valeurs cohérentes 10:00-17:30, ora-latest.png comme attachment
|
||||
- Cleanup data fictives 11/06 : restauration depuis backup pré-fake
|
||||
- Phase E.5 différée à 11/6 matin avant 10h (avant cron auto)
|
||||
|
||||
### Phase E.5 faite
|
||||
- cron run manuel test → vérifier WhatsApp reçoit texte + image PNG
|
||||
- a vérifier et faire si besoin cron auto utilise nouveau prompt → 2e validation
|
||||
- Si KO : revert via backup .bak-pre-E4-XXXX
|
||||
- Si OK : Phase E entièrement validée, fin Phase E
|
||||
|
||||
|
||||
## 23 juin 2026 ~01:15-01:30 UTC+2 — Migration cron email horaire vers rapport quotidien 8h30
|
||||
|
||||
### Contexte
|
||||
L’utilisateur souhaitait abandonner le rapport Gmail horaire (`hourly-email-check`) au
|
||||
profit d’un unique résumé quotidien à 8h30 Europe/Paris, tous les jours (week-end inclus),
|
||||
sur WhatsApp.
|
||||
|
||||
### Source de vérité identifiée
|
||||
Le cron actif n’était PAS dans les fichiers JSON obsolètes (`cron/jobs.json*`) mais dans
|
||||
la base SQLite :
|
||||
|
||||
- Path : `/volume1/docker/openclaw-data/state/openclaw.sqlite`
|
||||
- Table : `cron_jobs`
|
||||
- Job ID : `9d43dc31-f6ee-445e-a085-753ca65bc0b0`
|
||||
|
||||
### Actions réalisées
|
||||
1. **Backup** de `state/openclaw.sqlite`, `workspace/MEMORY.md`, `workspace/TOOLS.md`
|
||||
(timestamp `.bak-20260623-01...`).
|
||||
2. **UPDATE SQLite** :
|
||||
- `name` : `hourly-email-check` → `daily-email-report`
|
||||
- `schedule_expr` : `0 * * * *` → `30 8 * * *`
|
||||
- `payload_message` : résumé 24h, format court global + détail important (max 5)
|
||||
- `job_json` : resynchronisé avec les nouvelles valeurs
|
||||
- `next_run_at_ms` : recalculé (OpenClaw applique un `staggerMs` de 5 min max,
|
||||
donc exécution réelle entre 8h30 et 8h35).
|
||||
3. **Mise à jour `workspace/MEMORY.md`** :
|
||||
- TODO courant modifié
|
||||
- Apprentissage structurant du 23/6/2026 ajouté
|
||||
4. **Mise à jour `workspace/TOOLS.md`** :
|
||||
- Nouvelle section 9 « Gmail daily cron » (schedule, canal, format, source de vérité)
|
||||
5. **Archivage** des fichiers JSON obsolètes dans `cron/archived-20260623/` :
|
||||
- `jobs.json.migrated`
|
||||
- `jobs.json.bak`
|
||||
- `jobs-state.json.migrated`
|
||||
- `runs/*.jsonl.migrated` (12 fichiers)
|
||||
|
||||
### Validation utilisateur (challenge pré-build)
|
||||
- ✅ Tous les jours (week-end inclus)
|
||||
- ✅ Résumé des dernières 24h
|
||||
- ✅ Renommage en `daily-email-report`
|
||||
- ✅ Canal WhatsApp conservé (`+33607148216`)
|
||||
- ✅ Format court global + détail important avec date/heure
|
||||
- ✅ Mise à jour MEMORY.md / TOOLS.md
|
||||
- ✅ Archivage des JSON obsolètes (option B)
|
||||
- ✅ Backup SQLite avant mutation
|
||||
- ✅ Forçage de `next_run_at_ms`
|
||||
- ✅ StaggerMs conservé (exécution 8h30–8h35, acceptable)
|
||||
|
||||
### Fichiers impactés
|
||||
- `state/openclaw.sqlite` (mutation du job)
|
||||
- `workspace/MEMORY.md`
|
||||
- `workspace/TOOLS.md`
|
||||
- `cron/jobs.json.migrated` → `cron/archived-20260623/`
|
||||
- `cron/jobs.json.bak` → `cron/archived-20260623/`
|
||||
- `cron/jobs-state.json.migrated` → `cron/archived-20260623/`
|
||||
- `cron/runs/*.jsonl.migrated` → `cron/archived-20260623/runs/`
|
||||
|
||||
### Prochaine validation attendue
|
||||
Vérifier demain matin (~8h30–8h35) que WhatsApp reçoit bien le résumé quotidien avec
|
||||
le format convenu. Si format incorrect : ajuster `payload_message` dans SQLite.
|
||||
|
||||
|
||||
## 23 juin 2026 ~01:15-01:30 UTC+2 — Migration cron email horaire vers rapport quotidien 8h30
|
||||
|
||||
### Contexte
|
||||
L’utilisateur souhaitait abandonner le rapport Gmail horaire (`hourly-email-check`) au
|
||||
profit d’un unique résumé quotidien à 8h30 Europe/Paris, tous les jours (week-end inclus),
|
||||
sur WhatsApp.
|
||||
|
||||
### Source de vérité identifiée
|
||||
Le cron actif n’était PAS dans les fichiers JSON obsolètes (`cron/jobs.json*`) mais dans
|
||||
la base SQLite :
|
||||
|
||||
- Path : `/volume1/docker/openclaw-data/state/openclaw.sqlite`
|
||||
- Table : `cron_jobs`
|
||||
- Job ID : `9d43dc31-f6ee-445e-a085-753ca65bc0b0`
|
||||
|
||||
### Actions réalisées
|
||||
1. **Backup** de `state/openclaw.sqlite`, `workspace/MEMORY.md`, `workspace/TOOLS.md`
|
||||
(timestamp `.bak-20260623-01...`).
|
||||
2. **UPDATE SQLite** :
|
||||
- `name` : `hourly-email-check` → `daily-email-report`
|
||||
- `schedule_expr` : `0 * * * *` → `30 8 * * *`
|
||||
- `payload_message` : résumé 24h, format court global + détail important (max 5)
|
||||
- `job_json` : resynchronisé avec les nouvelles valeurs
|
||||
- `next_run_at_ms` : recalculé (OpenClaw applique un `staggerMs` de 5 min max,
|
||||
donc exécution réelle entre 8h30 et 8h35).
|
||||
3. **Mise à jour `workspace/MEMORY.md`** :
|
||||
- TODO courant modifié
|
||||
- Apprentissage structurant du 23/6/2026 ajouté
|
||||
4. **Mise à jour `workspace/TOOLS.md`** :
|
||||
- Nouvelle section 9 « Gmail daily cron » (schedule, canal, format, source de vérité)
|
||||
5. **Archivage** des fichiers JSON obsolètes dans `cron/archived-20260623/` :
|
||||
- `jobs.json.migrated`
|
||||
- `jobs.json.bak`
|
||||
- `jobs-state.json.migrated`
|
||||
- `runs/*.jsonl.migrated` (12 fichiers)
|
||||
|
||||
### Validation utilisateur (challenge pré-build)
|
||||
- ✅ Tous les jours (week-end inclus)
|
||||
- ✅ Résumé des dernières 24h
|
||||
- ✅ Renommage en `daily-email-report`
|
||||
- ✅ Canal WhatsApp conservé (`+33607148216`)
|
||||
- ✅ Format court global + détail important avec date/heure
|
||||
- ✅ Mise à jour MEMORY.md / TOOLS.md
|
||||
- ✅ Archivage des JSON obsolètes (option B)
|
||||
- ✅ Backup SQLite avant mutation
|
||||
- ✅ Forçage de `next_run_at_ms`
|
||||
- ✅ StaggerMs conservé (exécution 8h30–8h35, acceptable)
|
||||
|
||||
### Fichiers impactés
|
||||
- `state/openclaw.sqlite` (mutation du job)
|
||||
- `workspace/MEMORY.md`
|
||||
- `workspace/TOOLS.md`
|
||||
- `cron/jobs.json.migrated` → `cron/archived-20260623/`
|
||||
- `cron/jobs.json.bak` → `cron/archived-20260623/`
|
||||
- `cron/jobs-state.json.migrated` → `cron/archived-20260623/`
|
||||
- `cron/runs/*.jsonl.migrated` → `cron/archived-20260623/runs/`
|
||||
|
||||
### Prochaine validation attendue
|
||||
Vérifier demain matin (~8h30–8h35) que WhatsApp reçoit bien le résumé quotidien avec
|
||||
le format convenu. Si format incorrect : ajuster `payload_message` dans SQLite.
|
||||
370
workspace/AGENTS.md
Normal file
370
workspace/AGENTS.md
Normal file
@@ -0,0 +1,370 @@
|
||||
# AGENTS.md - Your Workspace
|
||||
|
||||
This folder is home. Treat it that way.
|
||||
|
||||
## 📈 BOURSE — Architecture N8N (refonte 2026-06-24)
|
||||
|
||||
> ⚠️ Les anciens scripts `generate_chart.py`, `get_quote.py`, `clean_bourse_md.py`
|
||||
> et le fichier `orange-bourse.md` sont OBSOLÈTES. NE PLUS les utiliser, NE PLUS
|
||||
> éditer `orange-bourse.md` à la main. Toute la bourse passe désormais par N8N.
|
||||
|
||||
### Principe
|
||||
Tu es l'INTERLOCUTEUR. N8N est l'EXÉCUTANT.
|
||||
Tu reçois la demande humaine → tu appelles le workflow N8N → il renvoie un PNG → tu l'affiches (WhatsApp/GUI).
|
||||
Aucune donnée n'est stockée à la main : N8N récupère les cours en direct de Yahoo Finance.
|
||||
|
||||
### Source de vérité = `bourse-config.json`
|
||||
La watchlist (liste des tickers) et les options de graphe vivent dans
|
||||
`/home/node/.openclaw/workspace/bourse-config.json`. Tu PEUX et DOIS éditer ce fichier
|
||||
quand l'humain demande d'ajouter/retirer une valeur ou changer une option.
|
||||
|
||||
### Le seul outil bourse autorisé : le webhook N8N
|
||||
Pour produire un graphe, tu fais UN appel HTTP POST (via `exec` + curl) :
|
||||
|
||||
```bash
|
||||
curl -s -X POST "https://n8n.airtria.pro/webhook/bourse-graphe" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tickers":["ORA.PA","TTE.PA"],"range":"5d","interval":"60m","beginAtZero":true}' \
|
||||
-o /home/node/.openclaw/workspace/charts/bourse.png
|
||||
```
|
||||
|
||||
Réponse = un fichier PNG prêt à envoyer sur WhatsApp. Paramètres du body (tous optionnels) :
|
||||
- `tickers` : liste de symboles Yahoo (def: lus dans bourse-config.json)
|
||||
- `range` : `1d`,`5d`,`1mo`,`3mo`,`6mo`,`1y` (def `5d`)
|
||||
- `interval` : `15m`,`60m`,`1d` (def `60m`)
|
||||
- `beginAtZero` : `true` = axe Y part de 0 (pas de "variation géante pour 5cts"), `false` = zoom sur les variations
|
||||
- `title` : titre du graphe (optionnel)
|
||||
|
||||
### Mapping demande humaine → action
|
||||
| Demande | Action |
|
||||
|---|---|
|
||||
| "montre-moi Orange" | POST webhook avec tickers=["ORA.PA"] |
|
||||
| "ajoute Total / Nvidia" | éditer `bourse-config.json` (ajouter "TTE.PA"/"NVDA") puis POST webhook avec la nouvelle liste |
|
||||
| "fais commencer le graphe à 0" | POST avec `beginAtZero:true` (+ mettre à jour le defaults dans la config) |
|
||||
| "zoome sur les variations" | POST avec `beginAtZero:false` |
|
||||
| "le cours d'Orange aujourd'hui" | POST avec range="1d", interval="15m" ; le PNG suffit |
|
||||
| "Anthropic" | Anthropic n'est PAS cotée en bourse → le dire, ne pas inventer de ticker |
|
||||
|
||||
### Règles
|
||||
1. NE PAS réinventer un script Python de graphe. Le webhook N8N fait tout.
|
||||
2. NE PAS éditer `orange-bourse.md` (fichier mort).
|
||||
3. Tickers Yahoo : actions FR = suffixe `.PA` (ORA.PA, TTE.PA). US = sans suffixe (NVDA, AAPL).
|
||||
4. Si le webhook renvoie un PNG "Aucune donnée" : c'est que le marché est fermé ou
|
||||
le ticker est invalide → le dire à l'humain, NE PAS inventer de cours.
|
||||
5. Si l'humain veut un nouveau type de graphe/comportement que le workflow ne sait pas faire,
|
||||
tu peux MODIFIER le workflow N8N via le MCP `n8n-mcp` (workflow id `4bluZIeN3TnbzIrv`).
|
||||
6. Réponse WhatsApp bourse : 3 lignes max + le PNG en pièce jointe.
|
||||
|
||||
|
||||
## First Run
|
||||
|
||||
If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again.
|
||||
|
||||
## Session Startup
|
||||
|
||||
Use runtime-provided startup context first.
|
||||
|
||||
That context may already include:
|
||||
|
||||
- `AGENTS.md`, `SOUL.md`, `USER.md`, and `HANDOFF.md`
|
||||
- recent daily memory such as `memory/YYYY-MM-DD.md`
|
||||
- `MEMORY.md` when this is the main session
|
||||
|
||||
Do not manually reread startup files unless:
|
||||
|
||||
1. The user explicitly asks
|
||||
2. The provided context is missing something you need
|
||||
3. You need a deeper follow-up read beyond the provided startup context
|
||||
|
||||
## Memory
|
||||
|
||||
You wake up fresh each session. These files are your continuity:
|
||||
|
||||
- **Daily notes:** `memory/YYYY-MM-DD.md` (create `memory/` if needed) — raw logs of what happened
|
||||
- **Long-term:** `MEMORY.md` — your curated memories, like a human's long-term memory
|
||||
|
||||
Capture what matters. Decisions, context, things to remember. Skip the secrets unless asked to keep them.
|
||||
|
||||
### 🧠 MEMORY.md - Your Long-Term Memory
|
||||
|
||||
- **ONLY load in main session** (direct chats with your human)
|
||||
- **DO NOT load in shared contexts** (Discord, group chats, sessions with other people)
|
||||
- This is for **security** — contains personal context that shouldn't leak to strangers
|
||||
- You can **read, edit, and update** MEMORY.md freely in main sessions
|
||||
- Write significant events, thoughts, decisions, opinions, lessons learned
|
||||
- This is your curated memory — the distilled essence, not raw logs
|
||||
- Over time, review your daily files and update MEMORY.md with what's worth keeping
|
||||
|
||||
### 📝 Write It Down - No "Mental Notes"!
|
||||
|
||||
- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE
|
||||
- "Mental notes" don't survive session restarts. Files do.
|
||||
- When someone says "remember this" → update `memory/YYYY-MM-DD.md` or relevant file
|
||||
- When you learn a lesson → update AGENTS.md, TOOLS.md, or the relevant skill
|
||||
- When you make a mistake → document it so future-you doesn't repeat it
|
||||
- **Text > Brain** 📝
|
||||
|
||||
## Red Lines
|
||||
|
||||
- Don't exfiltrate private data. Ever.
|
||||
- Don't run destructive commands without asking.
|
||||
- `trash` > `rm` (recoverable beats gone forever)
|
||||
- When in doubt, ask.
|
||||
|
||||
## 🔁 Anti-Loop — Règle générale d'arrêt (added 2026-06-14)
|
||||
|
||||
Cette règle est TRANSVERSALE et prime sur toute autre tâche.
|
||||
|
||||
### STOP après 2 échecs
|
||||
Si une ressource demandée (fichier, dossier, projet, service, API)
|
||||
est introuvable ou inaccessible après **2 vérifications maximum** :
|
||||
1. ARRÊTER immédiatement toute nouvelle tentative.
|
||||
2. NE PAS reformuler, NE PAS chercher ailleurs en boucle.
|
||||
3. NE PAS conclure "ça a été supprimé/déplacé" sans preuve.
|
||||
4. Signaler clairement à l'utilisateur :
|
||||
- Ce qui a été cherché (chemin/commande exacts)
|
||||
- Le résultat brut (ex: "No such file or directory")
|
||||
- L'hypothèse la plus probable (ex: "hors de mon sandbox")
|
||||
5. Demander une clarification ou un accès, puis ATTENDRE.
|
||||
|
||||
### Périmètre / Sandbox — vérité de base
|
||||
- Mon home est `/home/node/.openclaw/workspace`.
|
||||
- Je ne vois PAS l'hôte Synology ni les autres conteneurs
|
||||
(LMS / LyrionMusicServer, Plex, etc.) sauf si un volume est
|
||||
explicitement monté dans mon workspace.
|
||||
- "Introuvable dans le workspace" ≠ "n'existe pas sur le NAS".
|
||||
→ Le dire ainsi, ne JAMAIS affirmer une suppression.
|
||||
|
||||
### Détection de répétition
|
||||
Si je m'apprête à écrire une réponse quasi identique à la précédente
|
||||
(même phrase, même conclusion) → c'est le signal d'une boucle.
|
||||
ARRÊTER et passer en mode "demande de clarification".
|
||||
|
||||
## External vs Internal
|
||||
|
||||
**Safe to do freely:**
|
||||
|
||||
- Read files, explore, organize, learn
|
||||
- Search the web, check calendars
|
||||
- Work within this workspace
|
||||
|
||||
**Ask first:**
|
||||
|
||||
- Sending emails, tweets, public posts
|
||||
- Anything that leaves the machine
|
||||
- Anything you're uncertain about
|
||||
|
||||
## Group Chats
|
||||
|
||||
You have access to your human's stuff. That doesn't mean you _share_ their stuff. In groups, you're a participant — not their voice, not their proxy. Think before you speak.
|
||||
|
||||
### 💬 Know When to Speak!
|
||||
|
||||
In group chats where you receive every message, be **smart about when to contribute**:
|
||||
|
||||
**Respond when:**
|
||||
|
||||
- Directly mentioned or asked a question
|
||||
- You can add genuine value (info, insight, help)
|
||||
- Something witty/funny fits naturally
|
||||
- Correcting important misinformation
|
||||
- Summarizing when asked
|
||||
|
||||
**Stay silent when:**
|
||||
|
||||
- It's just casual banter between humans
|
||||
- Someone already answered the question
|
||||
- Your response would just be "yeah" or "nice"
|
||||
- The conversation is flowing fine without you
|
||||
- Adding a message would interrupt the vibe
|
||||
|
||||
**The human rule:** Humans in group chats don't respond to every single message. Neither should you. Quality > quantity. If you wouldn't send it in a real group chat with friends, don't send it.
|
||||
|
||||
**Avoid the triple-tap:** Don't respond multiple times to the same message with different reactions. One thoughtful response beats three fragments.
|
||||
|
||||
Participate, don't dominate.
|
||||
|
||||
### 😊 React Like a Human!
|
||||
|
||||
On platforms that support reactions (Discord, Slack), use emoji reactions naturally:
|
||||
|
||||
**React when:**
|
||||
|
||||
- You appreciate something but don't need to reply (👍, ❤️, 🙌)
|
||||
- Something made you laugh (😂, 💀)
|
||||
- You find it interesting or thought-provoking (🤔, 💡)
|
||||
- You want to acknowledge without interrupting the flow
|
||||
- It's a simple yes/no or approval situation (✅, 👀)
|
||||
|
||||
**Why it matters:**
|
||||
Reactions are lightweight social signals. Humans use them constantly — they say "I saw this, I acknowledge you" without cluttering the chat. You should too.
|
||||
|
||||
**Don't overdo it:** One reaction per message max. Pick the one that fits best.
|
||||
|
||||
## Tools
|
||||
|
||||
Skills provide your tools. When you need one, check its `SKILL.md`. Keep local notes (camera names, SSH details, voice preferences) in `TOOLS.md`.
|
||||
|
||||
**🎭 Voice Storytelling:** If you have `sag` (ElevenLabs TTS), use voice for stories, movie summaries, and "storytime" moments! Way more engaging than walls of text. Surprise people with funny voices.
|
||||
|
||||
**📝 Platform Formatting:**
|
||||
|
||||
- **Discord/WhatsApp:** No markdown tables! Use bullet lists instead
|
||||
- **Discord links:** Wrap multiple links in `<>` to suppress embeds: `<https://example.com>`
|
||||
- **WhatsApp:** No headers — use **bold** or CAPS for emphasis
|
||||
|
||||
## Règle WhatsApp - Suivi boursier
|
||||
Quand l'utilisateur mentionne "orange", "ora.pa", "cours", "bourse" :
|
||||
- Réponse en **3 lignes maximum**
|
||||
- Format : "ORA.PA : 11,42 € (-0,35%)"
|
||||
- Pas de tableau, pas de description longue
|
||||
- À chaque réponse boursière, **vider le tool result** après usage
|
||||
## Règles d'usage des outils Web Fetch
|
||||
- TOUJOURS limiter Web Fetch à 1500 chars max
|
||||
- Pour la bourse : fetch UNIQUEMENT le prix + variation, pas la page complète
|
||||
- Préférer une API directe quand possible (Yahoo Finance, Alpha Vantage)
|
||||
- Après usage d'un tool, RÉSUMER en 2 lignes max et oublier le contenu brut
|
||||
## 📊 Cours boursier ponctuel (texte seulement, sans graphe)
|
||||
|
||||
Pour un prix chiffré rapide SANS graphe, requête Yahoo directe :
|
||||
```bash
|
||||
curl -fs "https://query1.finance.yahoo.com/v8/finance/chart/SYMBOLE?interval=1d&range=1d" \
|
||||
| jq '.chart.result[0].meta | {price: .regularMarketPrice, prev: .chartPreviousClose, currency}'
|
||||
```
|
||||
Pour un GRAPHE → utiliser le webhook N8N (voir section BOURSE plus haut).
|
||||
|
||||
---
|
||||
|
||||
## Gmail — Hard Constraints (added 2026-06-05)
|
||||
|
||||
### NEVER
|
||||
|
||||
1. **Permanent delete** : interdiction absolue de `messages.delete`.
|
||||
Toujours `messages.trash` (récupérable 30 jours).
|
||||
2. **Toucher la whitelist** : voir `gmail-rules.md` section Whitelist absolue.
|
||||
Si un mail matche un domaine/adresse whitelisté, ABORT silencieusement.
|
||||
3. **Plus de 200 actions par batch** Gmail.
|
||||
4. **Plus de 2000 actions Gmail par jour** sans confirmation explicite humaine.
|
||||
5. **Modifier les labels système** : INBOX peut être retiré (archive),
|
||||
mais SENT/DRAFT/IMPORTANT/STARRED/SPAM/TRASH sont en lecture seule.
|
||||
6. **Lancer une vague sans dry-run préalable** validé par moi.
|
||||
|
||||
### ALWAYS
|
||||
|
||||
1. **Dry-run obligatoire** avant toute action en masse :
|
||||
- Lister les IDs concernés (sample 10 + total)
|
||||
- Présenter à validation humaine
|
||||
- Exécuter seulement après "go" explicite
|
||||
2. **Logger chaque batch** dans `gmail-housekeeping.md` :
|
||||
- Timestamp, règle ID, IDs touchés, action, résultat
|
||||
3. **Respecter `gmail-rules.md`** comme source de vérité unique
|
||||
pour les règles de tri.
|
||||
4. **Vérifier la whitelist au runtime**, pas seulement au design.
|
||||
La whitelist peut évoluer, l'agent doit la relire à chaque vague.
|
||||
5. **En cas de doute** sur un mail (matche partiellement whitelist,
|
||||
pattern ambigu, expéditeur inconnu) → laisser dans inbox + log dans
|
||||
`gmail-doubts.md` pour revue humaine.
|
||||
6. **Pause 5s** entre 2 batchs `gog gmail trash` ou `gog gmail archive`.
|
||||
|
||||
### Format des logs Gmail
|
||||
|
||||
`gmail-housekeeping.md` (append-only) :
|
||||
|
||||
```
|
||||
## 2026-06-XX HH:MM — Vague 1.03 (Quora)
|
||||
- Query: from:quora.com in:inbox older_than:90d
|
||||
- Matched: 487 threads
|
||||
- Sample (10): [id1, id2, ...]
|
||||
- Action: trash
|
||||
- Status: dry-run validated by Thierry at HH:MM
|
||||
- Executed: HH:MM, batch 1/3 (200 OK), batch 2/3 (200 OK), batch 3/3 (87 OK)
|
||||
- Total moved to trash: 487
|
||||
```
|
||||
|
||||
|
||||
## 💓 Heartbeats - Be Proactive!
|
||||
|
||||
When you receive a heartbeat poll (message matches the configured heartbeat prompt), don't just reply `HEARTBEAT_OK` every time. Use heartbeats productively!
|
||||
|
||||
You are free to edit `HEARTBEAT.md` with a short checklist or reminders. Keep it small to limit token burn.
|
||||
|
||||
### Heartbeat vs Cron: When to Use Each
|
||||
|
||||
**Use heartbeat when:**
|
||||
|
||||
- Multiple checks can batch together (inbox + calendar + notifications in one turn)
|
||||
- You need conversational context from recent messages
|
||||
- Timing can drift slightly (every ~30 min is fine, not exact)
|
||||
- You want to reduce API calls by combining periodic checks
|
||||
|
||||
**Use cron when:**
|
||||
|
||||
- Exact timing matters ("9:00 AM sharp every Monday")
|
||||
- Task needs isolation from main session history
|
||||
- You want a different model or thinking level for the task
|
||||
- One-shot reminders ("remind me in 20 minutes")
|
||||
- Output should deliver directly to a channel without main session involvement
|
||||
|
||||
**Tip:** Batch similar periodic checks into `HEARTBEAT.md` instead of creating multiple cron jobs. Use cron for precise schedules and standalone tasks.
|
||||
|
||||
**Things to check (rotate through these, 2-4 times per day):**
|
||||
|
||||
- **Emails** - Any urgent unread messages?
|
||||
- **Calendar** - Upcoming events in next 24-48h?
|
||||
- **Mentions** - Twitter/social notifications?
|
||||
- **Weather** - Relevant if your human might go out?
|
||||
|
||||
**Track your checks** in `memory/heartbeat-state.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"lastChecks": {
|
||||
"email": 1703275200,
|
||||
"calendar": 1703260800,
|
||||
"weather": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to reach out:**
|
||||
|
||||
- Important email arrived
|
||||
- Calendar event coming up (<2h)
|
||||
- Something interesting you found
|
||||
- It's been >8h since you said anything
|
||||
|
||||
**When to stay quiet (HEARTBEAT_OK):**
|
||||
|
||||
- Late night (23:00-08:00) unless urgent
|
||||
- Human is clearly busy
|
||||
- Nothing new since last check
|
||||
- You just checked <30 minutes ago
|
||||
|
||||
**Proactive work you can do without asking:**
|
||||
|
||||
- Read and organize memory files
|
||||
- Check on projects (git status, etc.)
|
||||
- Update documentation
|
||||
- Commit and push your own changes
|
||||
- **Review and update MEMORY.md** (see below)
|
||||
|
||||
### 🔄 Memory Maintenance (During Heartbeats)
|
||||
|
||||
Periodically (every few days), use a heartbeat to:
|
||||
|
||||
1. Read through recent `memory/YYYY-MM-DD.md` files
|
||||
2. Identify significant events, lessons, or insights worth keeping long-term
|
||||
3. Update `MEMORY.md` with distilled learnings
|
||||
4. Remove outdated info from MEMORY.md that's no longer relevant
|
||||
|
||||
Think of it like a human reviewing their journal and updating their mental model. Daily files are raw notes; MEMORY.md is curated wisdom.
|
||||
|
||||
The goal: Be helpful without being annoying. Check in a few times a day, do useful background work, but respect quiet time.
|
||||
|
||||
## Make It Yours
|
||||
|
||||
This is a starting point. Add your own conventions, style, and rules as you figure out what works.
|
||||
|
||||
## Related
|
||||
|
||||
- [Default AGENTS.md](/reference/AGENTS.default)
|
||||
128
workspace/HANDOFF.md
Normal file
128
workspace/HANDOFF.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# HANDOFF — OpenClaw — État global
|
||||
|
||||
**Date :** 2026-06-25
|
||||
**Session :** Passage du HANDOFF bourse-only à un dashboard multi-domaines.
|
||||
**Statut global :** 🟢 opérationnel — Bourse N8N en prod, Gmail actif, WhatsApp appairé.
|
||||
|
||||
---
|
||||
|
||||
## 📋 En-tête / Statut global
|
||||
|
||||
| Item | Valeur |
|
||||
|---|---|
|
||||
| Prochaine priorité | Valider le fix du cron `orange-cloture` (prochain run 26/06 17:40) |
|
||||
| Dernière refonte majeure | Bourse via N8N + passage modèle Thinking (voir handoff dédié) |
|
||||
| Backend LLM | `vllm/qwen3-vl` (Thinking), `maxTokens: 16384`, `contextWindow: 65536` |
|
||||
| WhatsApp | Appairé pour `+33607148216` |
|
||||
| GUI / Reasoning | Défaut conseillé **Medium** ; max tokens GUI à régler manuellement |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tableau de bord par domaine
|
||||
|
||||
| Domaine | État | Source de vérité | Prochaine action | Dernier événement |
|
||||
|---|---|---|---|---|
|
||||
| **Bourse** | 🟢 Actif | `workspace/bourse-config.json` + workflow N8N `4bluZIeN3TnbzIrv` | Valider fix `orange-cloture` (timeout 600s + prompt simplifié) au prochain run 26/06 17:40 | Refonte N8N 2026-06-24 |
|
||||
| **Gmail** | 🟢 Actif | `workspace/gmail-rules.md` + filtres natifs Phase E | Phase F : archive Philippot + Ulys (restes) ; surveiller filtres Phase E | Filtres Phase E créés 2026-06-25 ✅ |
|
||||
| **WhatsApp** | 🟢 Actif | `openclaw.json` (canal `custom-1`) + `workspace/USER.md` | Maintenir appairage / validation envoi images | Appairage confirmé |
|
||||
| **LLM / Infra** | 🟢 Actif | `openclaw.json` (`vllm/qwen3-vl`, `reasoning: true`) | Surveillance timeouts vs Thinking ; régler max tokens GUI | `maxTokens` porté à 16384 |
|
||||
| **Voice / TTS** | ⚫ Désactivé | `openclaw.json` (skills `sag`, `voice-*`, `openai-whisper` off) | Rien à faire sauf demande explicite | Désactivé |
|
||||
| **Heartbeat** | ⚫ Désactivé | `workspace/HEARTBEAT.md` vide, `agents.defaults.heartbeat.every: "0"` | Rien à faire sauf activation explicite | Désactivé |
|
||||
|
||||
---
|
||||
|
||||
## 📈 Bourse — Résumé opérationnel
|
||||
|
||||
- **Principe** : agent = interlocuteur ; N8N = exécutant. Aucune donnée boursière n'est éditée à la main.
|
||||
- **Workflow N8N** : `Bourse — Graphe multi-tickers (v3)` — ID `4bluZIeN3TnbzIrv`
|
||||
- **Webhook** : `POST https://n8n.airtria.pro/webhook/bourse-graphe`
|
||||
- **Watchlist** : définie dans `workspace/bourse-config.json` (actuellement `ORA.PA`, `TTE.PA`)
|
||||
- **Cron actif** : `orange-cloture` (`40 17 * * 1-5` Europe/Paris) → appelle le webhook et envoie le PNG sur WhatsApp.
|
||||
- **Crons historiques obsolètes** : `orange-ouverture`, `orange-intraday`, `orange-chart-update` — tous **désactivés** dans `state/openclaw.sqlite` (ne pas les réactiver).
|
||||
- **Détail de la refonte** : voir `handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md`
|
||||
|
||||
---
|
||||
|
||||
## 📬 Gmail — Résumé opérationnel
|
||||
|
||||
- **CLI** : `gog` v0.21.0, OAuth persisté.
|
||||
- **Règles** : `workspace/gmail-rules.md`
|
||||
- **Logs d'actions** : `workspace/gmail-housekeeping.md`
|
||||
- **Cron actif** : `daily-email-report` (`30 8 * * *` Europe/Paris) → résumé quotidien sur WhatsApp.
|
||||
- **Filtres Phase E** : 18 filtres natifs créés (2026-06-25) → labels `Promos`, `Dev-Tools`, `Social`, plus `Receipts`/`Newsletters` existants.
|
||||
- **Next steps** : Phase F (restes Philippot/Ulys), surveiller l’efficacité des filtres Phase E.
|
||||
|
||||
---
|
||||
|
||||
## 📱 WhatsApp
|
||||
|
||||
- **Compte** : `custom-1`
|
||||
- **Numéro autorisé** : `+33607148216`
|
||||
- **Capacités confirmées** : texte, image PNG/JPEG, commande `/new`.
|
||||
- **Format bourse** : 3 lignes max + PNG en pièce jointe.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Risques & vigilance partagés
|
||||
|
||||
1. **Cron `orange-cloture` en timeout corrigé** : timeout porté de 240 s à 600 s, prompt simplifié, compteurs d'erreur réinitialisés. Prochain run : 26/06 17:40. Le webhook N8N a été testé : ~1,3 s pour obtenir le PNG.
|
||||
2. **MCP N8N** : les outils `update_workflow` / `activate` sont buggés. Préférer l'API REST N8N directe (`PUT /workflows/{id}` puis `POST /workflows/{id}/activate`).
|
||||
3. **Divergence modèles** : `agents/main/agent/models.json` référence encore des modèles Codex/GPT, alors que le runtime utilise `vllm/qwen3-vl`. Risque de confusion GUI.
|
||||
4. **Ownership fichiers** : ✅ résolu le 25/06 — plus de fichiers `root` hors `node_modules` / `.git`.
|
||||
5. **Fichiers obsolètes bourse** : `orange-bourse.md`, `get_quote.py`, `generate_chart.py`, `clean_bourse_md.py` sont archivés dans `workspace/_archive-bourse-20260624/`. **Ne pas les réutiliser.**
|
||||
|
||||
---
|
||||
|
||||
## 📅 Journal d'exécution récent
|
||||
|
||||
| Date (Paris) | Domaine | Événement | Résultat |
|
||||
|---|---|---|---|
|
||||
| 2026-06-25 08:30 | Gmail | `daily-email-report` | ✅ livré WhatsApp |
|
||||
| 2026-06-25 17:40 | Bourse | `orange-cloture` | ⚠️ timeout |
|
||||
| 2026-06-25 ~19:30 | Gmail | Audit Phase E (2000 threads sample) | ✅ rapport dans `workspace/gmail-phase-e-audit-20260625.md` |
|
||||
| 2026-06-25 ~20:00 | Gmail | 18 filtres natifs Phase E + cleanup ~889 messages | ✅ |
|
||||
| 2026-06-25 ~20:15 | Gmail | Phase F — Philippot + Ulys inbox vides | ✅ |
|
||||
| 2026-06-24 | Bourse | Refonte N8N validée | ✅ graphes testés, workflow actif |
|
||||
|
||||
---
|
||||
|
||||
## ✅ TODOs actifs (cross-domaines)
|
||||
|
||||
| # | Action | Domaine | Priorité | Statut |
|
||||
|---|---|---|---|---|
|
||||
| 1 | Valider le cron `orange-cloture` après fix (timeout 600s, prochain run 26/06 17:40) | Bourse | Haut | ⏳ |
|
||||
| 2 | Phase F Gmail : archive Philippot + Ulys (restes non filtrés) | Gmail | Moyen | ✅ |
|
||||
| 3 | Surveiller l’efficacité des filtres Phase E (1–2 semaines) | Gmail | Moyen | ⏳ |
|
||||
| 4 | Régler le max tokens GUI à ~8192 (navigateur) | LLM/GUI | Haut | ⏳ |
|
||||
| 5 | Tester "2 graphes séparés zoomés" | Bourse | Moyen | ⏳ |
|
||||
|
||||
---
|
||||
|
||||
## 📚 Liens rapides (source de vérité)
|
||||
|
||||
| Besoin | Fichier |
|
||||
|---|---|
|
||||
| Comportement + hard constraints | `workspace/AGENTS.md` |
|
||||
| Skills / syntaxe des commandes | `workspace/TOOLS.md` |
|
||||
| Mémoire long terme | `workspace/MEMORY.md` |
|
||||
| État global / transfert | `workspace/HANDOFF.md` (ce fichier) |
|
||||
| Watchlist bourse | `workspace/bourse-config.json` |
|
||||
| Règles Gmail | `workspace/gmail-rules.md` |
|
||||
| Jobs cron | `state/openclaw.sqlite` (table `cron_jobs`) |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Reprise rapide pour une nouvelle session
|
||||
|
||||
1. Lire `workspace/AGENTS.md` (comportement + red lines).
|
||||
2. Lire `workspace/HANDOFF.md` (état global + TODOs).
|
||||
3. Aller au domaine concerné : `workspace/TOOLS.md` pour la syntaxe, `workspace/bourse-config.json` pour la bourse, `workspace/gmail-rules.md` pour Gmail.
|
||||
4. Vérifier les TODOs non résolus ci-dessus avant de commencer une tâche.
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Historique des handoffs détaillés
|
||||
|
||||
- `handoffs/HANDOFF-2026-06-09.md` — Session initiale / contexte global
|
||||
- `handoffs/HANDOFF-2026-06-09-GMAIL.md` — Refonte Gmail / GOG
|
||||
- `handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md` — Refonte Bourse N8N + Thinking (détail complet)
|
||||
158
workspace/MEMORY.md
Normal file
158
workspace/MEMORY.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# Mémoire opérationnelle — MEMORY.md
|
||||
|
||||
> Connaissances persistantes pour l'agent. Lu à chaque création de session.
|
||||
|
||||
---
|
||||
|
||||
## Identité du système
|
||||
|
||||
**OpenClaw** : v2026.6.5 (mis à jour le 11/6/2026)
|
||||
**Hébergement** : Synology DS920+ ARCHIVE3 (RAM 20Gi, /volume1/docker/)
|
||||
**LLM backend** : `Qwen/Qwen3-VL-30B-A3B-Thinking-FP8` servi par vLLM sur DGX Spark, `--served-model-name=qwen3-vl`
|
||||
**Utilisateur principal** : Thierry Tallagrand (`+33607148216`)
|
||||
**Vision projet** : système d'orchestration personnelle (bourse via N8N, mail multi-comptes, photos→sheets, WhatsApp/GUI).
|
||||
|
||||
---
|
||||
|
||||
## Capacités opérationnelles
|
||||
|
||||
### Gmail (gog CLI v0.21.0) — ACTIF
|
||||
- ✅ **Envoyer mail** : `gog gmail send --to ... --subject "..." --body "..." --attach <fichier>`
|
||||
- ✅ **Lire/chercher** : `gog gmail search "..." -j --max N`
|
||||
- ✅ **Brouillons** : `gog gmail drafts create/list/send/delete`
|
||||
- ✅ **Trier** : `gog gmail trash/archive` (toujours `--dry-run` d'abord)
|
||||
- ✅ **Labels** : `gog gmail labels list`, `gog gmail messages modify --add-label/--remove-label`
|
||||
|
||||
### WhatsApp — ACTIF
|
||||
- ✅ Envoi messages texte vers l'utilisateur principal
|
||||
- ✅ Envoi images PNG/JPEG — SVG interdits
|
||||
- ✅ Commande `/new` pour nouvelle session DM
|
||||
|
||||
### Bourse — Workflow N8N (refonte 2026-06-24)
|
||||
- ✅ **Graphe** : webhook N8N `POST https://n8n.airtria.pro/webhook/bourse-graphe` (workflow `4bluZIeN3TnbzIrv`)
|
||||
- ✅ **Watchlist** : éditable dans `workspace/bourse-config.json`
|
||||
- ✅ **Prix texte rapide** : `curl -fs "https://query1.finance.yahoo.com/v8/finance/chart/SYMBOLE?interval=1d&range=1d" | jq '.chart.result[0].meta | {price: .regularMarketPrice, prev: .chartPreviousClose, currency}'`
|
||||
- ✅ **Cron** : `orange-cloture` (40 17 * * 1-5) via le workflow N8N
|
||||
- ⚠️ **OBSOLÈTES** (ne plus utiliser) : `orange-bourse.md`, `get_quote.py`, `generate_chart.py`, `clean_bourse_md.py` — archivés dans `workspace/_archive-bourse-20260624/`
|
||||
|
||||
### Filesystem & exec
|
||||
- ✅ Lecture/écriture dans `/home/node/.openclaw/workspace/`
|
||||
- ✅ Exec `python3`, `node`, `curl`, `jq`, `git`
|
||||
- ✅ Aucun `pip install` runtime
|
||||
|
||||
### Web
|
||||
- ✅ `web_fetch` (1500 chars max), `web_search` (10 résultats max)
|
||||
|
||||
---
|
||||
|
||||
## Hard constraint GLOBAL — Anti-amnésie
|
||||
|
||||
**L'agent NE DIT JAMAIS "je ne peux pas faire X" sans vérification.**
|
||||
|
||||
Procédure obligatoire avant tout refus :
|
||||
1. Chercher X dans `TOOLS.md` (sections 1-9)
|
||||
2. Si X est documenté → tenter la commande et rapporter le résultat
|
||||
3. Si erreur → rapporter l'erreur EXACTE, pas l'incapacité
|
||||
4. Si vraiment non documenté → demander précision à l'utilisateur
|
||||
|
||||
**Exemples de refus INTERDITS** :
|
||||
- "Je ne peux pas envoyer un mail" (faux : Gmail send actif)
|
||||
- "Je n'ai pas accès à Gmail" (faux : auth persistée)
|
||||
- "Je suis un assistant sans capacités" (faux : voir `TOOLS.md`)
|
||||
- "Gmail à venir" (faux : opérationnel depuis 9/6/2026)
|
||||
- "Je ne peux pas tracer un graphe boursier" (faux : webhook N8N actif depuis 24/6/2026)
|
||||
|
||||
---
|
||||
|
||||
## Bourse — Architecture N8N (source de vérité actuelle)
|
||||
|
||||
### Principe
|
||||
Agent = interlocuteur. N8N = exécutant. Aucune donnée n'est editée à la main.
|
||||
|
||||
### Source de vérité
|
||||
- Fichier : `workspace/bourse-config.json`
|
||||
- Tickers FR : suffixe `.PA` (ORA.PA, TTE.PA)
|
||||
- Tickers US : sans suffixe (NVDA, AAPL)
|
||||
- Aliases et options par défaut définis dans le JSON
|
||||
|
||||
### Crons actifs
|
||||
- `orange-cloture` (`40 17 * * 1-5` Europe/Paris) : appelle le webhook N8N et envoie le PNG sur WhatsApp.
|
||||
- Actuellement en timeout — voir `workspace/HANDOFF.md` TODOs.
|
||||
|
||||
### Crons bourse obsolètes (désactivés dans SQLite)
|
||||
- `orange-ouverture`
|
||||
- `orange-intraday`
|
||||
- `orange-chart-update`
|
||||
|
||||
### Format réponse standard
|
||||
- Cours simple : `ORA.PA : 17,86€ (+1,16%)`
|
||||
- Indisponible/marché fermé : dire "Aucune donnée", ne pas inventer
|
||||
- Graphe : 3 lignes max + PNG attaché
|
||||
|
||||
---
|
||||
|
||||
## Gmail — Suivi des phases
|
||||
|
||||
### Phase terminées
|
||||
- Re-auth OAuth + GOG_HOME persisté (2026-06-09)
|
||||
- Phase D : 12 401 mails trashés
|
||||
|
||||
### Phases terminées
|
||||
- Phase E : filtres natifs Gmail anti-spam (2026-06-25) — 18 filtres créés, ~889 messages archivés
|
||||
- Phase F : archive Philippot + Ulys (2026-06-25) — inbox vides, futurs messages filtrés
|
||||
|
||||
### Phases en attente
|
||||
- Phase G : longue traîne newsletters
|
||||
|
||||
### Cron actif
|
||||
- `daily-email-report` (`30 8 * * *` Europe/Paris) → résumé quotidien WhatsApp des dernières 24h
|
||||
|
||||
---
|
||||
|
||||
## TODO actuel
|
||||
|
||||
### Haute priorité
|
||||
- Stabiliser le cron `orange-cloture` (timeouts)
|
||||
- Régler le max tokens GUI à ~8192 (navigateur)
|
||||
|
||||
### Moyenne priorité
|
||||
- Tester "2 graphes séparés zoomés" (2× `beginAtZero:false`)
|
||||
- Surveiller l’efficacité des filtres Phase E (1–2 semaines)
|
||||
- Phase G Gmail : longue traîne newsletters
|
||||
|
||||
### Basse priorité
|
||||
- Aligner `agents/main/agent/models.json` avec `vllm/qwen3-vl`
|
||||
- Augmenter `OPENCLAW_CRON_JOB_TIMEOUT_MS` si le Thinking déborde
|
||||
|
||||
---
|
||||
|
||||
## Apprentissages structurants
|
||||
|
||||
### Sessions précédentes
|
||||
- **9/6/2026** : Re-auth OAuth Gmail + GOG_HOME persisté (test compose down/up validé)
|
||||
- **10/6/2026** : Fix cron orange-intraday (prompt "OK" → vrai cours), RAM upgrade 16GB
|
||||
- **10/6/2026** : Découverte SVG incompatible WhatsApp + bug tri chronologique
|
||||
- **23/6/2026** : Migration du cron email horaire (`hourly-email-check`) vers un rapport quotidien (`daily-email-report`) à 8h30 Europe/Paris. Source de vérité : `state/openclaw.sqlite` (pas les JSON obsolètes). Format : résumé court global + détail des messages importants.
|
||||
- **24-25/6/2026** : Refonte bourse via N8N — suppression des scripts Python, du fichier `orange-bourse.md` et des workflows cassés ; passage au modèle Thinking.
|
||||
- **25/6/2026** : Phase E Gmail (filtres natifs) + Phase F (archive Philippot/Ulys) terminées. Audit via SSH sur Synology + `gog` dans container `openclaw-gateway`.
|
||||
|
||||
### Patterns à respecter
|
||||
- Test après chaque modification (checklist comportementale)
|
||||
- Backup AVANT chaque mutation (`.bak-<TS>` avec timestamp)
|
||||
- 3 couches doivent rester alignées : Tools/Skills (`TOOLS.md`) + Knowledge (`MEMORY.md`) + Identity (`SOUL.md` / `IDENTITY.md`)
|
||||
- L'agent ne modifie jamais des fichiers directement quand un outil/service est la source de vérité (cas bourse : `bourse-config.json` OK, mais les prix viennent de Yahoo via N8N)
|
||||
|
||||
---
|
||||
|
||||
## Méta : où trouver quoi
|
||||
|
||||
| Sujet | Fichier de référence |
|
||||
|---|---|
|
||||
| Skills opérationnels (syntaxe gog, webhook, etc.) | `TOOLS.md` |
|
||||
| Comportement, hard constraints | `AGENTS.md` |
|
||||
| Identité, persona | `SOUL.md`, `IDENTITY.md` |
|
||||
| État global / transfert inter-sessions | `HANDOFF.md` |
|
||||
| Mode batch/cron silencieux | `HEARTBEAT.md` |
|
||||
| Règles métier Gmail | `gmail-rules.md` |
|
||||
| Données bourse (watchlist + options) | `bourse-config.json` |
|
||||
| Mémoire évolutive (ce fichier) | `MEMORY.md` |
|
||||
287
workspace/TOOLS.md
Normal file
287
workspace/TOOLS.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# Outils opérationnels (TOOLS.md)
|
||||
|
||||
> **Source de vérité skills.** Ce fichier liste les capacités RÉELLEMENT
|
||||
> disponibles pour l'agent. Si une capacité y figure, l'agent PEUT et DOIT
|
||||
> l'utiliser. Si l'utilisateur demande une action documentée ici, l'agent
|
||||
> NE DOIT PAS répondre "je ne peux pas".
|
||||
|
||||
---
|
||||
### 1.0 IMPORTANT — Comment l'agent invoque les commandes gog
|
||||
|
||||
`gog` n'est PAS un tool natif d'OpenClaw. C'est une commande CLI installée
|
||||
dans le container PATH. L'agent DOIT l'invoquer via le tool natif `exec`
|
||||
(ou son alias `bash`) avec la commande gog complète comme argument.
|
||||
|
||||
INTERDIT (l'agent essaye d'appeler `gog` comme tool → ÉCHEC garanti) :
|
||||
tool: gog
|
||||
args: { "operation": "send", "to": "...", "subject": "..." }
|
||||
|
||||
OBLIGATOIRE (l'agent appelle `exec` avec la commande gog complète) :
|
||||
tool: exec
|
||||
args: { "command": "gog gmail send -a tallagrand.thierry@gmail.com --to ... --subject ... --body ..." }
|
||||
|
||||
Toutes les commandes documentées ci-dessous (sections 1.1 à 1.6) doivent
|
||||
être invoquées via `exec` ou `bash` avec la commande complète comme argument.
|
||||
|
||||
### Pattern général pour TOUTE commande CLI dans ce fichier
|
||||
|
||||
Cette règle s'applique aussi à : `python3`, `curl`, `jq`, `git`, `node`,
|
||||
et tout binaire installé dans le container.
|
||||
|
||||
Bon réflexe :
|
||||
tool: exec, args: { "command": "<binaire> <arguments>" }
|
||||
|
||||
Mauvais réflexe :
|
||||
tool: <binaire>, args: { ... }
|
||||
|
||||
|
||||
## 1. Gmail — gog CLI v0.21.0 (OPÉRATIONNEL)
|
||||
|
||||
**Statut** : ACTIF depuis 9 juin 2026. Auth OAuth Google persistée.
|
||||
**Compte** : tallagrand.thierry@gmail.com
|
||||
**Path keyring** : /home/node/.openclaw/gogcli/data/keyring/
|
||||
**Doc complète** : workspace/gmail-rules.md
|
||||
|
||||
### 1.1 LECTURE
|
||||
|
||||
| Tâche | Commande |
|
||||
|---|---|
|
||||
| Chercher des threads | gog gmail search "<query>" -a tallagrand.thierry@gmail.com -j --max N |
|
||||
| Lister labels | gog gmail labels list -a tallagrand.thierry@gmail.com |
|
||||
| Détail d'un thread | gog gmail thread get <id> -a tallagrand.thierry@gmail.com -j |
|
||||
| Détail d'un message | gog gmail messages get <id> -a tallagrand.thierry@gmail.com -j |
|
||||
|
||||
### 1.2 ENVOI (capacité ACTIVE)
|
||||
|
||||
Syntaxe :
|
||||
|
||||
gog gmail send -a tallagrand.thierry@gmail.com --to <destinataire> --subject "<sujet>" --body "<corps>"
|
||||
|
||||
Flags utiles :
|
||||
- --cc=<email>, --bcc=<email> : copies
|
||||
- --body-html="<html>" : version HTML (alternative à --body)
|
||||
- --attach=<path> : pièce jointe (répétable, ex: graphe PNG)
|
||||
- --reply-to-message-id=<id> : répondre à un mail spécifique
|
||||
- --dry-run : simuler sans envoyer
|
||||
- -j : sortie JSON
|
||||
|
||||
Exemple concret avec attachement :
|
||||
|
||||
gog gmail send -a tallagrand.thierry@gmail.com --to tallagrand.thierry@gmail.com --subject "Cours ORA" --body "ORA.PA : 17,86€ (+1,16%)" --attach /home/node/.openclaw/workspace/charts/ora-2026-06-11-1700.png
|
||||
|
||||
### 1.3 BROUILLONS (alternative prudente)
|
||||
|
||||
| Tâche | Commande |
|
||||
|---|---|
|
||||
| Créer un brouillon | gog gmail drafts create -a <email> --to <dest> --subject "..." --body "..." |
|
||||
| Lister brouillons | gog gmail drafts list -a <email> |
|
||||
| Envoyer un brouillon | gog gmail drafts send <draftId> -a <email> |
|
||||
| Supprimer brouillon | gog gmail drafts delete <draftId> -a <email> |
|
||||
|
||||
### 1.4 MUTATIONS — `--dry-run` OBLIGATOIRE avant mass action
|
||||
|
||||
| Tâche | Commande |
|
||||
|---|---|
|
||||
| Mettre à la corbeille | gog gmail trash "<query>" -a <email> --dry-run puis --force |
|
||||
| Archiver | gog gmail archive "<query>" -a <email> --dry-run puis --force |
|
||||
| Modifier labels | gog gmail messages modify <id> -a <email> --add-label X --remove-label Y |
|
||||
|
||||
### 1.5 Mapping question utilisateur → action
|
||||
|
||||
| Question | Commande à utiliser |
|
||||
|---|---|
|
||||
| "Envoie un mail à X avec sujet Y et corps Z" | gog gmail send --to X --subject "Y" --body "Z" |
|
||||
| "Envoie-moi un mail" | gog gmail send --to tallagrand.thierry@gmail.com ... |
|
||||
| "Combien de mails j'ai aujourd'hui" | gog gmail search "in:inbox newer_than:1d" -j --max 100 |
|
||||
| "Trie mes promos vieilles" | gog gmail trash "category:promotions older_than:30d" --dry-run |
|
||||
| "Liste les mails de X" | gog gmail search "from:X" -j --max N |
|
||||
|
||||
### 1.6 Hard constraints Gmail
|
||||
|
||||
- INTERDIT : "je ne peux pas envoyer un mail" — la capacité EST active
|
||||
- INTERDIT : "Gmail à venir" — c'est OPÉRATIONNEL depuis 9/6/2026
|
||||
- Si une commande échoue, RAPPORTER l'erreur réelle (stderr)
|
||||
- 2 erreurs syntax/auth max → STOP, demander à l'utilisateur
|
||||
- --dry-run avant action en masse (>5 mails)
|
||||
- Container headless : pas de browser disponible
|
||||
|
||||
---
|
||||
|
||||
## 2. WhatsApp — Plugin OpenClaw
|
||||
|
||||
### 2.1 Capacités confirmées
|
||||
- Envoi message texte vers utilisateur (+33607148216)
|
||||
- Envoi image PNG/JPEG (à valider Phase E.5)
|
||||
- Commande slash /new : nouvelle session DM (testée 10/6 OK)
|
||||
|
||||
### 2.2 Format restrictions
|
||||
- AUTORISÉS : PNG, JPEG, WebP, PDF, Office docs, archives
|
||||
- INTERDIT : SVG (rejeté par WhatsApp Cloud API avec OutboundDeliveryError)
|
||||
|
||||
### 2.3 Mapping question → action
|
||||
|
||||
| Question | Action |
|
||||
|---|---|
|
||||
| "Envoie-moi un message WhatsApp" | tool whatsapp send_message |
|
||||
| "Envoie le graphe sur WhatsApp" | tool whatsapp send_message + image PNG attachée |
|
||||
| Cron horaire bourse | delivery.mode=announce → dernière réponse agent envoyée auto |
|
||||
|
||||
### 2.4 Hard constraint
|
||||
- Si erreur "OutboundDeliveryError image/svg+xml" : convertir en PNG
|
||||
- Si l'envoi WhatsApp échoue : rapporter l'erreur exacte, ne pas re-tenter en boucle
|
||||
|
||||
---
|
||||
|
||||
## 3. Bourse — Workflow N8N (REFONTE 2026-06-24)
|
||||
|
||||
> ⚠️ OBSOLÈTES (ne plus utiliser) : `generate_chart.py`, `get_quote.py`,
|
||||
> `clean_bourse_md.py`, `orange-bourse.md`. Toute la bourse passe par N8N.
|
||||
|
||||
### 3.1 Webhook graphe (outil principal)
|
||||
- URL : `https://n8n.airtria.pro/webhook/bourse-graphe` (POST JSON)
|
||||
- Workflow N8N id : `4bluZIeN3TnbzIrv` ("Bourse — Graphe multi-tickers (v3)")
|
||||
- Renvoie : un PNG (image/png) prêt pour WhatsApp
|
||||
- Body JSON (tout optionnel) :
|
||||
- `tickers` : liste de symboles Yahoo, ex ["ORA.PA","TTE.PA","NVDA"]
|
||||
- `range` : 1d|5d|1mo|3mo|6mo|1y (def 5d)
|
||||
- `interval` : 15m|60m|1d (def 60m)
|
||||
- `beginAtZero` : true (axe Y depuis 0) | false (zoom variations)
|
||||
- `title` : titre optionnel
|
||||
- Gestion marché fermé / ticker invalide : renvoie un PNG "Aucune donnée"
|
||||
(jamais d'invention de cours).
|
||||
|
||||
Exemple :
|
||||
```bash
|
||||
curl -s -X POST "https://n8n.airtria.pro/webhook/bourse-graphe" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tickers":["ORA.PA","TTE.PA"],"beginAtZero":true}' \
|
||||
-o /home/node/.openclaw/workspace/charts/bourse.png
|
||||
```
|
||||
|
||||
### 3.2 Watchlist = bourse-config.json
|
||||
- Path : `/home/node/.openclaw/workspace/bourse-config.json`
|
||||
- Source de vérité des tickers suivis + options par défaut.
|
||||
- L'agent ÉDITE ce fichier pour ajouter/retirer une valeur.
|
||||
|
||||
### 3.3 Prix texte rapide (sans graphe)
|
||||
- `curl -fs "https://query1.finance.yahoo.com/v8/finance/chart/SYMBOLE?interval=1d&range=1d" | jq '.chart.result[0].meta'`
|
||||
|
||||
### 3.4 Modifier le comportement du graphe
|
||||
- Via MCP `n8n-mcp` (update_workflow) ou l'API n8n, workflow id `4bluZIeN3TnbzIrv`.
|
||||
- Node JS "Fetch + Build QuickChart" = logique fetch+rendu. Rendu via QuickChart `version:"4"`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Filesystem workspace
|
||||
|
||||
### 4.1 Path racine
|
||||
/home/node/.openclaw/workspace/
|
||||
|
||||
### 4.2 Capacités
|
||||
- Lecture/écriture de tout fichier dans workspace
|
||||
- Exec scripts python3, bash dans workspace/scripts/
|
||||
- PAS d'install pip durant runtime (figé Dockerfile : yfinance, requests)
|
||||
|
||||
### 4.3 Fichiers structurants
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| MEMORY.md | Connaissances persistantes |
|
||||
| AGENTS.md | Comportement, hard constraints |
|
||||
| SOUL.md / IDENTITY.md | Identité, persona |
|
||||
| TOOLS.md (ce fichier) | Skills opérationnel |
|
||||
| HEARTBEAT.md | Mode batch/cron silencieux |
|
||||
| gmail-rules.md | Règles métier Gmail |
|
||||
| HANDOFF.md | État global / transfert inter-sessions |
|
||||
| bourse-config.json | Watchlist + options du graphe bourse (obsolète : orange-bourse.md) |
|
||||
|
||||
---
|
||||
|
||||
## 5. Outils système disponibles
|
||||
|
||||
### 5.1 Dans le container
|
||||
- python3 (3.11), pip3 (figé build-time)
|
||||
- node (Node.js), npm
|
||||
- curl, jq, git, tini
|
||||
- gog (Google APIs CLI v0.21.0)
|
||||
|
||||
### 5.2 Web
|
||||
- web_fetch : ~1500 chars max par fetch
|
||||
- web_search : 10 résultats max
|
||||
- Toutes URLs publiques HTTPS
|
||||
|
||||
---
|
||||
|
||||
## 6. Bourse — Pipeline (refonte N8N 2026-06-24)
|
||||
|
||||
### 6.1 Architecture
|
||||
- L'agent reçoit la demande → POST webhook N8N (section 3.1) → PNG → WhatsApp.
|
||||
- Watchlist dans `bourse-config.json` (section 3.2).
|
||||
- Cron clôture (40 17 * * 1-5, Europe/Paris) : appelle le webhook et envoie le PNG WhatsApp.
|
||||
|
||||
### 6.2 Format réponse standard
|
||||
- Avec graphe : 3 lignes texte + PNG attaché.
|
||||
- Prix simple : `ORA.PA : 16,89€ (-0,68%)`.
|
||||
- Marché fermé/indispo : le PNG "Aucune donnée" + le dire, ne pas inventer.
|
||||
|
||||
---
|
||||
|
||||
## 7. Hard constraint GLOBAL — Anti-amnésie
|
||||
|
||||
L'agent NE DOIT JAMAIS dire "je ne peux pas faire X" sans avoir vérifié
|
||||
dans ce fichier (TOOLS.md) si X est une capacité documentée.
|
||||
|
||||
### Procédure mentale obligatoire avant de refuser :
|
||||
1. Vérifier dans TOOLS.md si X est documenté
|
||||
2. Si oui → tenter la commande, rapporter le résultat (succès ou erreur exacte)
|
||||
3. Si erreur, demander de l'aide à l'utilisateur (pas prétendre l'incapacité)
|
||||
4. Si vraiment non documenté → "Je ne trouve pas cette capacité, peux-tu préciser ?"
|
||||
|
||||
### Exemples de refus INTERDITS
|
||||
- "Je ne peux pas envoyer de mail" (faux : voir section 1.2)
|
||||
- "Je n'ai pas accès à Gmail" (faux : voir section 1)
|
||||
- "Gmail est à venir" (faux : opérationnel depuis 9/6/2026)
|
||||
- "Je suis dans un environnement sécurisé sans capacité" (faux : capacités listées ci-dessus)
|
||||
|
||||
### Nouvelle obligation (11/6/2026 post-test)
|
||||
|
||||
L'agent NE DOIT JAMAIS dire "tool 'gog' isn't available" ou équivalent.
|
||||
`gog` n'est jamais un tool, c'est une commande shell.
|
||||
Si l'agent voit "gog" dans une instruction, il DOIT utiliser `exec` :
|
||||
tool: exec, args: { "command": "gog gmail send ..." }
|
||||
|
||||
Idem pour python3, curl, jq, git, node, et tout binaire CLI :
|
||||
ces commandes passent TOUJOURS par `exec` ou `bash`, jamais comme tool direct.
|
||||
|
||||
---
|
||||
|
||||
## 8. Procédure d'ajout d'outil
|
||||
1. Documenter dans TOOLS.md (ce fichier) avec syntaxe exacte
|
||||
2. Ajouter mapping question→action (section 1.5, 2.3, etc.)
|
||||
3. Ajouter hard constraint si nécessaire
|
||||
4. Tester en dashboard ou WhatsApp /new
|
||||
5. Backup TOOLS.md avant modification (.bak-<TS>)
|
||||
|
||||
---
|
||||
|
||||
## 9. Gmail daily cron
|
||||
|
||||
### 9.1 Job actif
|
||||
|
||||
| Cron | Schedule | Rôle | Canal |
|
||||
|---|---|---|---|
|
||||
| `daily-email-report` | `30 8 * * *` Europe/Paris | Résumé quotidien Gmail des dernières 24h | WhatsApp `announce` vers `+33607148216` |
|
||||
|
||||
### 9.2 Format de réponse attendu
|
||||
|
||||
- Ligne 1 : résumé global court (ex: « Gmail : 3 nouveaux, 1 important »).
|
||||
- Lignes suivantes : détail UNIQUEMENT les messages importants (livraisons, rendez-vous, alertes, factures).
|
||||
- Pour chaque message important : expéditeur, sujet, date/heure d'arrivée.
|
||||
- Maximum 5 messages détaillés.
|
||||
- Réponse en français.
|
||||
- Ignorer les promotions et newsletters dans le détail.
|
||||
|
||||
### 9.3 Source de vérité
|
||||
|
||||
- Le job est défini dans `state/openclaw.sqlite`, table `cron_jobs`.
|
||||
- Les fichiers `cron/jobs.json*` sont des migrations obsolètes d'anciens jobs bourse. Ne PAS les utiliser pour modifier ce cron.
|
||||
|
||||
8
workspace/cron/README.md
Normal file
8
workspace/cron/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Cron legacy directory
|
||||
|
||||
> ⚠️ Les fichiers `jobs.json*` et `orange-monitor-state.json` ont été archivés dans
|
||||
> `workspace/_archive-bourse-20260624/legacy-cron/` car ils constituent des migrations obsolètes.
|
||||
>
|
||||
> **Source de vérité actuelle :** `state/openclaw.sqlite`, table `cron_jobs`.
|
||||
>
|
||||
> Ne pas rééditer les fichiers JSON ici : le runtime lit les jobs depuis SQLite.
|
||||
181
workspace/gmail-housekeeping.md
Normal file
181
workspace/gmail-housekeeping.md
Normal file
@@ -0,0 +1,181 @@
|
||||
|
||||
## 2026-06-05 20:23:00 — Vague 1 batch run
|
||||
|
||||
| Règle | Description | Total trashed | Batchs |
|
||||
|---|---|---:|---:|
|
||||
| V1.01 | Rustica | 0 | 1 |
|
||||
| V1.02 | TAAFT | 240 | 1 |
|
||||
| V1.03 | Quora | 720 | 3 |
|
||||
| V1.04 | Bricomarché | 0 | 1 |
|
||||
| V1.05 | Beehiiv | 1 | 1 |
|
||||
| V1.06 | Carrefour | 218 | 1 |
|
||||
| V1.07 | Cdiscount | 240 | 1 |
|
||||
| V1.08 | Weldom | 275 | 1 |
|
||||
| V1.09 | Suunto | 0 | 1 |
|
||||
| V1.10 | Samsung | 9 | 1 |
|
||||
| V1.11 | Ollama | 0 | 1 |
|
||||
| V1.12 | RedHat | 0 | 1 |
|
||||
| V1.13 | eBay | 136 | 1 |
|
||||
| V1.14 | AliExpress | 384 | 2 |
|
||||
| V1.15 | Avis | 10 | 1 |
|
||||
| V1.16 | LinkedIn updates | 754 | 3 |
|
||||
| V1.17 | LinkedIn notifs | 983 | 4 |
|
||||
| V1.18 | LinkedIn messages | 1365 | 5 |
|
||||
| V1.19 | Facebook | 0 | 1 |
|
||||
|
||||
**Total Vague 1 trashed: 5335 messages**
|
||||
|
||||
## 2026-06-05 21:34:45 — Vague 1bis (tranche 6m→1y)
|
||||
|
||||
| Règle | Description | Total trashed | Batchs |
|
||||
|---|---|---:|---:|
|
||||
| V1.01 | Rustica | 82 | 1 |
|
||||
| V1.02 | TAAFT | 160 | 1 |
|
||||
| V1.03 | Quora | 631 | 3 |
|
||||
| V1.04 | Bricomarché | 55 | 1 |
|
||||
| V1.05 | Beehiiv | 0 | 1 |
|
||||
| V1.06 | Carrefour | 32 | 1 |
|
||||
| V1.07 | Cdiscount | 36 | 1 |
|
||||
| V1.08 | Weldom | 49 | 1 |
|
||||
| V1.09 | Suunto | 12 | 1 |
|
||||
| V1.10 | Samsung | 16 | 1 |
|
||||
| V1.11 | Ollama | 2 | 1 |
|
||||
| V1.12 | RedHat | 15 | 1 |
|
||||
| V1.13 | eBay | 64 | 1 |
|
||||
| V1.14 | AliExpress | 84 | 1 |
|
||||
| V1.15 | Avis | 6 | 1 |
|
||||
| V1.16 | LinkedIn updates | 77 | 1 |
|
||||
| V1.17 | LinkedIn notifs | 90 | 1 |
|
||||
| V1.18 | LinkedIn messages | 133 | 1 |
|
||||
| V1.19 | Facebook | 103 | 1 |
|
||||
|
||||
**Total Vague 1bis (6m→1y) trashed: 1647 messages**
|
||||
|
||||
## 2026-06-06 01:07:10 — Vague 1ter (tranche 30j→6m)
|
||||
|
||||
| Règle | Description | Total trashed | Batchs |
|
||||
|---|---|---:|---:|
|
||||
| V1.01 | Rustica | 232 | 1 |
|
||||
| V1.02 | TAAFT | 155 | 1 |
|
||||
| V1.03 | Quora | 551 | 2 |
|
||||
| V1.04 | Bricomarché | 49 | 1 |
|
||||
| V1.05 | Beehiiv | 64 | 1 |
|
||||
| V1.06 | Carrefour | 29 | 1 |
|
||||
| V1.07 | Cdiscount | 35 | 1 |
|
||||
| V1.08 | Weldom | 36 | 1 |
|
||||
| V1.09 | Suunto | 33 | 1 |
|
||||
| V1.10 | Samsung | 30 | 1 |
|
||||
| V1.11 | Ollama | 23 | 1 |
|
||||
| V1.12 | RedHat | 25 | 1 |
|
||||
| V1.13 | eBay | 16 | 1 |
|
||||
| V1.14 | AliExpress | 65 | 1 |
|
||||
| V1.15 | Avis | 21 | 1 |
|
||||
| V1.16 | LinkedIn updates | 66 | 1 |
|
||||
| V1.17 | LinkedIn notifs | 44 | 1 |
|
||||
| V1.18 | LinkedIn messages | 138 | 1 |
|
||||
| V1.19 | Facebook | 259 | 1 |
|
||||
|
||||
**Total Vague 1ter (30j→6m) trashed: 1871 messages**
|
||||
|
||||
## 2026-06-06 01:27:51 — Vague Synology (notifs www.airtria.net)
|
||||
Query: subject:"[www.airtria.net]" in:inbox
|
||||
|
||||
|
||||
**Total Synology trashed: 1160 messages**
|
||||
|
||||
## 2026-06-06 01:45:19 — Vague Synology ALL variants
|
||||
| SynPRO | 210 trashed |
|
||||
| SynNET | 0 trashed |
|
||||
| SynIP1 | 1889 trashed |
|
||||
|
||||
## 2026-06-06 02:09:21 — Vague 1quinquies (7j→30j) + 4 nouvelles règles
|
||||
|
||||
| Règle | Description | Total trashed | Batchs |
|
||||
|---|---|---:|---:|
|
||||
| V1.01 | Rustica | 37 | 1 |
|
||||
| V1.02 | TAAFT | 23 | 1 |
|
||||
| V1.03 | Quora | 85 | 1 |
|
||||
| V1.04 | Bricomarché | 9 | 1 |
|
||||
| V1.05 | Beehiiv | 11 | 1 |
|
||||
| V1.06 | Carrefour | 7 | 1 |
|
||||
| V1.07 | Cdiscount | 8 | 1 |
|
||||
| V1.08 | Weldom | 5 | 1 |
|
||||
| V1.09 | Suunto | 4 | 1 |
|
||||
| V1.10 | Samsung | 3 | 1 |
|
||||
| V1.11 | Ollama | 2 | 1 |
|
||||
| V1.12 | RedHat | 3 | 1 |
|
||||
| V1.13 | eBay | 5 | 1 |
|
||||
| V1.14 | AliExpress | 21 | 1 |
|
||||
| V1.15 | Avis | 3 | 1 |
|
||||
| V1.16 | LinkedIn updates | 10 | 1 |
|
||||
| V1.17 | LinkedIn notifs | 7 | 1 |
|
||||
| V1.18 | LinkedIn messages | 25 | 1 |
|
||||
| V1.19 | Facebook | 3 | 1 |
|
||||
| V1.20 | VPAuto | 6 | 1 |
|
||||
| V1.21 | Substack airepo | 4 | 1 |
|
||||
| V1.22 | Intermarché | 5 | 1 |
|
||||
| V1.23 | k8slens | 3 | 1 |
|
||||
|
||||
**Total Vague 1quinquies trashed: 289 messages**
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-25 — Phase E : filtres natifs Gmail + cleanup
|
||||
|
||||
### Labels créés
|
||||
- `Promos` (Label_11)
|
||||
- `Dev-Tools` (Label_12)
|
||||
- `Social` (Label_13)
|
||||
|
||||
### Filtres créés : 18
|
||||
|
||||
| ID | Query | Label |
|
||||
|---|---|---|
|
||||
| E01 | `from:linkedin.com OR from:e.linkedin.com` | Social |
|
||||
| E02 | `from:facebookmail.com` | Social |
|
||||
| E03 | `from:clients.ulys.com` | Receipts |
|
||||
| E04 | `from:les-patriotes.fr` | Newsletters |
|
||||
| E05 | `from:rustica-info.fr` | Newsletters |
|
||||
| E06 | `from:mail.theresanaiforthat.com` | Newsletters |
|
||||
| E07 | `from:quora.com` | Newsletters |
|
||||
| E08 | `from:airepo@substack.com` | Newsletters |
|
||||
| E09 | `from:vpauto.fr OR from:mail.vpauto.eu` | Promos |
|
||||
| E10 | `from:communication.andre.fr` | Promos |
|
||||
| E11 | `from:fr-news.adidas.com` | Promos |
|
||||
| E12 | `from:eu1.tocampaigns.com` | Promos |
|
||||
| E13 | `from:mkt.norauto.fr` | Promos |
|
||||
| E14 | `from:news.intermarche.com` | Promos |
|
||||
| E15 | `from:monmagasinvert.fr` | Promos |
|
||||
| E16 | `from:dlink.com` | Promos |
|
||||
| E17 | `from:messages.mongodb.com` | Dev-Tools |
|
||||
| E18 | `from:k8slens.dev` | Dev-Tools |
|
||||
|
||||
### Cleanup rétroactif Phase E (archivés hors inbox)
|
||||
|
||||
| Query | Archivés |
|
||||
|---|---:|
|
||||
| `from:linkedin.com OR from:e.linkedin.com in:inbox` | 200 |
|
||||
| `from:facebookmail.com in:inbox` | 43 |
|
||||
| `from:clients.ulys.com in:inbox` | 87 |
|
||||
| `from:les-patriotes.fr in:inbox` | 252 |
|
||||
| `from:rustica-info.fr in:inbox` | 42 |
|
||||
| `from:mail.theresanaiforthat.com in:inbox` | 26 |
|
||||
| `from:vpauto.fr OR from:mail.vpauto.eu in:inbox` | 50 |
|
||||
| `from:communication.andre.fr in:inbox` | 3 |
|
||||
| `from:fr-news.adidas.com in:inbox` | 50 |
|
||||
| `from:eu1.tocampaigns.com in:inbox` | 38 |
|
||||
| `from:news.intermarche.com in:inbox` | 48 |
|
||||
| `from:dlink.com in:inbox` | 50 |
|
||||
| **Total Phase E archivés** | **~889** |
|
||||
|
||||
### Phase F complément (2026-06-25)
|
||||
|
||||
- `from:clients.ulys.com in:inbox` : 0 restant ✅
|
||||
- `from:les-patriotes.fr in:inbox` : 0 restant ✅
|
||||
- Phase F terminée : Philippot + Ulys complètement sortis de l’inbox et filtrés à l’arrivée.
|
||||
|
||||
### Audit
|
||||
|
||||
- Rapport : `workspace/gmail-phase-e-audit-20260625.md`
|
||||
- Échantillon audité : 2000 threads
|
||||
|
||||
176
workspace/gmail-phase-e-audit-20260625.md
Normal file
176
workspace/gmail-phase-e-audit-20260625.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# Gmail Phase E — Audit expéditeurs résiduels
|
||||
|
||||
Date : 2026-06-25 17h40 UTC
|
||||
|
||||
Échantillon : 2000 threads (500 par catégorie)
|
||||
|
||||
| Catégorie | Threads analysés |
|
||||
|---|---:|
|
||||
| Promotions | 500 |
|
||||
| Social | 500 |
|
||||
| Updates | 500 |
|
||||
| Older than 30d | 500 |
|
||||
|
||||
## Top 25 expéditeurs non-whitelist
|
||||
|
||||
| Rang | Threads | Expéditeur |
|
||||
|---|---|---|
|
||||
| 1 | 109 | LinkedIn <linkedin@e.linkedin.com> |
|
||||
| 2 | 65 | LinkedIn <jobs-listings@linkedin.com> |
|
||||
| 3 | 56 | ULYS <info@clients.ulys.com> |
|
||||
| 4 | 53 | "André" <contact@communication.andre.fr> |
|
||||
| 5 | 45 | adidas <adidas@fr-news.adidas.com> |
|
||||
| 6 | 29 | LinkedIn <messages-noreply@linkedin.com> |
|
||||
| 7 | 29 | Florian Philippot <florian.philippot@les-patriotes.fr> |
|
||||
| 8 | 28 | D-Link <uki-marketing@dlink.com> |
|
||||
| 9 | 28 | VPauto <actu@vpauto.fr> |
|
||||
| 10 | 27 | Rustica - La news du Jour <nepasrepondre@rustica-info.fr> |
|
||||
| 11 | 26 | "TAAFT - There's An AI For That" <hi@mail.theresanaiforthat.com> |
|
||||
| 12 | 25 | Cabesto <cabesto@eu1.tocampaigns.com> |
|
||||
| 13 | 24 | Norauto <norauto.france@mkt.norauto.fr> |
|
||||
| 14 | 22 | "Sélection Quora" <french-quora-digest@quora.com> |
|
||||
| 15 | 22 | Chargemap <hello@chargemap.com> |
|
||||
| 16 | 21 | Google <no-reply@accounts.google.com> |
|
||||
| 17 | 20 | MongoDB <mongodbteam@messages.mongodb.com> |
|
||||
| 18 | 20 | LinkedIn <news-noreply@linkedin.com> |
|
||||
| 19 | 20 | AI Blueprint <airepo@substack.com> |
|
||||
| 20 | 19 | Point Vert - Magasin Vert <noreply.marketing@monmagasinvert.fr> |
|
||||
| 21 | 17 | "Intermarché" <intermarche@news.intermarche.com> |
|
||||
| 22 | 17 | VPauto <vpauto@mail.vpauto.eu> |
|
||||
| 23 | 16 | "Booking.com" <email.campaign@sg.booking.com> |
|
||||
| 24 | 16 | Team Lens <no-reply@k8slens.dev> |
|
||||
| 25 | 16 | LinkedIn <news@linkedin.com> |
|
||||
|
||||
## Top 20 domaines non-whitelist
|
||||
|
||||
| Rang | Threads | Domaine |
|
||||
|---|---|---|
|
||||
| 1 | 348 | linkedin.com |
|
||||
| 2 | 133 | e.linkedin.com |
|
||||
| 3 | 69 | quora.com |
|
||||
| 4 | 67 | clients.ulys.com |
|
||||
| 5 | 53 | communication.andre.fr |
|
||||
| 6 | 45 | fr-news.adidas.com |
|
||||
| 7 | 45 | google.com |
|
||||
| 8 | 42 | rustica-info.fr |
|
||||
| 9 | 39 | facebookmail.com |
|
||||
| 10 | 31 | vpauto.fr |
|
||||
| 11 | 30 | dlink.com |
|
||||
| 12 | 29 | les-patriotes.fr |
|
||||
| 13 | 26 | mail.theresanaiforthat.com |
|
||||
| 14 | 25 | eu1.tocampaigns.com |
|
||||
| 15 | 24 | mkt.norauto.fr |
|
||||
| 16 | 22 | chargemap.com |
|
||||
| 17 | 21 | accounts.google.com |
|
||||
| 18 | 20 | messages.mongodb.com |
|
||||
| 19 | 20 | substack.com |
|
||||
| 20 | 19 | monmagasinvert.fr |
|
||||
|
||||
## Détail top 15 expéditeurs
|
||||
|
||||
### LinkedIn <linkedin@e.linkedin.com> — 109 threads (Social:109)
|
||||
Sujets d'exemple :
|
||||
- `2025-10-09 10:17` Demande d'expertise de LinkedIn
|
||||
- `2025-08-13 22:28` thierry, merci de compter parmi nos membres
|
||||
- `2025-03-12 17:23` thierry, merci de compter parmi nos membres
|
||||
|
||||
### LinkedIn <jobs-listings@linkedin.com> — 65 threads (Social:65)
|
||||
Sujets d'exemple :
|
||||
- `2024-06-20 14:10` Poste de French Freelance Translator Remote chez Top Language Jobsdisponible
|
||||
- `2024-02-15 13:14` Centific recrute : Part-Time Work From Home as Internet Evaluator Anywhere in France: Project Milkyw
|
||||
- `2023-08-31 14:05` Poste de RESPONSABLE R&D IT (F/H) chez Randstad Search : recrute activement
|
||||
|
||||
### ULYS <info@clients.ulys.com> — 56 threads (Promotions:33, Older than 30d:19, Updates:4)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 16:59` Coup de chaud sur les prix ⚡
|
||||
- `2026-06-16 18:01` 📩 La Pause Ulys #6 | Nos conseils pour réussir votre été 👀🌞
|
||||
- `2026-05-17 18:02` Faites le plein de RÉCOMPENSES à partager 📢♥️
|
||||
|
||||
### "André" <contact@communication.andre.fr> — 53 threads (Promotions:39, Older than 30d:14)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 16:30` Soldes : le savoir-faire italien à −70 %
|
||||
- `2026-06-24 16:31` Top départ pour les Soldes André 🚀
|
||||
- `2026-06-21 08:34` Bonne fête à tous les papas (et -50% pour lui)
|
||||
|
||||
### adidas <adidas@fr-news.adidas.com> — 45 threads (Promotions:28, Older than 30d:17)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 09:16` Jusqu'à -30 %, en ligne et en magasin
|
||||
- `2026-06-15 14:12` L'été commence ici
|
||||
- `2026-05-01 12:09` Prêt(e) pour les festivals ?
|
||||
|
||||
### LinkedIn <messages-noreply@linkedin.com> — 29 threads (Social:29)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 20:09` thierry, ajoutez Stanislas Zimmermann - Learning & Development Manager
|
||||
- `2026-06-25 16:24` Nouvelle compétence disponible : Résolution de casse-têtes 🧩
|
||||
- `2026-06-25 00:08` 7 personnes ont consulté votre profil
|
||||
|
||||
### Florian Philippot <florian.philippot@les-patriotes.fr> — 29 threads (Updates:17, Older than 30d:12)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 11:01` La vérité triomphe !
|
||||
- `2026-06-18 11:00` Une bascule historique !
|
||||
- `2026-06-11 11:00` La révolte populaire !
|
||||
|
||||
### D-Link <uki-marketing@dlink.com> — 28 threads (Promotions:21, Older than 30d:7)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-23 15:44` THIERRY Check out our Prime Day Deals
|
||||
- `2026-06-16 10:46` THIERRY Experience Next-Generation 5G Connectivity with the F530
|
||||
- `2026-06-09 11:38` Webinar - Bring Surveillance Back Into Focus
|
||||
|
||||
### VPauto <actu@vpauto.fr> — 28 threads (Promotions:23, Older than 30d:5)
|
||||
Sujets d'exemple :
|
||||
- `2026-05-09 09:01` +240 véhicules à vendre ce lundi à Lorient ! 📅
|
||||
- `2026-05-05 18:08` 💫 Jeudi : +160 véhicules en vente multi-sites
|
||||
- `2026-05-04 18:31` +800 véhicules à vendre cette semaine chez VPauto 🤯
|
||||
|
||||
### Rustica - La news du Jour <nepasrepondre@rustica-info.fr> — 27 threads (Promotions:19, Updates:8)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-25 11:40` Arrosage tomates : les meilleures techniques pour des fruits juteux
|
||||
- `2026-06-24 13:37` Récolte du potager : faut‑il cueillir le matin ou le soir pour un meilleur goût ?
|
||||
- `2026-06-23 11:41` Taille courge : maîtrisez la croissance pour de beaux légumes !
|
||||
|
||||
### "TAAFT - There's An AI For That" <hi@mail.theresanaiforthat.com> — 26 threads (Updates:25, Promotions:1)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-03 23:55` 🦾 May's Hottest AI Tools
|
||||
- `2026-06-25 00:55` 🦾 OpenAI Cooks Up Jalapeño
|
||||
- `2026-06-24 00:39` 🦾 GPT-5 Cracked a 3-Year Mystery
|
||||
|
||||
### Cabesto <cabesto@eu1.tocampaigns.com> — 25 threads (Promotions:22, Older than 30d:3)
|
||||
Sujets d'exemple :
|
||||
- `2026-03-19 08:50` Thierry, on a sélectionné des promos rien que pour toi !
|
||||
- `2026-03-11 06:48` Découvre nos nouveautés pour toi Thierry 😉
|
||||
- `2026-03-05 11:30` Thierry, on a sélectionné des promos rien que pour toi !
|
||||
|
||||
### Norauto <norauto.france@mkt.norauto.fr> — 24 threads (Promotions:18, Older than 30d:6)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-08 08:13` Reprenez la route au meilleur prix
|
||||
- `2026-04-07 08:27` Facilité, prix et services : plus de raison d’attendre
|
||||
- `2026-04-01 07:00` 10€ de remise sur votre vidange
|
||||
|
||||
### "Sélection Quora" <french-quora-digest@quora.com> — 22 threads (Updates:21, Promotions:1)
|
||||
Sujets d'exemple :
|
||||
- `2026-06-12 20:06` La France blanche et chrétienne n’a jamais existé » : L’extrême droite fantasme une F...
|
||||
- `2026-06-24 22:07` Le Français parle toujours de s'expatrier en Espagne ou au Portugal, pourquoi pas en ...?
|
||||
- `2026-06-23 21:07` Combien de musulmans y a-t-il en France ?
|
||||
|
||||
### Chargemap <hello@chargemap.com> — 22 threads (Promotions:16, Older than 30d:5, Updates:1)
|
||||
Sujets d'exemple :
|
||||
- `2026-05-22 17:02` Long trajet : les 5 réflexes indispensables
|
||||
- `2026-05-17 14:00` -10% chez Atlante ⚡️
|
||||
- `2026-04-27 14:00` -10% chez Plug Inn fast charge ⚡️
|
||||
|
||||
## Recommandations filtres Phase E
|
||||
|
||||
### Filtres à créer (Archive + Label)
|
||||
|
||||
| Expéditeur / Domaine | Action proposée | Note |
|
||||
|---|---|---|
|
||||
| @linkedin.com / @e.linkedin.com | Archive + Label `Social` | Encore très présent malgré Phase D |
|
||||
| @clients.ulys.com | Archive + Label `Receipts` | Prévu Phase F, peut être anticipé |
|
||||
| @les-patriotes.fr | Archive + Label `Newsletters` | V2.01 existante |
|
||||
| @rustica-info.fr, @mail.theresanaiforthat.com, @quora.com, @substack.com | Archive + Label `Newsletters` | Newsletters récurrentes |
|
||||
| @vpauto.fr, @mail.vpauto.eu | Archive + Label `Promos` | Enchères/promos auto |
|
||||
| @communication.andre.fr, @fr-news.adidas.com, @eu1.tocampaigns.com, @mkt.norauto.fr, @monmagasinvert.fr | Archive + Label `Promos` | E-com / promo |
|
||||
| @dlink.com | Archive + Label `Promos` | Marketing D-Link |
|
||||
| @messages.mongodb.com, @k8slens.dev | Archive + Label `Dev-Tools` | Tech tools updates |
|
||||
| @chargemap.com | à vérifier | Lié VE / recharge — peut mériter label `Charge-VE` |
|
||||
| @accounts.google.com | NE PAS FILTRER | Sécurité / alertes Google |
|
||||
199
workspace/gmail-rules.md
Normal file
199
workspace/gmail-rules.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Gmail Rules — Plan de ménage
|
||||
|
||||
_Généré le 2026-06-05 par Phase C (validation humaine)._
|
||||
_Source : `gmail-audit.md` (sample 3000 threads), validations Thierry._
|
||||
|
||||
## Légende
|
||||
|
||||
- 🟢 **Vague 1 — Trash** : aucune valeur, jamais lu, désabo Gmail natif ensuite
|
||||
- 🟡 **Vague 2 — Archive** : pas de valeur active mais on garde (taggé)
|
||||
- 🔴 **Whitelist absolue** : ne JAMAIS toucher
|
||||
- 🟣 **Spécial** : traitement dédié (digest VE, etc.)
|
||||
|
||||
## 🔴 Whitelist absolue (NE JAMAIS TOUCHER)
|
||||
|
||||
Toute action Gmail (trash, archive, label) est INTERDITE sur ces sources.
|
||||
|
||||
### Banques
|
||||
- `@cic.fr`, `@e-cic.fr`
|
||||
- `@bpgo.fr` (Banque Pop Grand Ouest)
|
||||
- `@cmb.fr`
|
||||
|
||||
### Admin / légal
|
||||
- `@impots.gouv.fr`, `@dgfip.finances.gouv.fr`
|
||||
- `@digiposte.fr`
|
||||
- `@ameli.fr`
|
||||
|
||||
### Telco perso
|
||||
- `@orange.com`, `@orange.fr`
|
||||
- `@neuf.fr`
|
||||
|
||||
### Véhicules whitelist
|
||||
- `@vwfs.com`, `@volkswagen.fr`
|
||||
- `@jeep.com` (cf. règle 🟣 V01 ci-dessous)
|
||||
- `@ze-watt.fr`, `@ze-watt.com`
|
||||
- `@zeromotorcycles.com`
|
||||
|
||||
### Club plongée
|
||||
- `@gissacg.fr`, `@lists.gissacg.fr`
|
||||
- `president@gissacg.fr`
|
||||
|
||||
### Sociétés AIRTRIA
|
||||
- `@airtria.net`, `@airtria.fr`
|
||||
|
||||
### Solaire pro
|
||||
- `@laboutique-solaire-pro.com`
|
||||
|
||||
### Identités personnelles
|
||||
- `tallagrand.thierry@gmail.com` (mes propres SENT)
|
||||
- `thierry.tallagrand@me.com` (mon adresse iCloud)
|
||||
|
||||
### Labels système protégés
|
||||
- `IMPORTANT`, `STARRED`, `SENT`, `DRAFT`
|
||||
- `Personal`, `Travail`, `Achats`, `Receipts`, `Notes`
|
||||
|
||||
---
|
||||
|
||||
## 🟢 Vague 1 — Trash en masse
|
||||
|
||||
**Stratégie** : `gog gmail trash` par batch de 200, pause 5s entre batchs.
|
||||
**Critère commun** : `older_than:90d` pour ne pas trasher les arrivées récentes au cas où.
|
||||
**Réversibilité** : Trash Gmail garde 30 jours.
|
||||
|
||||
### Règles V1
|
||||
|
||||
| ID | Query Gmail | Sample | Estimation totale |
|
||||
|---|---|---:|---:|
|
||||
| **V1.01** | `from:nepasrepondre@rustica-info.fr in:inbox older_than:90d` | 196 | ~400 |
|
||||
| **V1.02** | `from:hi@mail.theresanaiforthat.com in:inbox older_than:90d` | 123 | ~200 |
|
||||
| **V1.03** | `from:quora.com in:inbox older_than:90d` | 240 | ~600 |
|
||||
| **V1.04** | `from:no-reply@info.bricomarche.com in:inbox older_than:90d` | 44 | ~100 |
|
||||
| **V1.05** | `from:beehiiv.com in:inbox older_than:90d` (FutureBlueprint+ai-signal) | 56 | ~150 |
|
||||
| **V1.06** | `from:carrefour@email.carrefour.fr in:inbox older_than:90d` | 37 | ~100 |
|
||||
| **V1.07** | `from:cds.newsletter-cdiscount.com in:inbox older_than:90d` | 32 | ~80 |
|
||||
| **V1.08** | `from:n.weldom.fr in:inbox older_than:90d` | 30 | ~80 |
|
||||
| **V1.09** | `from:news.suunto.com in:inbox older_than:90d` | 26 | ~60 |
|
||||
| **V1.10** | `from:crm.samsung.fr in:inbox older_than:90d` | 26 | ~60 |
|
||||
| **V1.11** | `from:ollama.com in:inbox older_than:90d` | 25 | ~60 |
|
||||
| **V1.12** | `from:go.explore.redhat.com in:inbox older_than:90d` | 24 | ~60 |
|
||||
| **V1.13** | `from:reply.ebay.fr in:inbox older_than:90d` | 23 | ~60 |
|
||||
| **V1.14** | `from:aliexpress.com in:inbox older_than:90d` (selections+deals) | 53 | ~150 |
|
||||
| **V1.15** | `from:news_frfr@avis-comms.international in:inbox older_than:90d` | 21 | ~50 |
|
||||
| **V1.16** | `from:updates-noreply@linkedin.com in:inbox older_than:90d` | 53 | ~120 |
|
||||
| **V1.17** | `from:notifications-noreply@linkedin.com in:inbox older_than:90d` | 25 | ~60 |
|
||||
| **V1.18** | `from:messages-noreply@linkedin.com in:inbox older_than:90d` | 117 | ~250 |
|
||||
| **V1.19** | `from:facebookmail.com in:inbox older_than:90d` | 145 | ~350 |
|
||||
|
||||
**Estimation totale Vague 1 : ~3000 threads à trasher** (sur ta boîte de 12 703).
|
||||
|
||||
---
|
||||
|
||||
## 🟡 Vague 2 — Archive avec label
|
||||
|
||||
**Stratégie** : `gog gmail archive` (retire INBOX) + apply label.
|
||||
**Réversibilité** : zéro destruction, juste sortie de l'inbox.
|
||||
|
||||
### Règles V2
|
||||
|
||||
| ID | Query Gmail | Action | Sample | Note |
|
||||
|---|---|---|---:|---|
|
||||
| **V2.01** | `from:florian.philippot@les-patriotes.fr in:inbox` | Archive + label `Newsletters` | 18 | Politique perso |
|
||||
| **V2.02** | `from:info@clients.ulys.com in:inbox older_than:30d` | Archive + label `Receipts` | 23 | Télépéage VINCI |
|
||||
|
||||
**Estimation totale Vague 2 : ~50 threads à archiver.**
|
||||
|
||||
Note : la 2ème passe Q8 enrichira cette liste avec la longue traîne newsletters tech.
|
||||
|
||||
---
|
||||
|
||||
## 🟣 Spécial — Catégorie 2 (digest VE)
|
||||
|
||||
### Règle V01
|
||||
|
||||
`from:uconnectservices@jeep.com` (172 sample / ~400 boîte totale) :
|
||||
- **Phase D (immédiat)** : aucune action, on les laisse dans inbox.
|
||||
- **Phase F+ (digest VE)** : agent quotidien parse les mails Jeep, génère
|
||||
`charge-vehicule.md` + notif WhatsApp synthèse, puis archive automatiquement
|
||||
les mails parsés avec label `Charge-VE`.
|
||||
|
||||
**Pas d'action Phase D**.
|
||||
|
||||
---
|
||||
|
||||
## Phase E — Filtres natifs Gmail (2026-06-25)
|
||||
|
||||
Objectif : empêcher les newsletters / promos récurrentes d’atterrir dans l’inbox.
|
||||
Méthode : filtres natifs Gmail (`Settings > Filters and Blocked Addresses`) créés via `gog gmail filters create`.
|
||||
Action par défaut : **archiver** (`removeLabelIds: [INBOX, UNREAD]`) + **appliquer un label**.
|
||||
|
||||
### Labels créés
|
||||
- `Promos` (id Label_11)
|
||||
- `Dev-Tools` (id Label_12)
|
||||
- `Social` (id Label_13)
|
||||
|
||||
### Filtres actifs
|
||||
|
||||
| # | Query | Label | Type |
|
||||
|---|---|---|---|
|
||||
| E01 | `from:linkedin.com OR from:e.linkedin.com` | `Social` | Social |
|
||||
| E02 | `from:facebookmail.com` | `Social` | Social |
|
||||
| E03 | `from:clients.ulys.com` | `Receipts` | Télépéage |
|
||||
| E04 | `from:les-patriotes.fr` | `Newsletters` | Politique |
|
||||
| E05 | `from:rustica-info.fr` | `Newsletters` | Jardinage |
|
||||
| E06 | `from:mail.theresanaiforthat.com` | `Newsletters` | Tech/IA |
|
||||
| E07 | `from:quora.com` | `Newsletters` | Tech/QA |
|
||||
| E08 | `from:airepo@substack.com` | `Newsletters` | Tech/IA |
|
||||
| E09 | `from:vpauto.fr OR from:mail.vpauto.eu` | `Promos` | Auto |
|
||||
| E10 | `from:communication.andre.fr` | `Promos` | E-com |
|
||||
| E11 | `from:fr-news.adidas.com` | `Promos` | E-com |
|
||||
| E12 | `from:eu1.tocampaigns.com` | `Promos` | E-com (Cabesto) |
|
||||
| E13 | `from:mkt.norauto.fr` | `Promos` | Auto |
|
||||
| E14 | `from:news.intermarche.com` | `Promos` | E-com |
|
||||
| E15 | `from:monmagasinvert.fr` | `Promos` | E-com |
|
||||
| E16 | `from:dlink.com` | `Promos` | Tech |
|
||||
| E17 | `from:messages.mongodb.com` | `Dev-Tools` | Dev |
|
||||
| E18 | `from:k8slens.dev` | `Dev-Tools` | Dev |
|
||||
|
||||
### Cleanup rétroactif (2026-06-25)
|
||||
- ~687 messages archivés manuellement depuis l’inbox (batchs limités à 200 max, pause 6 s).
|
||||
- Voir `gmail-housekeeping.md` pour le détail.
|
||||
|
||||
---
|
||||
|
||||
## 📋 2ème passe (Q8) — Longue traîne
|
||||
|
||||
À lancer après Vague 1 + Vague 2 stabilisées.
|
||||
|
||||
```bash
|
||||
# Script proposé : gmail_audit.py --query "category:promotions OR category:updates older_than:6m" --sample 5000
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Mises à jour 6 juin 2026 (Phase D execution)
|
||||
|
||||
### Whitelist enrichie (à ajouter à la whitelist principale)
|
||||
|
||||
#### Synology infrastructure
|
||||
- `from:sns@synologynotification.com` (Active Insight - alertes critiques disque/storage)
|
||||
- `from:noreply@c2.synology.com` (C2 backup subscription)
|
||||
|
||||
#### Finance
|
||||
- `from:noreply@amundi-esr.com` (épargne salariale PEE/PERCO - transactionnel)
|
||||
- `from:r.clientele@vwfs.com` (VW Financial Services)
|
||||
|
||||
#### Famille & cercle proche
|
||||
- `frederic.tallagrand@*` (famille)
|
||||
- `@arimair.fr` (plongée copain)
|
||||
|
||||
### 4 nouvelles règles Vague 1 (ajoutées en cours d'exécution)
|
||||
- V1.20 : `from:vpauto@mail.vpauto.eu` (enchères auto)
|
||||
- V1.21 : `from:airepo@substack.com` (newsletter IA Substack)
|
||||
- V1.22 : `from:intermarche@news.intermarche.com` (promo)
|
||||
- V1.23 : `from:no-reply@k8slens.dev` (newsletter Lens K8s)
|
||||
|
||||
### Synology trash variants (3 patterns)
|
||||
- `subject:"[www.airtria.net]"` (ARCHIVE2 → 1 160 mails)
|
||||
- `subject:"[www.airtria.pro]"` (ARCHIVE3 → 210 mails)
|
||||
- `subject:"[10.10.10.50]"` (ARCHIVE originel → 1 889 mails)
|
||||
|
||||
Reference in New Issue
Block a user