From 9e51ab20f776faf489a2f271bfe78fee419c9204 Mon Sep 17 00:00:00 2001 From: Tetardtek Date: Sat, 14 Mar 2026 03:49:20 +0100 Subject: [PATCH] docs: ARCHITECTURE.md + scribe-system v2 + bootstrap-spec --- ARCHITECTURE.md | 183 +++++++++++++++++++++++++++++++++++++++ profil/bootstrap-spec.md | 114 ++++++++++++++++++++++++ profil/scribe-system.md | 25 +++--- 3 files changed, 312 insertions(+), 10 deletions(-) create mode 100644 ARCHITECTURE.md create mode 100644 profil/bootstrap-spec.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..843a225 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,183 @@ +# ARCHITECTURE — Brain System + +> Rédigé : 2026-03-14 — pendant que c'est chaud. +> Les décisions non-évidentes, les pourquoi, les trade-offs assumés. +> Pour se souvenir dans 6 mois. Pour les gens qui fork. + +--- + +## C'est quoi le brain + +Un système de mémoire externe pour sessions Claude — persistent, versionné, multi-machine. + +**Problème résolu :** Claude oublie entre les sessions. Le brain ne oublie pas. + +**Ce que ça n'est pas :** un simple dossier de markdown. C'est un système avec des couches, des agents, des scribes, un protocole de coordination inter-sessions, et une logique de bootstrap. + +--- + +## Les 3 couches — décision fondamentale + +``` +KERNEL agents/, profil/ + Universel. Valable pour n'importe qui. + Partagé entre toutes les instances via symlinks ou clone. + → brain-template est le kernel exportable. + +INSTANCE focus.md, projets/, todo/, infrastructure/, PATHS.md + Personnel à une machine / un contexte. + Jamais dans le kernel. Jamais exporté tel quel. + +PERSONNEL progression/, capital.md + Intime. Jamais partagé, jamais forké. + Une personne, un repo, aucun export. +``` + +**Pourquoi 3 couches et pas 2 ?** +La ligne kernel/personnel est évidente. La couche instance est moins intuitive — elle existe parce qu'un même kernel peut tourner sur plusieurs machines avec des configs radicalement différentes (chemins, services, projets). Sans instance, on hardcode dans le kernel. Le kernel pollue. L'export devient impossible. + +--- + +## Les repos satellites — décision architecture + +Le brain n'est pas un monorepo. Chaque couche a son repo : + +| Repo | Chemin local | Couche | Push vers | +|------|-------------|--------|-----------| +| `brain` | `/home/tetardtek/Dev/Docs/` | Kernel + instance | Gitea privé | +| `brain-profil` | `Docs/profil/` | Kernel (profil perso) | Gitea privé | +| `brain-todo` | `Docs/todo/` | Instance | Gitea privé | +| `brain-toolkit` | `Docs/toolkit/` | Instance (patterns) | Gitea privé | +| `brain-progression` | `Docs/progression/` | Personnel | Gitea privé | +| `brain-agent-review` | `Docs/reviews/` | Instance (audits) | Gitea privé | + +Tous gitignorés dans `brain/` sauf leur propre `.git/`. + +**Pourquoi des repos séparés ?** +- Rythme de commit différent : `todo/` change tous les jours, `profil/` change rarement +- Exportabilité granulaire : on peut partager `profil/` sans exposer `todo/` ou `progression/` +- Isolation des accès : un collaborateur peut avoir accès à `reviews/` sans voir `progression/` +- Chaque scribe commit dans son repo — responsabilité claire, historique lisible + +--- + +## Le pattern `.env` du brain + +Même logique qu'un projet dev : + +``` +brain-compose.yml → .env.example (versionné, valeurs génériques) +brain-compose.local.yml → .env (gitignored, valeurs machine réelles) +CLAUDE.md.example → .env.example (versionné, template avec ) +~/.claude/CLAUDE.md → .env (non versionné, config live) +PATHS.md → .env (chemins réels de cette machine) +``` + +**La règle :** toute valeur qui change selon la machine vit dans un fichier gitignored ou dans le fichier local de la couche. Jamais hardcodée dans le kernel. + +--- + +## Pourquoi helloWorld plutôt qu'un bootstrap statique + +Le bootstrap statique (lire focus.md + tous les agents au démarrage) charge trop, charge à l'aveugle, ne s'adapte pas au contexte. + +helloWorld fait mieux : + +``` +Bootstrap statique helloWorld +───────────────── ────────────────────────── +Charge tout au démarrage Charge le minimum +Ignore le contexte Détecte le type de session +Ignore les feature flags Filtre les agents par tier +Ignore BRAIN-INDEX.md Scanne le CHECKPOINT avant tout +Statique Adaptatif +``` + +**Trade-off assumé :** helloWorld est un agent comme les autres — il peut halluciner, rater un signal. Le bootstrap statique était déterministe. On a choisi l'adaptabilité sur la déterminisme, parce que le brain est devenu trop grand pour être chargé en entier à chaque session. + +--- + +## BSI — Brain Session Index + +Problème : plusieurs sessions en parallèle peuvent modifier les mêmes fichiers sans se voir. + +Solution : `BRAIN-INDEX.md` — registre de claims + bus de signaux. + +``` +## Claims actifs → scribe uniquement — qui travaille sur quoi +## Signals → orchestrator-scribe uniquement — messages inter-sessions +## Historique → audit trail — ce qui s'est passé +``` + +**Locking optimiste + TTL :** on ne bloque pas, on déclare. Si deux sessions se croisent, le watchdog détecte et alerte. L'humain décide. + +**CHECKPOINT :** signal spécial A→A. Une session se snapshote elle-même dans BRAIN-INDEX.md. La session suivante (ou la même après compactage LLM) relit le checkpoint et reprend exactement là où c'était. Persisté dans git — survit à tout. + +--- + +## Session-as-identity — pourquoi pas de fork par rôle + +Problème initial : plusieurs rôles en parallèle (build, review, test) → on forke un brain par rôle → explosion de configs. + +Solution : le slug de session IS l'identité de routage. + +``` +sess-20260314-0900-build@desktop → rôle build +sess-20260314-0901-review@desktop → rôle review +sess-20260314-0902-test@desktop → rôle test +``` + +Un seul brain par machine. N sessions nommées. orchestrator-scribe route les signaux par `sess-id@machine` (message direct) ou `brain_name@machine` (broadcast). + +--- + +## Le Scribe Pattern — principe de non-contamination + +Règle dure : un agent métier n'écrit jamais directement dans le brain. + +``` +Agent métier → signal → scribe compétent → write +``` + +Sans ça : chaque agent écrit partout → dérive garantie. +Avec ça : chaque scribe est le seul responsable de son territoire. + +8 scribes, 8 territoires exclusifs. Voir `profil/scribe-system.md` pour la carte complète. + +--- + +## brain-template — le kernel exportable + +`brain-template` = le kernel sans la couche instance et sans la couche personnelle. + +``` +brain-template/ + agents/ ← tous les agents universels (zéro valeur perso) + profil/ ← profil universel (anti-hallucination, spec, patterns) + BRAIN-INDEX.md ← vide + brain-compose.yml ← spec versionnée + PATHS.md ← template avec + focus.md ← starter + README.md ← procédure d'installation complète +``` + +**Versioning :** semver `v0.x.x` — kernel en évolution. `v1.0.0` quand l'interface est contractuelle. +**Distribution :** repo Gitea privé aujourd'hui. GitHub public quand v1.0.0 validé. + +--- + +## Ce qui n'est pas dans ce doc + +- Comment créer un agent → `agents/_template.md` +- Comment les scribes fonctionnent → `profil/scribe-system.md` +- La spec BSI complète → `profil/bsi-spec.md` +- Les patterns d'orchestration → `profil/orchestration-patterns.md` +- Les règles de collaboration → `profil/collaboration.md` + +--- + +## Changelog + +| Date | Changement | +|------|------------| +| 2026-03-14 | Création — première ARCHITECTURE.md du brain, décisions non-évidentes documentées pendant que c'est chaud | diff --git a/profil/bootstrap-spec.md b/profil/bootstrap-spec.md new file mode 100644 index 0000000..23421e2 --- /dev/null +++ b/profil/bootstrap-spec.md @@ -0,0 +1,114 @@ +# Bootstrap Spec — Auto vs Explicite + Réflexes conventionnels + +> Rédigé : 2026-03-14 +> Résout : "Audit bootstrap — agents auto-déclenchés vs invocation explicite" +> "Réflexes conventionnels — invocations implicites par contexte" + +--- + +## Problème + +CLAUDE.md liste tous les agents dans une table uniforme. Mais ils n'ont pas tous le même mode de déclenchement. Certains doivent réagir automatiquement à chaque message — d'autres sont invoqués explicitement sur demande. Sans cette distinction, le bootstrap est flou et les agents ne savent pas quand ils sont censés s'activer. + +--- + +## Deux modes — définition + +### Mode A — Présence permanente (vérification continue) + +Ces agents observent CHAQUE message et interviennent si leurs seuils sont atteints. Ils ne sont pas "chargés" — ils sont présents. + +| Agent | Seuil de déclenchement | Intervient comment | +|-------|----------------------|-------------------| +| `coach` | Toujours actif | Observe la progression, signale les patterns récurrents, guide sans bloquer | +| `interprete` | Demande ambiguë / scope croisé / intention floue | Reformule avant que Claude agisse | +| `mentor` | Explication demandée / plan complexe / risque de mauvaise compréhension | Pédagogie, validation de compréhension | +| `aside` | Message préfixé `/btw` | 2-3 lignes, capture todo si actionnable, retour session | + +### Mode B — Agents 🔴 chauds (détection domaine) + +Chargés automatiquement quand le domaine est détecté dans la conversation. Un seul chargement par session suffit. + +``` +Domaine détecté → charger l'agent → il reste actif pour la session +``` + +Table de détection dans `~/.claude/CLAUDE.md` section "Agents 🔴 chauds". + +### Mode C — Agents 🔵 stables (invocation explicite) + +Ne se déclenchent jamais automatiquement. Invoqués par l'utilisateur ou sur signal d'un agent chaud. + +``` +"charge l'agent X" → lire agents/X.md immédiatement +"scribe, [action]" → scribe agit +"orchestrator-scribe, [action]" → orchestrator-scribe agit +``` + +--- + +## Réflexes conventionnels — invocations implicites + +Ces déclenchements n'ont pas besoin d'une instruction explicite. Ils sont des **réflexes du système** — Claude doit les appliquer sans qu'on le demande. + +### Réflexes toujours actifs + +| Signal contextuel | Réflexe attendu | +|------------------|-----------------| +| `/btw ` | `aside` — 2-3 lignes max, `→ on reprend.` | +| Session qui se termine naturellement | Proposer bilan scribes + checkpoint si session longue | +| `checkpoint` / `/checkpoint` | orchestrator-scribe pose signal CHECKPOINT dans BRAIN-INDEX.md | +| Tâche dans `focus.md` terminée | scribe la marque ✅ sans qu'on le demande | +| Agent forgé ou modifié | scribe vérifie AGENTS.md en fin de session | +| Gap infra identifié (port, service absent) | scribe le signale en fin de session même si non corrigé | + +### Réflexes sur domaine détecté + +| Signal contextuel | Réflexe attendu | +|------------------|-----------------| +| Fix sur code sensible (auth, tokens) | `security` suggère `testing` | +| Nouvelle feature en prod | `capital-scribe` signalé si milestone notable | +| Pattern validé en conditions réelles | `toolkit-scribe` proposé | +| "todo cette feature" dans un projet | `todo-scribe` vérifie + crée l'entrée si absente | +| Commit avec beaucoup de fichiers touchés | `git-analyst` proposé pour narration sémantique | + +### Réflexes de coordination inter-sessions + +| Signal contextuel | Réflexe attendu | +|------------------|-----------------| +| Travail terminé, autre instance doit reviewer | `orchestrator-scribe` pose READY_FOR_REVIEW | +| Session trop longue (compactage prévisible) | Proposer CHECKPOINT avant que ça arrive | +| Démarrage de session — watchdog | Scribe scanne Claims + Signals. helloWorld scanne CHECKPOINT. | + +--- + +## Ce qui NE doit PAS être un réflexe + +``` +❌ Charger des agents "au cas où" +❌ Lire des fichiers brain sans raison précise +❌ Proposer un bilan scribe toutes les 5 minutes +❌ Demander confirmation pour chaque micro-décision +❌ Interrompre le travail pour signaler un gap non urgent +``` + +**Règle :** les réflexes sont discrets. Ils agissent ou signalent en fin d'action, pas pendant. + +--- + +## Ordre de priorité des modes + +``` +1. Mode A (présence permanente) — toujours actif, en arrière-plan +2. Réflexes conventionnels — déclenchés sur signal contextuel précis +3. Mode B (🔴 chauds) — chargés sur détection domaine +4. Mode C (🔵 stables) — sur invocation explicite uniquement +``` + +--- + +## Changelog + +| Date | Changement | +|------|------------| +| 2026-03-14 | Création — résout "Audit bootstrap" + "Réflexes conventionnels". Trois modes distincts, table de réflexes, règle anti-bruit | diff --git a/profil/scribe-system.md b/profil/scribe-system.md index 83bf641..f828977 100644 --- a/profil/scribe-system.md +++ b/profil/scribe-system.md @@ -29,13 +29,16 @@ Le scribe est le seul responsable de la cohérence de son repo. | Scribe | Écrit où | Repo | Couche | Exportable | Cycle de vie | |--------|----------|------|--------|------------|-------------| | `scribe` | `focus.md`, `projets/`, `infrastructure/`, `agents/AGENTS.md`, `profil/objectifs.md` | `brain/` | Universel | ✅ | Permanent | -| `todo-scribe` | `todo/` | `brain/` (→ `todo/` futur) | Universel | ✅ structure | Stable quand todo en régime | -| `toolkit-scribe` | `toolkit/` | `toolkit/` | Universel | ✅ | Actif tant que nouveaux patterns | +| `todo-scribe` | `todo/` | `brain-todo/` | Universel | ✅ structure | Stable quand todo en régime | +| `toolkit-scribe` | `toolkit/` | `brain-toolkit/` | Universel | ✅ | Actif tant que nouveaux patterns | +| `orchestrator-scribe` | `BRAIN-INDEX.md ## Signals` uniquement | `brain/` | Universel | ✅ protocole | Permanent — multi-instance actif | +| `config-scribe` | `PATHS.md`, `infrastructure/` d'une instance | instance locale | Universel | ✅ structure | Invoqué sur `brain-compose new` | | `git-analyst` | Commits git (narration sémantique) | Tous repos | Universel | ✅ | Ponctuel — invoqué sur demande | -| `coach-scribe` | `journal/`, `skills/`, `milestones/` | `progression/` | Personnel | ❌ | Suit le coach — retraité ensemble | -| `capital-scribe` | `profil/capital.md` | `brain/` | Personnel | ❌ strippé | Suit objectifs — veille quand CV stabilisé | +| `coach-scribe` | `journal/`, `skills/`, `milestones/` | `brain-progression/` | Personnel | ❌ | Suit le coach — retraité ensemble | +| `capital-scribe` | `profil/capital.md` | `brain-profil/` | Personnel | ❌ strippé | Suit objectifs — veille quand CV stabilisé | > `helloWorld` et `coach` ne sont **pas** des scribes — ils observent et rapportent, jamais n'écrivent. +> `orchestrator-scribe` n'écrit QUE dans `## Signals` — jamais dans `## Claims` (→ `scribe`). --- @@ -44,12 +47,13 @@ Le scribe est le seul responsable de la cohérence de son repo. Quand plusieurs scribes écrivent dans la même session : ``` -1. todo-scribe → commit brain/ "todo(): " -2. capital-scribe → commit brain/ "feat(capital): " si signal reçu -3. scribe → commit brain/ "feat(brain): " toujours en dernier sur brain/ -4. toolkit-scribe → commit toolkit/ "feat(toolkit): " si signal reçu -5. coach-scribe → commit progression/ "feat(progression): " si session coach -6. git-analyst → valide cohérence sémantique des commits optionnel +1. todo-scribe → commit brain-todo/ "todo(): " +2. toolkit-scribe → commit brain-toolkit/ "feat(toolkit): " si signal reçu +3. coach-scribe → commit brain-progression/ "feat(progression): " si session coach +4. capital-scribe → commit brain-profil/ "feat(capital): " si signal reçu +5. scribe → commit brain/ "feat(brain): " toujours en dernier sur brain/ +6. orchestrator-scribe → commit brain/ "feat(signals): " si inter-sessions actives +7. git-analyst → valide cohérence sémantique des commits optionnel ``` **Règle :** `scribe` est toujours le dernier à commiter sur `brain/` — il a la vue complète de ce que les autres ont écrit. @@ -110,3 +114,4 @@ Quelqu'un qui fork récupère le moteur d'écriture. Pas le cerveau, pas la prog | Date | Changement | |------|------------| | 2026-03-13 | Création — émergé de la session agent-review + architecture multi-repos + Scribe Pattern | +| 2026-03-14 | Ajout orchestrator-scribe (## Signals) + config-scribe — 8 scribes, repos satellites mis à jour, ordre de commit v2 |