Un système d'exploitation personnel qui tourne sur Claude Code. Le stockage est du markdown brut sous git — sans base de données, sans service, sans compte. Un lien, une présentation ou une tâche jetés depuis un téléphone dans un canal Discord sont extraits, classés, mis en gabarit et archivés, pour arriver dans le dépôt sous forme de pull request en attente de relecture.
| Point de friction | Ce qui est fait ici |
|---|---|
| Des tâches éparpillées entre messageries, courriels et mémoire | Toutes les actions convergent vers un registre unique, tasks/TASKS.md, dont un script valide le format et dont les identifiants doivent être uniques |
| Les documents arrivent dans tous les formats — pages web, Word, diapositives, PDF, enregistrements | scripts/intake/extract.py les réduit tous à du texte brut, que wb-intake digère ensuite |
| Archiver n'est pas retrouver — trois mois plus tard, c'est introuvable | Gabarits obligatoires et frontmatter YAML, validés par machine, classés selon PARA, avec un index généré |
| On voit quelque chose d'utile sur son téléphone, et on l'a oublié une fois revenu au bureau | On le dépose dans le canal Discord #inbox ; le pont le récupère, Claude le digère et ouvre une PR |
Trois canaux d'entrée convergent vers un même pipeline. Il n'y a qu'une étape au milieu — la compétence
wb-intake extrait, classe et applique un gabarit — et la sortie se répartit vers quatre destinations.
Chaque digestion se termine par une pull request plutôt que par une écriture directe sur le tronc :
le verrou humain est la seule partie de ce système qui ne peut pas être sautée.
Dans ce système, celui qui écrit tous les jours est Claude, pas moi. Une règle inscrite dans
CONTRIBUTING.md sous forme d'un paragraphe de conseils en langue naturelle sera immanquablement diluée
après quelques dizaines de sessions. D'où une méta-règle : chaque règle doit porter un contrôle qui s'exécute
automatiquement (règle 2), et un contrôle vérifie cette propriété elle-même —
all_rules_have_checks.py parcourt la liste des règles, et toute règle sans contrôle correspondant fait
passer la CI au rouge.
Une seule commande, python3 scripts/run_checks.py, les exécute tous. Au vert, le squelette est intact.
Une décision mérite sa place dans design/ à un seul critère : le moi futur demandera-t-il
« pourquoi cela a-t-il été tranché ainsi ? », et la réponse est-elle absente du code ?
Un seul utilisateur, aucun budget d'exploitation, et en cas de panne c'est moi qui répare. Discord plutôt que
Telegram ou iMessage parce qu'il faut plusieurs canaux pour trier (#inbox / #tasks /
#daily / #refs) et de la place pour ajouter plus tard d'autres robots, chacun avec sa
fonction. Les plateformes chinoises conviendraient mieux aux conditions réseau et à l'aperçu des fichiers Office,
mais elles imposeraient d'entretenir un pont dès le premier jour — contre le principe de faire fonctionner avant
d'ajouter de la complexité.
La vraie contrainte n'est pas fonctionnelle : c'est que celui qui écrit est un agent. Markdown + git fait de
chaque écriture un diff — condition préalable au verrou de fusion humain, et raison pour laquelle la recherche
plein texte se réduit à grep. Aucune dépendance, aucun service, aucun compte ; dans dix ans,
cat le lira encore. Le prix à payer : les requêtes complexes demandent un script, et quelques
milliers de fichiers finiront par appeler un index.
Le plugin officiel entièrement configuré, le bot ne répondait toujours pas. La cause : il reçoit par la passerelle
Discord — un WebSocket — et le WebSocket ne passe pas sur cette machine : le DNS résolvait vers une adresse d'une
plage Facebook, et une fois le DNS corrigé, les couches IP et SNI étaient bloquées elles aussi. Après avoir testé
sept variantes une à une, la conclusion était nette : seul le WebSocket était bloqué ; le REST fonctionnait
parfaitement. Le pont est donc devenu un script Python sans dépendance qui sonde l'API REST de Discord,
urllib lisant nativement https_proxy.
Le critère de ce diagnostic n'était pas « la connexion est établie » mais la trame HELLO (op:10) que la
passerelle Discord doit envoyer après la poignée de main. Ne guetter que « c'est connecté » produit des faux positifs
— trois processus restaient en SYN_SENT tout en ayant l'air de tourner. Choisir un critère incapable de
mentir est la seule chose qui fasse gagner du temps sur ce type de problème réseau.
ProgramArguments doit nommer le chemin réel de l'interpréteur, pas le raccourci /usr/bin/python3, sinon le contrôle de permissions s'attache au mauvais binaire.
Les mécanismes de gouvernance — chaque règle porte un contrôle, les contrats agent-loop / agent-verify, garder
CLAUDE.md court — sont distillés d'un projet antérieur et d'une boîte à outils construite en parallèle ;
la forme du pipeline « inbox → PR » est empruntée à l'éclaireur de références de ce projet. Autrement dit, ce n'est
pas un flux conçu à partir de rien, mais deux ensembles de pratiques déjà éprouvées en conditions réelles, ramenés
au plus petit squelette qu'une seule personne puisse entretenir.