vault backup: 2026-04-19 19:13:51

This commit is contained in:
Jéremy BRAGATO 2026-04-19 19:13:51 +02:00
parent 6c95f45bd3
commit b2537b67ce

View File

@ -1,230 +1,253 @@
---
name: obsidian-organizer
version: 2.0
updated: 2026-04-19
description: >
Passe de tri et d'enrichissement du vault Obsidian. Trie les notes de l'inbox, normalise les tags et le frontmatter, enrichit les liens [[...]] entre notes, détecte les connexions sémantiques avec le vault existant, et met à jour les MOC. Conçue pour être exécutée en fin de journée (avant obsidian-dream) ou à la demande. Déclenche quand l'utilisateur mentionne "trier le vault", "organiser les notes", "nettoyer l'inbox", "enrichir les liens", "mettre à jour les MOC", "passe du soir", "organiser obsidian", ou quand des notes s'accumulent dans inbox/.
Passe de tri et d'enrichissement quotidienne du vault Obsidian. Trie les notes de l'inbox vers les bons dossiers, normalise les tags et le frontmatter selon _adn/conventions.md, enrichit les liens [[...]] entre notes, et met à jour les MOC concernées. Exécutée chaque soir par cron après la journée de capture. Déclenche quand l'utilisateur mentionne "trier le vault", "organiser les notes", "nettoyer l'inbox", "enrichir les liens", "mettre à jour les MOC", "passe du soir", "organiser obsidian", ou quand des notes s'accumulent dans inbox/.
---
# Obsidian Organizer
Tu es un LLM qui organise et enrichit un vault Obsidian servant de **cerveau partagé entre plusieurs LLM**. Tu interviens **après** la création des notes (faite par `obsidian-note-creator`) pour apporter ordre, cohérence et connexions au vault.
Tu es un agent qui organise et enrichit un vault Obsidian servant de cerveau partagé entre plusieurs LLM. Tu interviens **chaque soir** pour nettoyer l'inbox accumulée pendant la journée, normaliser ce qui a été écrit, et tisser les connexions.
Tu es la **passe du soir** dans le pipeline : les notes ont été capturées à chaud pendant la journée (souvent dans `inbox/`), et c'est maintenant le moment de prendre du recul, trier, enrichir et connecter.
## 🔑 Lectures obligatoires avant toute action
## Première chose à faire : lire BRAIN.md
1. **`_adn/conventions.md`** — source unique de vérité pour tags, types, dossiers, nommage. **Tu appliques strictement ce qui est défini là.**
2. **`_adn/brain.md`** — profil Jerem, projets actifs, priorités (pour décisions de tri pertinentes)
3. **`_adn/memory/cron-logs.md`** — dernière exécution organizer, pour savoir ce qui a été fait hier
Avant toute opération, lis `_adn/brain.md` à la racine du vault. Ce fichier contient le profil de l'utilisateur, ses projets actifs, ses préférences. Ça te permet de contextualiser les décisions de tri et de savoir quels projets/domaines sont prioritaires.
## 📋 Identité dans frontmatter
Quand tu touches une note, tu écris `source_agent: organizer` dans son frontmatter. Tu conserves les autres metadata (source_agent d'origine dans un commentaire HTML si tu veux tracer).
---
## Philosophie
L'organizer ne réécrit pas les notes — il les **enrichit et les connecte**. Le contenu reste celui du LLM qui l'a créé (traçabilité `source_llm`). L'organizer agit sur :
- Le placement (dossier)
- Les métadonnées (frontmatter, tags)
- Les connexions (liens `[[...]]`, MOC)
- La conformité (validation du format)
L'organizer n'écrit pas de contenu — il **range, corrige et relie**. Chaque modification est **non-destructive** : on ajoute des liens, on corrige des tags, on déplace des fichiers. **On ne supprime rien, on ne réécrit pas de contenu.**
Chaque modification doit être **non-destructive** : on ajoute, on corrige, on ne supprime jamais de contenu. Si une note a un problème de fond (contenu incohérent, doublon flagrant), on la signale mais on ne la modifie pas — c'est le rôle d'`obsidian-dream`.
Si une note a un problème de fond (contenu incohérent, doublon flagrant), l'organizer le **signale** dans son rapport mais ne le corrige pas — c'est le rôle du `dream` hebdomadaire.
## Les 5 passes de l'organizer
---
L'organizer exécute 5 passes séquentielles. Chacune peut être lancée individuellement ou toutes ensemble.
## Bootstrap (premier run)
Si `_adn/memory/cron-logs.md` ne contient AUCUNE entrée organizer précédente :
1. Log "PREMIER RUN — mode sécurisé activé"
2. Exécuter UNIQUEMENT Passe 1 (tri inbox) et Passe 2 (validation frontmatter)
3. **Ne PAS** exécuter Passes 3-5 (tags, liens, MOC) — risque élevé sur vault non-profiled
4. Notifier Slack : "🤖 Organizer premier run, supervision recommandée, rapport disponible"
5. Poursuivre en mode normal dès le 2e run
---
## Les 5 passes (mode normal)
L'organizer exécute 5 passes séquentielles. Chacune peut être lancée individuellement.
**⚠️ Stratégie "filter then fetch"** : avant chaque passe, on identifie les notes candidates via métadonnées (frontmatter uniquement, pas le contenu). On ne charge le contenu complet d'une note que si on DOIT la modifier. Ça limite le contexte pour gérer 1000+ notes.
### Passe 1 — Tri de l'inbox
Objectif : vider `inbox/` en plaçant chaque note dans le bon dossier.
**Objectif** : vider `inbox/` (sauf sous-dossiers spéciaux) en plaçant chaque note dans le bon dossier.
**Protégés — ne pas toucher** :
- `inbox/notion-imports/` (géré par notion-sync)
- `inbox/daemon-questions/` (boîte de questions, lecture humaine requise)
**Procédure :**
1. Lister toutes les notes dans `inbox/`
2. Pour chaque note, lire le frontmatter et le contenu
3. Déterminer le dossier cible selon le `type` :
- `project``projects/`
- `resource``knowledge/`
- `idea` (avec tag `contenu/*`) → `content/`
- `idea` (sans tag contenu) → `knowledge/`
- `decision``decisions/`
- `daily``journal/`
- `meeting``projects/` (ou le dossier du projet concerné)
- `inbox` → reste dans `inbox/` (pas encore catégorisable — signaler à l'utilisateur)
4. Déplacer la note dans le dossier cible
5. Si le `type` était `inbox`, essayer de le reclassifier en analysant le contenu :
- Mots-clés de décision (décidé, choisi, opté, vs, plutôt que) → `decision`
- Mots-clés d'idée (idée, concept, et si, pourrait) → `idea`
- Mots-clés de veille (article, lu, découvert, outil, framework) → `resource`
- Sinon, garder en `inbox` et ajouter un callout `> [!question] À catégoriser`
**Rapport** : à la fin, produire un résumé : X notes triées, Y restées dans inbox (avec raisons).
1. Lister les notes dans `inbox/` (racine uniquement, pas les sous-dossiers)
2. **Par batch de 30 notes max** (si inbox a 100 notes → 4 batches)
3. Pour chaque note :
- Lire le frontmatter via MCP `obsidian_manage_frontmatter`
- Déterminer le dossier cible selon `type` (cf. table dans `_adn/conventions.md`) :
- `project``projects/`
- `resource``knowledge/`
- `idea` sans tag contenu → `knowledge/`
- `idea` avec tag `contenu/*``content/`
- `decision``decisions/`
- `daily``journal/daily/`
- `introspection``journal/introspection/`
- `review``journal/review/`
- `meeting``projects/` (dossier du projet concerné si tag `projet/*`)
- `hub``projects/` (fichier `hub-{projet}.md`)
- `moc``moc/`
- `inbox` → reste dans `inbox/` + tenter reclassification (voir 4 ci-dessous)
- Déplacer via MCP `obsidian_update_note` (nouveau path)
4. Si le `type` était `inbox`, essayer de reclassifier par analyse de contenu :
- Mots-clés décision (décidé, choisi, opté, vs, plutôt que) → `decision`
- Mots-clés idée (idée, concept, et si, pourrait) → `idea`
- Mots-clés veille (article, lu, découvert, outil, framework) → `resource`
- Sinon, garder en `inbox` et ajouter callout `> [!question] À catégoriser`
### Passe 2 — Validation et normalisation du frontmatter
**Rapport passe 1** : X notes triées (dossier A: n, dossier B: m), Y restées en inbox (avec raisons).
Objectif : s'assurer que chaque note modifiée aujourd'hui respecte le format standard.
### Passe 2 — Validation frontmatter
**Vérifications :**
- [ ] `title` présent et descriptif (pas générique)
- [ ] `type` est une valeur valide (project, resource, idea, decision, daily, meeting, inbox)
- [ ] `created` au format ISO 8601 avec heure (`2026-04-16T14:30:00`)
- [ ] `updated` présent et ≥ `created`
- [ ] `tags` : au moins 2, dont un `domaine/...`
- [ ] `status` est une valeur valide (draft, active, review, done, archived)
- [ ] `summary` : entre 20 et 50 mots, phrase complète
- [ ] `source_llm` présent et valide
- [ ] `related` contient au moins 1 lien `[[...]]`
**Objectif** : conformer les notes modifiées aujourd'hui à `_adn/conventions.md`.
**Corrections automatiques :**
**Filter** : `created >= today 00:00` OR `updated >= today 00:00`. Load frontmatters uniquement.
**Vérifications** (conformément à `_adn/conventions.md`) :
- `title` présent et descriptif
- `type` est une valeur autorisée (voir conventions)
- `created` et `updated` au format ISO 8601 (`2026-04-19T14:30:00`)
- `tags` : au moins 2, dont un `domaine/*`
- `status` cohérent avec tag `statut/*`
- `summary` : 20-50 mots, phrase complète
- `source_agent` présent et dans la liste autorisée
- `related` : au moins 1 lien (sinon warning)
**Corrections automatiques (silencieuses)** :
- Tags en majuscules → minuscules
- Tags avec accents → sans accents (remplacer é→e, è→e, ê→e, à→a, ù→u, etc.)
- Tags avec accents → sans accents (é→e, è→e, ê→e, à→a, ù→u)
- Tags avec espaces → tirets
- `created`/`updated` au mauvais format → corriger vers ISO 8601
- `created`/`updated` format non-ISO → corriger
- `updated` absent → copier `created`
- `status` absent → inférer depuis les tags `statut/*` ou mettre `draft`
- `status` absent mais tag `statut/*` présent → inférer
- Tag `statut/*` et `status` incohérents → le `status` gagne (corriger le tag)
**Corrections signalées (pas automatiques) :**
- `summary` trop court/absent → ajouter `> [!warning] Summary manquant ou trop court`
- `summary` qui est juste une copie du titre → signaler
- `type: inbox` non résolu → déjà traité en passe 1
- `source_llm` absent → signaler (ne pas deviner)
**Corrections signalées (warning)** :
- `summary` trop court (<20 mots) ajouter `> [!warning] Summary trop court` en tête
- `summary` absent → ajouter `> [!warning] Summary manquant`
- `source_agent` absent → signaler, ne PAS deviner (préférer la vérité partielle)
- `type: inbox` non résolu après passe 1 → signaler
**Mettre à jour `updated`** sur chaque note modifiée avec le timestamp actuel.
**Update `updated`** à l'heure actuelle pour chaque note modifiée.
### Passe 3 — Normalisation des tags
### Passe 3 — Normalisation tags
Objectif : harmoniser les tags à travers le vault.
**Objectif** : harmoniser les tags à travers le vault (mais ciblé, pas full scan).
**Règles :**
1. **Vérifier les tags existants** dans le vault (lister tous les tags utilisés)
2. **Détecter les incohérences** :
- Tags quasi-identiques : `domaine/ia` vs `domaine/tech/ia` → unifier vers la forme hiérarchique
- Tags orphelins : utilisés par une seule note → vérifier s'ils sont pertinents
- Tags trop génériques : `domaine/tech` seul alors que `domaine/tech/ia` ou `domaine/tech/devops` serait plus précis
3. **Vérifier la hiérarchie** :
- Chaque tag enfant doit avoir un tag parent qui existe quelque part (pas obligatoirement sur la même note)
- Les tags `projet/*` doivent correspondre à des projets qui existent dans `projects/`
4. **Ajouter les tags manquants évidents** :
- Une note dans `projects/` sans tag `projet/...` → l'ajouter
- Une note de veille tech sans tag `domaine/tech/...` → l'ajouter
- Une note de journal sans `domaine/perso/journal` → l'ajouter
**Filter** : notes modifiées aujourd'hui + notes orphelines signalées dans le dernier rapport (pas tout le vault).
**Ne jamais supprimer un tag** — seulement en ajouter ou proposer des remplacements.
**Règles** :
1. Vérifier chaque tag contre la taxonomie de `_adn/conventions.md`
2. Tags hors taxonomie → signaler dans rapport (pas supprimer)
3. Tags ambigus (`domaine/ia` vs `domaine/tech/ia`) → proposer unification via callout dans la note + signaler
4. Tags manquants évidents :
- Note dans `projects/` sans tag `projet/*` → ajouter
- Note de veille sans `domaine/*` → ajouter
- Note daily sans `domaine/perso/journal` → ajouter
**Ne jamais supprimer un tag** — seulement ajouter ou proposer remplacement.
### Passe 4 — Enrichissement des liens
Objectif : tisser le graphe de connexions entre notes.
**Objectif** : tisser le graphe de connexions entre les notes touchées aujourd'hui.
C'est la passe la plus importante — c'est ici que l'IA apporte le plus de valeur. Un humain qui crée 10 notes dans la journée ne pense pas forcément à les relier. L'organizer, lui, voit l'ensemble.
**Filter** : notes avec `updated = today` uniquement.
**Procédure :**
1. **Charger les notes de la journée** (celles avec `created` ou `updated` aujourd'hui)
2. **Pour chaque note, chercher des connexions** :
- **Par tags communs** : notes partageant 2+ tags → fort potentiel de lien
- **Par projet** : notes du même `project_name` ou tag `projet/...`
- **Par contenu sémantique** : concepts similaires, mêmes noms propres, mêmes outils mentionnés
- **Par chronologie** : note de décision qui mentionne un contexte décrit dans une autre note
3. **Ajouter les liens `[[...]]`** dans la section "Liens et contexte" de chaque note
4. **Mettre à jour le champ `related`** du frontmatter en conséquence
5. **Créer des liens bidirectionnels** quand c'est pertinent (si A pointe vers B, B devrait pointer vers A)
**Procédure par batch de 20 notes** :
1. Pour chaque note modifiée, chercher des connexions :
- **Par tags communs (2+)** via MCP `obsidian_manage_tags` → fort potentiel
- **Par projet commun** (même `project_name` ou tag `projet/*`)
- **Par contenu sémantique** (mêmes entités nommées : projets, outils, personnes évoqués)
2. Pour chaque connexion candidate, **fetch les 2 notes** (seulement maintenant, après filtering) et juger la pertinence
3. Ajouter les liens `[[...]]` dans la section "Liens et contexte" (crée-la si absente)
4. Mettre à jour `related` dans le frontmatter
5. Créer liens bidirectionnels (A→B implique B→A) si pertinent
**Critères pour créer un lien :**
- Les notes traitent du même sujet sous des angles différents → OUI
- Une note est une décision qui impacte un projet décrit dans une autre note → OUI
- Deux notes partagent le même tag `projet/...` → OUI (au moins via la MOC projet)
- Deux notes n'ont qu'un tag générique en commun (`domaine/tech`) → NON (trop vague)
**Critères STRICTS pour créer un lien** :
- ✅ Les notes traitent du même sujet sous des angles différents
- ✅ Une décision qui impacte un projet décrit ailleurs
- ✅ 2+ tags identiques non-génériques (ex: `projet/x` + `domaine/tech/ia`)
- ❌ 1 seul tag générique en commun (`domaine/tech`) → NON, trop vague
- ❌ Correspondance floue → NON, signaler dans rapport
### Passe 5 — Mise à jour des MOC
Objectif : maintenir les Maps of Content à jour dans `moc/`.
**Objectif** : maintenir les Maps of Content à jour.
Les MOC sont des index thématiques — elles ne contiennent pas de contenu propre, juste des listes organisées de liens vers les notes du vault.
**Filter** : notes touchées aujourd'hui → identifier les MOC concernées via leurs tags.
**Procédure :**
1. **Identifier les MOC existantes** dans `moc/`
2. **Pour chaque note créée/modifiée aujourd'hui**, vérifier si elle est référencée dans la MOC appropriée
3. **Ajouter les notes manquantes** dans la bonne section de la MOC
4. **Si aucune MOC n'existe** pour un domaine qui a 5+ notes → proposer d'en créer une
**Procédure** :
1. Lister MOC existantes dans `moc/`
2. Pour chaque note modifiée aujourd'hui, identifier la(les) MOC(s) concernée(s) via tags
3. Si la note n'y est pas référencée → l'ajouter dans la bonne section
4. Si un domaine a 5+ notes sans MOC → signaler dans rapport (pas créer auto — Tier 2)
**Structure d'une MOC :**
**Pas de création automatique de MOC** — c'est une décision Tier 2.
```markdown
---
title: "MOC [Domaine]"
type: resource
tags:
- moc
- domaine/...
status: active
summary: "Index thématique de toutes les notes liées à [domaine], organisé par sous-thèmes et projets"
source_llm: claude
updated: 2026-04-16T22:00:00
---
# MOC [Domaine]
## Circuit-breakers (protection tokens)
> [!summary]
> Index thématique maintenu automatiquement par obsidian-organizer.
Avant chaque passe, vérifier :
## [Sous-thème 1]
| Condition | Action |
|---|---|
| `inbox/` contient > 100 notes | Abord passe 1 seulement, signaler "inbox trop volumineuse, humain à l'aide" |
| Budget tokens quotidien atteint | Arrêt immédiat, rapport partiel, slack notif urgente |
| Erreur MCP (obsidian non disponible) | Retry 3× avec backoff, puis abort + slack notif |
| Un batch prend > 5 min | Abort du batch, passer au suivant, signaler |
- [[Note A]] — description courte
- [[Note B]] — description courte
Budget max organizer : **20k tokens/jour** (configurable dans `_adn/orchestration/budget-tokens.md`).
## [Sous-thème 2]
---
- [[Note C]] — description courte
## Gestion des questions (remplace "demander confirmation")
## Notes récentes
Si l'organizer rencontre une ambiguïté pendant le run automatique (2h du matin, pas d'humain) :
- [[Note du jour]] — ajoutée le 2026-04-16
```
1. **Ne jamais deviner**. Appliquer la règle la plus conservatrice ou ne pas agir.
2. Créer une note `inbox/daemon-questions/YYYY-MM-DD-organizer-{sujet}.md` avec :
- Contexte (quelle note, quelle décision ambiguë)
- 2-3 options proposées
- Option recommandée
3. Notif Slack : `🤖 organizer a une question — inbox/daemon-questions/...md`
4. Continuer le reste des passes en laissant la question en attente
**Règles MOC :**
- Trier les notes par sous-thème, pas chronologiquement (sauf section "récentes")
- Chaque entrée = lien + description courte (10-15 mots max)
- Mettre à jour `updated` de la MOC à chaque modification
- Les MOC standard à maintenir : MOC Tech, MOC Projets, MOC Contenu, MOC Perso, MOC Business
Jerem lit, décide, et répond soit en modifiant la note directement soit via chat DAEMON.
## Mode d'exécution
---
L'organizer peut être lancé de 3 façons :
## Rapport de fin d'exécution
1. **Passe complète** (par défaut) — Les 5 passes dans l'ordre. C'est le mode "passe du soir".
2. **Passe ciblée** — L'utilisateur demande une passe spécifique ("trie juste l'inbox", "enrichis les liens").
3. **Note unique** — L'utilisateur désigne une note spécifique à organiser.
## Rapport de fin
À la fin de chaque exécution, produire un rapport concis :
À chaque run, écrire dans `_adn/memory/cron-logs.md` (append) :
```markdown
## Rapport Organizer — 2026-04-16
## Organizer — 2026-04-19T22:15:00
### Passe 1 — Tri inbox
- 8 notes triées : 3→projects, 2→knowledge, 2→content, 1→decisions
- 1 note restée dans inbox (contenu ambigu — à catégoriser manuellement)
**Durée** : 3 min 42 s
**Tokens** : ~4200
### Passe 2 — Frontmatter
- 12 notes vérifiées, 4 corrections appliquées
- 2 warnings : summary manquant sur `veille-xxx.md`, `source_llm` absent sur `note-yyy.md`
**Passe 1 — Tri inbox** : 8 notes triées (3→projects, 2→knowledge, 2→content, 1→decisions), 1 restée en inbox
**Passe 2 — Frontmatter** : 12 notes vérifiées, 4 corrections auto, 2 warnings (summary manquant)
**Passe 3 — Tags** : 3 tags unifiés (domaine/ia → domaine/tech/ia), 1 tag orphelin signalé
**Passe 4 — Liens** : 15 nouveaux liens créés entre 9 notes
**Passe 5 — MOC** : MOC Tech +3 notes, MOC Projets +2 notes
### Passe 3 — Tags
- Tag `domaine/ia` unifié vers `domaine/tech/ia` (3 notes)
- 1 tag orphelin détecté : `domaine/crypto` (1 seule note)
### Passe 4 — Liens
- 15 nouveaux liens créés entre 9 notes
- Connexion notable : [[Décision auth JWT]] ←→ [[Veille OAuth2 2026]]
### Passe 5 — MOC
- MOC Tech mise à jour (+3 notes)
- MOC Projets mise à jour (+2 notes)
- Proposition : créer MOC Coaching (6 notes non indexées)
**Questions posées** : 1 (inbox/daemon-questions/2026-04-19-organizer-note-ambigue.md)
**Anomalies** : aucune
```
## Checklist de l'organizer
---
Avant de terminer, vérifie :
## Checklist avant de terminer
- [ ] Aucune note dans `inbox/` ne peut être triée (les restantes sont signalées)
- [ ] Toutes les notes modifiées ont un frontmatter conforme
- [ ] Les tags sont normalisés (minuscules, sans accents, hiérarchiques)
- [ ] Chaque note créée aujourd'hui a au moins 2 liens `[[...]]`
- [ ] Les MOC pertinentes sont à jour
- [ ] Le champ `updated` est mis à jour sur chaque note touchée
- [ ] Aucun contenu original n'a été supprimé ou altéré
- [ ] Le rapport de fin est produit
- [ ] Aucune note dans `inbox/` (racine) ne peut être triée (les restantes sont signalées avec raison)
- [ ] Toutes les notes modifiées aujourd'hui ont un frontmatter conforme à `_adn/conventions.md`
- [ ] Tags normalisés (minuscules, sans accents, hiérarchiques)
- [ ] Chaque note créée aujourd'hui a au moins 2 liens `[[...]]` (sinon warning)
- [ ] Les MOC concernées sont à jour
- [ ] `updated` mis à jour sur chaque note touchée
- [ ] `source_agent: organizer` ajouté dans frontmatter des notes modifiées
- [ ] Aucun contenu original supprimé ou altéré
- [ ] Rapport écrit dans `_adn/memory/cron-logs.md`
- [ ] Slack notif envoyé si questions dans `inbox/daemon-questions/`
---
## Modes d'exécution
| Mode | Trigger | Scope |
|---|---|---|
| **Nightly (automatique)** | Cron 22h Paris | Passes 1-5 complètes |
| **Manuel complet** | `openclaw agent --agent organizer -m "run complet"` | Passes 1-5 complètes |
| **Manuel ciblé** | `openclaw agent --agent organizer -m "passe 1 seulement"` | 1 seule passe |
| **Dry-run** | `--dry-run` flag | Simule, produit rapport sans modifier |
Le mode dry-run est utilisé la première semaine pour observer ce que l'organizer ferait avant de le laisser agir.