Files
OPENCLAW_ARCHIVE3_17/handoffs/HANDOFF-2026-06-09.md
Tallagrand Thierry 5363f99b76 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
2026-06-26 00:28:07 +02:00

26 KiB
Raw Permalink Blame History

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... $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 : € (%)' 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.