feat(template): ADRs 018-035 — 14 décisions architecturales manquantes

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>]
This commit is contained in:
2026-03-18 22:38:36 +01:00
parent 519b22809b
commit 8c95b70314
14 changed files with 1762 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
---
scope: kernel
name: 018-migration-rust-strangler-fig-toolkit
type: decision
context_tier: 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 :
1. **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.
2. **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** :
1. Python brain-engine reste en prod pendant toute la migration
2. Un service Rust monte en parallèle sur un port distinct
3. Apache redirige les endpoints un par un vers Rust dès qu'ils sont stables
4. 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 :
```rust
// 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), futur `brain-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