Temps de lecture : ~10 min
TL;DR
- Le problème : 260 notes Zettelkasten dans un vault Obsidian — impossible de retrouver les 10 bonnes dans les 10 secondes où elles sont utiles
- La solution naïve : charger tout le vault en contexte LLM. 239 notes × ~600 mots × 1,33 ≈ 191 000 tokens. Qualité dégradée, coût explosé. Abandonné en une semaine.
- L’architecture réponse : 4 couches (mémoire persistante → graphe de connaissances → pipeline de traitement → branches de production) + chargement sélectif déclaré par chaque skill
- La règle qui change tout : le LLM ne voit jamais plus que ce dont il a besoin — chaque skill déclare explicitement ses fichiers sources dans son en-tête
- Ce qui a vraiment échoué : le tout-automatique, le CLAUDE.md monolithique, les agents parallèles, et le comptage de queues depuis le cache de session
Pourquoi documenter ça en public
Le TL;DR ci-dessus dit ce qui fonctionne. Ce qu’il ne dit pas : pourquoi les quatre solutions évidentes ont toutes échoué avant d’arriver là — et dans quel ordre.
La plupart des articles sur les “second cerveaux” montrent le résultat final :
- un vault bien organisé,
- un workflow propre,
- un diagramme d’architecture élégant.
Ce que personne ne montre : les 6 mois de tentatives ratées qui ont précédé.
Cette série — 7 articles — documente comment un vault Obsidian de 260 notes est devenu un OS de la connaissance opérationnel piloté par LLM. L’architecture réelle. Le code réel. Et, systématiquement, les impasses.
Le problème de fond est simple à formuler : une connaissance accumulée mais non structurée est inaccessible à l’IA. JARVIS est la réponse architecturale à ce problème, construite à l’échelle 1, depuis une situation réelle.
Si vous êtes consultant en cabinet et que vous reconnaissez cette situation — des années de missions, de méthodes, d’observations accumulées qui existent quelque part mais ne se retrouvent plus quand vous en avez besoin — cette série est pour vous. Elle documente comment ce problème de capitalisation se règle architecturalement, pas disciplinairement.
Le problème : une connaissance non retrouvable
J’accumule des observations terrain sur le delivery logiciel, des connexions entre la philosophie stoïcienne et les organisations modernes, des données DORA, des retours d’expérience sur les Digital Factories. Depuis 2025, tout ça vit dans Obsidian avec une méthode Zettelkasten : chaque note est un claim atomique, pas un sujet. “L’IA amplifie ce qui est déjà là, elle ne corrige pas ce qui est cassé” est une note. “L’IA” n’en est pas une.
260 notes permanentes. 11 MOCs (Maps of Content) pour naviguer entre elles. Des centaines de liens wikilink qui tissent un graphe.
Le problème : Claude a une fenêtre de contexte de 200 000 tokens. Ça semble énorme jusqu’au calcul : 260 notes × ~600 mots en moyenne × 1,33 tokens/mot ≈ 207 000 tokens. On dépasse la fenêtre de contexte — et surtout, charger tout ça à chaque session est absurde. Pour rédiger un article sur le Change Failure Rate, j’ai besoin de 8 notes, pas de 260.
Le vrai problème n’est pas le volume. C’est le routage : comment identifier les 8 notes pertinentes parmi 239 sans lire les 239 ?
Ce qui ne marche pas — et pourquoi
Option 1 : charger tout le vault. Testé en premier, abandonné rapidement. Résultat : sessions lentes, coût token explosé, et — paradoxalement — qualité moindre. Un LLM noyé dans du contexte non pertinent perd en précision. Le phénomène est observable dans les sessions longues : au-delà de ~50k tokens de contexte saturé, la précision des réponses se dégrade indépendamment de la qualité des instructions — Anthropic évoque ce mécanisme dans ses guides de context engineering.
Option 2 : un chatbot RAG générique. Les outils RAG traitent les notes comme des documents interchangeables. Ils chunkent du texte — pas des claims liés à d’autres claims. La structure sémantique du graphe Zettelkasten disparaît dans le découpage. Ce qui remonte est du texte extrait de son contexte relationnel : pertinent sur le mot-clé, aveugle sur la connexion.
Option 3 : tout garder dans la mémoire de session. Les LLMs n’ont pas de mémoire persistante entre les sessions. Chaque conversation repart de zéro. Pour un système de production qui s’étale sur des semaines, c’est structurellement insuffisant.
Option 4 : agents parallèles. J’ai voulu accélérer le traitement des notes en parallélisant
plusieurs agents Claude Code sur le même vault. Race conditions sur ops/queue.md, conflits de
permissions sur les fichiers, erreurs qui n’apparaissent qu’après 10 minutes de traitement. Claude Code n’est pas conçu pour le multi-agent parallèle sur un filesystem local partagé. Revenu au séquentiel — 3x plus lent, 10x plus fiable.
Ce que ces quatre échecs ont en commun : ils traitent le LLM comme un outil universel qu’on branche sur une base de données. JARVIS part du principe inverse — le LLM est l’OS, et c’est le système qui contrôle ce qu’il voit.
L’architecture en 4 couches
┌─────────────────────────────────────────────────┐
│ COUCHE 4 — Branches de production │
│ /mens-libera, /article-vision-ceo, │
│ /notes-de-terrain, /linkedin-posts, │
│ /emerge, /suggest, /veille... │
├─────────────────────────────────────────────────┤
│ COUCHE 3 — Pipeline de traitement │
│ /reduce → /reflect → /reweave → /verify │
│ Orchestré par /ralph │
├─────────────────────────────────────────────────┤
│ COUCHE 2 — Graphe de connaissances │
│ RESSOURCES/Notes/ (260 notes Zettelkasten) │
│ + RESSOURCES/MOCs/ (11 cartes de navigation) │
├─────────────────────────────────────────────────┤
│ COUCHE 1 — Mémoire persistante │
│ self/ — chargée sélectivement par chaque skill │
└─────────────────────────────────────────────────┘
Couche 1 — La mémoire persistante (self/)
self/ contient ce que JARVIS doit savoir pour agir avec cohérence : voix et style (identity.md), ICP cible (icp.md), parcours chiffré (parcours_pro_key_facts.md), état inter-sessions (memory.md), objectif global (northstar.md), casquettes actives (roles.md).
La règle critique : chaque skill déclare en en-tête les fichiers self/ qu’elle charge.
La skill /reflect ne charge rien — tisser des liens entre notes ne requiert aucun contexte
personnel. La skill /mens-libera charge identity.md + icp.md + parcours_pro_key_facts.md — elle a besoin de la voix, de la cible, et de l’arsenal de crédibilité. Jamais plus.
Couche 2 — Le graphe de connaissances (RESSOURCES/)
239 notes atomiques, chacune avec un titre en forme de claim et un frontmatter structuré. 11 MOCs (Maps of Content) qui servent de cartes de navigation.
Les MOCs sont la clé du routage token-efficient. Quand une skill cherche des notes pertinentes, elle commence par lire les frontmatters des MOCs — pas leur contenu complet. Elle identifie les MOCs candidats par tags, puis charge sélectivement les sections concernées. Une session ciblée charge 3 à 5 notes. Pas 260.
Couche 3 — Le pipeline de traitement
Quand une nouvelle source entre dans le système (article lu, observation terrain, idée brute) :
Record → ops/inbox/ capture zéro friction, aucun traitement
Reduce → /reduce source brute → claims Zettelkasten atomisés
Reflect → /reflect nouvelles notes → liens vers le graphe existant
Reweave → /reweave notes existantes → liens rétrospectifs vers la nouvelle
Verify → /verify contrôle qualité schéma + frontmatter
Rethink → /rethink audit périodique — mensuel, pas quotidien
/ralph orchestre l’enchaînement — une tâche à la fois, jamais en parallèle.
Couche 4 — Les branches de production
20 skills actives, chacune dans .claude/commands/[nom]/SKILL.md. Chaque SKILL.md est
l’instruction système de cette skill : mission, sources, règles, fichiers self/ à charger.
Cette série de 7 articles est produite par la skill /notes-de-terrain.
Le chargement sélectif en pratique
Le principe de chargement sélectif se voit directement dans l’en-tête de chaque skill.
Exemple extrait du frontmatter de la skill /mens-libera :
context:
charge:
- self/identity.md
- self/parcours_pro_key_facts.md
- self/icp.md
- self/competitive-positioning.md
- WRITING PRODUCT/Mens Libera/CLAUDE.md
ne_pas_charger:
- self/roles.md
- self/memory.md
- RESSOURCES/Notes/
Ce n’est pas de la documentation — c’est du context engineering. La skill déclare son budget d’attention avant même de commencer à travailler. Si elle a besoin d’autre chose en cours de route, elle le retriève just-in-time via le MCP.
La logique inverse est ce qui tue les systèmes naïfs : charger tout “au cas où” garantit le context rot.
Les hooks : le ciment de la cohérence inter-sessions
Le plus grand obstacle d’un système LLM au quotidien n’est pas la qualité du modèle. C’est l’amnésie structurelle : chaque session repart de zéro.
JARVIS résout ça avec 4 hooks configurés dans .claude/settings.json :
SessionStart (démarrage) : charge 5 fichiers (memory.md, northstar.md, identity.md,
icp.md, roles.md), exécute le health-check sur les queues, injecte le briefing d’état.
Coût : < 3 000 tokens. Résultat : je n’ai jamais à ré-expliquer où j’en suis.
PostToolUse avec matcher Write|Edit|Create (après chaque écriture dans le vault) : détecte
si une golden source vient d’être modifiée, pose un flag docs: pending dans la queue si
nécessaire. Sensor computationnel déterministe, < 1 seconde, zéro coût LLM. Les dérives de
documentation sont signalées avant la fin de session.
PreCompact (avant compaction contexte) : génère un digest d’état depuis le disque — comptes
réels des queues, focus actif — et le snapshote dans ops/sessions/. La compaction n’est pas un
oubli brutal : c’est une transition contrôlée avec handoff d’état.
Stop (fin de session) : vérifie les flags en attente (docs:pending, etc.), déclenche les actions de clôture. La session du mardi reprend exactement là où la session du lundi s’est arrêtée.
L’article 4 de cette série entre dans les détails de chaque hook : comment ils sont implémentés, quels problèmes ils résolvent, et ce qu’ils ne peuvent pas résoudre.
Ce qui a échoué avant d’arriver là
Phase 1 — Le tout-automatique
Première vision : détection et traitement automatique de toutes les nouvelles sources en arrière-plan. Résultat : des notes créées à partir de matière non validée, des claims qui n’étaient pas les miens, un graphe qui commençait à me ressembler de moins en moins. Revenu à un modèle semi-automatique : le pipeline se déclenche sur demande explicite. Ce n’est pas une contrainte technique — c’est une décision de conception. Le jugement reste dans la boucle.
Si vous avez déjà essayé de déléguer la prise de notes à un outil sans décider ce qui vaut la peine d’être gardé — vous reconnaissez ce problème.
Phase 2 — Le CLAUDE.md monolithique
Toutes les règles du système dans un seul fichier CLAUDE.md à la racine. Le fichier dépassait 800 lignes. Chaque session chargeait l’intégralité — y compris les 70% de règles non pertinentes pour la tâche en cours. Solution : un CLAUDE.md racine pour les règles transversales, des CLAUDE.md dans chaque sous-répertoire pour les règles spécifiques au contexte. Chargement sélectif structurel.
Phase 3 — Les agents parallèles
Tentative d’accélérer le traitement des queues en parallélisant plusieurs agents Claude Code.
Race conditions sur ops/queue.md. Deux agents qui écrivent simultanément la même note avec
des contenus divergents. Erreurs de permissions qui n’apparaissent qu’après 10 minutes de
traitement — au moment où défaire le travail coûte plus cher que recommencer. Le traitement
séquentiel via /ralph est plus lent et structurellement fiable.
Phase 4 — Le comptage depuis le cache de session
Bug subtil à double manifestation : des skills affichaient des comptes de queues lus depuis le contexte courant plutôt que depuis le filesystem. Le vault signalait “3 notes en attente” ; les 3 notes avaient été traitées dans la session précédente. Deuxième manifestation : le hook SessionStart calculait les comptes depuis la mémoire compactée, pas depuis les fichiers.
Règle ajoutée dans le CLAUDE.md racine : avant tout compte de queue, relire le fichier depuis le disque. Pas de cache de session. La donnée opérationnelle vient du filesystem, jamais du contexte LLM.
Tradeoffs et ce qu’on a laissé de côté
Ce que le système gère bien : production de contenu avec cohérence de voix sur des semaines, navigation sémantique dans le graphe, mémoire inter-sessions sans friction, pipeline de traitement traçable et reproductible.
Ce qu’il ne gère pas encore : ingestion mobile (capturer une idée depuis le téléphone reste
manuel), détection automatique de contradictions entre notes (implémentée dans /rethink --deep, mais invocation manuelle trimestrielle), péremption des notes (une note de 2024 avec des données 2023 passe les mêmes filtres de recherche sémantique qu’une note récente).
Ce qui est délibérément manuel : validation des claims avant création d’une note, décisions
éditoriales (quelle note dans quel article), revue des suggestions de /suggest. Ces trois éléments restent humains — non pas par impossibilité technique, mais parce que les automatiser produirait du contenu qui n’est pas le mien.
La dette visible : 4 hooks actifs, 20 skills, 13 fichiers self/, 4 scripts Python de
maintenance. Surface de maintenance non triviale. Un hook bugué peut bloquer une session entière.
L’article 7 de cette série fera le bilan complet de ce qui reste cassé — mais seulement après que les 6 autres auront été publiés.
Ce qui vient ensuite
Cette architecture n’est que la surface. Six articles vont documenter les couches une par une :
Article 2 — Le MCP jarvis-vault : pourquoi la recherche par mot-clé échoue sur un vault
Zettelkasten, comment une recherche sémantique locale avec embeddings (HNSW, @xenova/transformers) résout le problème de routage.
Article 3 — Le pipeline 6Rs : modéliser son système de connaissance comme un système de production, et pourquoi chaque étape doit être isolée dans son propre espace d’attention.
Article 4 — Les hooks en détail : ingénierie du contexte et du harness dans un système LLM long-terme — ce que Karpathy appelle context engineering et Hashimoto harness engineering.
Articles 5 & 6 — Les 5 phases d’évolution de JARVIS, et le système de skills : comment le système a appris à s’auto-piloter sans perdre la cohérence sur la durée.
Article 7 — Bilan honnête : ce qui a vraiment changé, ce qui reste cassé, ce que je referais différemment. Uniquement après publication des 6 premiers.