Synchronise le template avec les décisions fondatrices 2025-2026 : - 018 : migration Rust strangler fig toolkit - 023 : Cortex/Cosmos product vision - 025 : cortex composition operator - 026 : IPC context packet access matrix - 027 : ambient autonomy engine - 028 : learning loop detect-iterate - 029 : Cosmos frontend brain - 030 : boot mode empirical validation - 031 : distribution model - 032 : execution mode vs workflow - 033/033a : embedding language strategy + zone filter - 034 : infra separation local/VPS/template - 035 : session pilote mode (ADR-035) Dépersonnalisation : keys/brain.<OWNER_DOMAIN>, deciders: [<owner>]
4.2 KiB
scope, name, type, context_tier
| scope | name | type | context_tier |
|---|---|---|---|
| kernel | 018-migration-rust-strangler-fig-toolkit | decision | warm |
ADR-018 — Migration Rust : strangler fig + toolkit pattern
Date : 2026-03-17 Statut : actif Décidé par : brainstorm session brain
Contexte
Le brain-engine actuel est en Python (FastAPI). Deux problèmes émergent à mesure que le modèle d'utilisation se précise :
-
BSI sur git n'est pas viable pour l'async multimodal — git est synchrone et lourd. Un vrai bus d'événements async requiert un backend capable de gérer des channels, du state en mémoire, et de la persistance légère.
-
Cold start multi-plateforme — le modèle d'utilisation cible (session pilote + sessions doc + CLI futur) implique de tourner sur laptop, VPS, et potentiellement d'autres machines. Une dépendance Python (venv, pip, uvicorn, FastAPI) est un frein.
Rust répond aux deux : binaire unique cross-platform, tokio pour l'async réel, performances natives.
Décision
Migration progressive de brain-engine vers Rust via le pattern strangler fig :
- Python brain-engine reste en prod pendant toute la migration
- Un service Rust monte en parallèle sur un port distinct
- Apache redirige les endpoints un par un vers Rust dès qu'ils sont stables
- Quand Rust couvre ~80% des endpoints, Python est éteint
Ordre de migration :
Phase 1 — Fondations (forge les patterns toolkit)
/health → Axum hello world + config loading
/state → tokio + pm2 query + JSON response
Phase 2 — Core read-only
/agents → SQLite read + Layer 2 gate
/workflows → état dérivé
/focus → lecture fichier
Phase 3 — Write + auth
/brain/:path → write + tier enforcement
/tier → key validation
Phase 4 — RAG (dernière, la plus Python-dépendante)
/boot → embeddings → à évaluer selon maturité Rust ML
Toolkit pattern — KPI stonks
Chaque endpoint extrait des patterns réutilisables qui s'appliquent aux suivants :
// Ces 4 patterns apparaissent sur chaque endpoint
// On les forge une fois sur /health + /state
1. Auth middleware → x-api-key validation
2. _is_localhost() → Layer 2 gate
3. JSON response → helpers 200/401/403/404
4. Config struct → env vars → typed config
Courbe de vélocité :
Endpoint 1 (/health) → 2 jours (Rust + forge toolkit)
Endpoint 2 (/state) → 4h (patterns existent)
Endpoint 3+ → 30min (composition pure)
Le toolkit brain-rust devient lui-même distribuable — partie du kernel open.
Stack cible
| Besoin | Crate |
|---|---|
| HTTP async | axum (tokio-based) |
| Async runtime | tokio |
| Sérialisation | serde + serde_json |
| SQLite | rusqlite ou sqlx |
| Config env | dotenvy |
| Process query (pm2) | std::process::Command + parse JSON |
Alternatives considérées
| Option | Raison du rejet |
|---|---|
| Rester Python | Cold start lourd, pas de binaire unique, bus async limité |
| Greenfield Rust | Big bang = risque, Python en prod = valeur certaine à ne pas perdre |
| Go | Rust = binaire plus léger, memory safety compile-time, "le pti crab fait de l'oeil" |
| Node.js | Déjà Python en prod, pas besoin d'ajouter un 3e runtime |
Conséquences
Positives :
- Zéro downtime pendant la migration
- Apprentissage Rust progressif sur des vrais endpoints en prod
- Chaque iteration dégage un toolkit réutilisable
- Binaire unique → cold start trivial sur toute plateforme
- BSI v2 possible : vrai bus async (tokio channels + SQLite)
Négatives / trade-offs assumés :
- Deux services à maintenir pendant la transition
- Phase RAG (embeddings) : Rust ML moins mature que Python — décision reportée
- Temps d'apprentissage Rust non nul sur les premières itérations
Références
- Fichiers concernés :
brain-engine/(Python, à migrer), futurbrain-engine-rs/ - ADR-015 : architecture L1/L2
- ADR-016 : BSI → now.md (le bus async justifie Rust)
- ADR-017 : brain_state Layer 2 (premier endpoint candidat Phase 1)
- Sessions où la décision a émergé : session brain 2026-03-17