240 lines
20 KiB
Markdown
240 lines
20 KiB
Markdown
Je vais analyser la solution Assistant V2. Commençons par explorer la structure du projet et localiser les références à "Assistant V2".
|
||
|
||
|
||
|
||
Il y a un dossier `docs/Assistant-V2/` avec plusieurs documents de spécification. Explorons-le en détail.
|
||
|
||
|
||
|
||
Let me lire le document principal et les documents de phase.
|
||
|
||
|
||
|
||
Continuons la lecture du document principal puis des phases.
|
||
|
||
|
||
|
||
Maintenant, lisons les documents de phase V2.1. Vérifions d'abord leur taille.
|
||
|
||
|
||
|
||
Ces documents sont volumineux. Je vais déléguer le résumé des phases 2 à 5 à des sous-agents en parallèle, pendant que je lis moi-même la phase 0 (fondations) et la phase 1, et que je vérifie l'état réel du code.
|
||
|
||
|
||
|
||
|
||
|
||
The sub-agents reference a parent document `ASSISTANT-V2.1.md`. Let me check whether it exists, read phases 0 and 1 myself, and inspect the actual backend state.
|
||
|
||
|
||
|
||
Now let me read phase 1 and verify the actual codebase state — whether any of this exists (memory store, runs, policies) and how it's tracked in the roadmap.
|
||
|
||
|
||
|
||
Excellent picture forming. Let me verify the missing parent document references, and how (if at all) this is registered in the roadmap/todolist.
|
||
|
||
|
||
|
||
Key finding: IDs may collide with existing roadmap items. Let me inspect the roadmap's current/upcoming sections and the highest IDs in use.
|
||
|
||
|
||
|
||
Let me do a final quick check on dependencies and existing data stores to ground the component list.
|
||
|
||
|
||
|
||
J'ai lu l'intégralité de la documentation `docs/Assistant-V2/` (7 documents), vérifié l'état réel du code, et croisé le tout avec `ROADMAP.md`, `ISSUES_TODOLIST.md` et les conventions `AGENTS.md`. Voici l'analyse complète.
|
||
|
||
---
|
||
|
||
## 0. Verdict en une phrase
|
||
|
||
**Assistant V2 (et sa suite V2.1) est aujourd'hui une conception de très bonne qualité, mais 100 % non implémentée, non enregistrée dans le Roadmap, et dont le plan d'IDs est cassé par des collisions avec des features déjà livrées.** Le contenu technique est solide et réutilise finement l'existant ; la dette est d'abord méthodologique et documentaire, pas architecturale.
|
||
|
||
---
|
||
|
||
## 1. Cartographie des documents
|
||
|
||
| Fichier | Génération | Statut déclaré | IDs couverts |
|
||
|---|---|---|---|
|
||
| `docs/Assistant-V2/ASSISTANT-V2.md` (528 l.) | **V2** — 2026-10-08 | « Spécification (non implémentée) » | #191 → #201 |
|
||
| `assistant-v21-phase-0-socle-sur.md` (279 l.) | **V2.1** — 2026-10-09 | « Prêt à implémenter » | #191,#192,#193,#206,#213 + amorce #212 |
|
||
| `assistant-v21-phase-1-le-travail.md` (276 l.) | V2.1 | Prêt à implémenter | #202,#203,#204,#205 |
|
||
| `assistant-v21-phase-2-temps-reel.md` | V2.1 | Prêt à implémenter | #200,#194,#199,#208,#214 |
|
||
| `assistant-v21-phase-3-le-monde.md` | V2.1 | Prêt à implémenter | #195,#196,#197,#198,#207 |
|
||
| `assistant-v21-phase-4-les-gens.md` | V2.1 | Prêt à implémenter | #211,#209,#201 |
|
||
| `assistant-v21-phase-5-extension.md` (160 l.) | V2.1 | Cadre prêt | #210,#212 |
|
||
|
||
**Fait saillant n°1 — document parent manquant.** Les 5 phases V2.1 s'appuient toutes sur un `ASSISTANT-V2.1.md` (§2 P1–P16, §6.1, §8.2, §9.2/9.3, §10.2, §13.2, §15, §16, §19, §21). **Ce fichier n'existe nulle part dans le dépôt.** Conséquence directe : toutes les références croisées sont pendantes — notamment les schémas exacts des tables `tasks`/`inbox_items`/`facts`/`entities`/`agent_runs`, les règles de politique §15.2, et surtout **les définitions des golden tasks G1→G14** (§16.1) qui sont pourtant le critère d'acceptation central de chaque phase. On ne peut pas implémenter les phases « telles quelles » sans ce parent.
|
||
|
||
**Fait saillant n°2 — collision d'IDs.** Le Roadmap (v2.63.0) a déjà consommé ces ID :
|
||
|
||
- `#191` = « Chat — suppression de post, DM, link preview OG » (livré 2.60.0)
|
||
- `#192` = « Chat — boîte auto-agrandissante, accusé ✓✓ » (livré 2.61.0)
|
||
- `#194` = « Dossier personnel par utilisateur » (🔵 **en cours**, fiche `docs/features/user-home-194.md`)
|
||
|
||
Or V2.1 assigne #191 = purge Ollama, #192 = mémoire socle, #194 = consolidation nocturne. **Ce sont des collisions avec du code déjà publié**, ce qui viole la règle n°1 d'`AGENTS.md` (« ID stable, jamais réutilisé »).
|
||
|
||
**Fait saillant n°3 — plan non enregistré.** Aucune des 7 docs n'est référencée dans `ROADMAP.md`, dans la cartographie documentaire d'`AGENTS.md`, ni dans `docs/features/`. Le programme entier vit dans une bulle documentaire non branchée sur le processus de livraison.
|
||
|
||
---
|
||
|
||
## 2. Résumé de la solution
|
||
|
||
### Vision (4 piliers)
|
||
Transformer ObsiGate d'un « portail de notes avec assistant » en **second cerveau conversationnel autonome** :
|
||
1. **Il se souvient** — mémoire long terme structurée (faits, préférences, entités, décisions), consolidée la nuit, **auditable en markdown dans le vault** (anti-boîte-noire).
|
||
2. **Il agit** — sur le vault **et** les services externes connectés (Gmail, Google Agenda, Teams, Discord, Notion, Drive…).
|
||
3. **Il anticipe** — rappels conversationnels, briefing quotidien, détection de boucles ouvertes et d'engagements non tenus.
|
||
4. **Il centralise** — ObsiGate devient le point d'entrée unique (desktop Tauri, MCP externe, PWA mobile → *ce même* cerveau).
|
||
|
||
### Principes directeurs
|
||
- **V2 (P1–P9)** : autonomie du stack (1 conteneur, Ollama retiré) · zéro framework d'agent externe · un outil = un `@tool` typé · mémoire = markdown d'abord · humain dans la boucle · secrets jamais committés · i18n FR/EN · desktop Tauri offline-first · réutilisation de la sécurité existante.
|
||
- **V2.1 (ajout majeur)** : insère **dès la phase 0** deux mécanismes qui rendent tout le reste délégable :
|
||
- **Moteur de politiques** (#213) — décision **déterministe** `autorisé | approbation_run | approbation_renforcée | refusé` = f(risque × niveau d'autonomie × provenance × sensibilité × réversibilité). **Jamais de LLM dans le chemin d'autorisation.**
|
||
- **Exécution fiable** (#206) — *« un run est l'unité de tout »* : plans avant écriture, approbation par run, `agent_runs`/`agent_steps`, post-conditions (`verify`), inverses (`inverse`), idempotence, reprise après crash, annulation (undo).
|
||
|
||
Le delta V2 → V2.1 est significatif et pertinent : la V2 donnait de la mémoire et des connecteurs **sans** le socle de sécurité/exécution. La V2.1 corrige cela en prerequisite. Mais la V2.1 introduit aussi ~2× plus de périmètre.
|
||
|
||
### Phasage et effort (source : docs)
|
||
|
||
| Phase | Thème | Tranches | Effort |
|
||
|---|---|---|---|
|
||
| **0** | Socle sûr (purge Ollama, mémoire, miroir, politiques, runs) | #191,#192,#193,#213,#206, amorce #212 | 15–19 j |
|
||
| **1** | Le travail (tâches, Aujourd'hui, planification, capture) | #202,#203,#204,#205 | 14–18 j |
|
||
| **2** | Le temps réel (agent programmé, consolidation, rappels, automations, rituels) | #200,#194,#199,#208,#214 | 14–19 j |
|
||
| **3** | Le monde (connecteurs, sync, client MCP) | #195,#196,#197,#198,#207 | 17–23 j |
|
||
| **4** | Les gens (personnes & engagements, voix, insights) | #211,#209,#201 | 9–13 j |
|
||
| **5** | L'extension (packs A–G + éval continue) | #210,#212 | 3–5 j/chantier + continu |
|
||
|
||
**Total cœur = ≈ 69–92 jours** de développement, plus l'extension. C'est un **programme de plusieurs mois**, pas une feature.
|
||
|
||
---
|
||
|
||
## 3. Les composantes à mettre en place
|
||
|
||
### 3.1 Backend — nouveaux modules
|
||
|
||
```mermaid
|
||
graph TD
|
||
L[agent/loop.py existant] --> P[agent/policies.py]
|
||
L --> R[agent/runs.py]
|
||
P --> REG[tools/registry.py étendu verify/inverse]
|
||
M[memory/ store, entities, recall, compiler, mirror, consolidator] --> T1[tools/memory.py]
|
||
C[connectors/ base, oauth, registry, sync, ical/caldav/imap, mcp_client] --> T2[tools/connectors.py]
|
||
A[automations/ bus, engine, detectors] --> T3[tools/reminders.py]
|
||
K[tasks/ model, store, rrule, planner] --> T4[tools/tasks.py + planner.py]
|
||
I[inbox/store.py] --> T5[tools/inbox.py]
|
||
G[people/ + voice/] --> T6[tools/people.py, commitment, voice]
|
||
```
|
||
|
||
| Module | Rôle |
|
||
|---|---|
|
||
| `backend/memory/{store,entities,recall,compiler,mirror,consolidator}.py` | faits bi-temporels, entités/relations, recall RRF, compileur de contexte, miroir markdown, consolidation nocturne |
|
||
| `backend/agent/policies.py` | moteur de politiques déterministe |
|
||
| `backend/agent/runs.py` | `agent_runs`/`agent_steps`, plans, idempotence, reprise, undo |
|
||
| `backend/connectors/{base,oauth,registry,sync,ical,caldav,imap,mcp_client}.py` | cadre connecteurs OAuth2+PKCE + replis zéro-OAuth + sync incrémentale + client MCP |
|
||
| `backend/tasks/{model,store,rrule,planner}.py` | parseur de tâches markdown, index, RRULE, moteur de planification |
|
||
| `backend/inbox/store.py`, `backend/automations/{bus,engine,detectors}.py` | capture, bus d'événements, automatisations, détecteurs d'insights |
|
||
| `backend/tools/{memory,connectors,reminders,tasks,planner,inbox,people,voice}.py` | outils `@tool` |
|
||
| `backend/routers/{memory,runs,delegations,today,tasks,plans,approvals,inbox,connectors,automations,reminders,commitments}.py` | API REST |
|
||
|
||
### 3.2 Stores de données (tous dans `data/`, JSON ou SQLite reconstructible)
|
||
|
||
- `data/memory.sqlite3` — `facts` (bi-temporel : `entity_id, valid_from, valid_to, recorded_at, sensitivity, provenance_trust`, `kind` étendu à `procedure`), `entities`, `relations`, `consolidation_runs`.
|
||
- `data/assistant.sqlite3` — `agent_runs`, `agent_steps`, `delegations`, `approvals`, `inbox_items`, `commitments`, `plans`, `automation_runs`, `event_log`.
|
||
- `data/tasks.sqlite3` — index des tâches (reconstructible).
|
||
- `data/connectors_cache.sqlite3` — `sync_state`, `synced_objects` (extraits bornés, jamais le corps complet).
|
||
- `data/connectors.json` (public) + `data/connector_secrets.json` (0600, chiffré `secret.key`).
|
||
|
||
### 3.3 Artefacts vault — `99_Assistant/`
|
||
|
||
`Profil.md` (balises `<!-- obsigate:managed:* -->`, re-parsées en faits `source='user'`), `Insights.md`, `Rappels.md`, `Personnes.md`, `Journal.md`, `Briefings/YYYY-MM-DD.md`, `Plans/YYYY-MM-DD.md`, `Automatisations/*.md`, `Revues/`.
|
||
|
||
### 3.4 Frontend (vanilla JS, zéro build — contrainte à respecter)
|
||
|
||
Vue **Aujourd'hui**, **file d'approbations unifiée**, **centre de contrôle** (runs, délégations, budgets, santé des index), page Configurations étendue **« Sources connectées »**, cartes mémoire/pending, panneau cloche rappels, vue Automatisations + dry-run, registre des packs. i18n FR **et** EN obligatoire.
|
||
|
||
### 3.5 Infra & config
|
||
|
||
- Retrait Ollama : `docker-compose.yml` + `.test-linux` + `.test-win` (service, volume `ollama_data`, `OLLAMA_BASE_URL/MODEL`, port 11434).
|
||
- Variables : `OBSIGATE_MEMORY_*`, `OBSIGATE_CONSOLIDATION_*`, `OBSIGATE_TZ`, `OBSIGATE_BRIEFING_TIME`, `OBSIGATE_NOTIFY_DAILY_BUDGET`, `GOOGLE_CLIENT_ID/SECRET`, `AZURE_CLIENT_ID/SECRET`, `OBSIGATE_NOTION_API_KEY`, `OBSIGATE_DISCORD_BOT_TOKEN`, `OBSIGATE_RUN_MAX_*`.
|
||
- Pas de nouvelle dépendance lourde nécessaire : `httpx` et `mcp` sont déjà présents.
|
||
|
||
---
|
||
|
||
## 4. État réel du code (vérifié, pas déduit)
|
||
|
||
| Élément cité par les specs | Réalité constatée |
|
||
|---|---|
|
||
| `backend/agent/loop.py` (`run_agent`) | ✅ existe (`DEFAULT_MAX_ITERATIONS=10`, `STOP_*`, propose/apply) |
|
||
| `backend/tools/registry.py` (`@tool`, `ToolRisk`) | ✅ existe — mais **pas de `verify`/`inverse`/`data_classes`** (donc P0-T12 est bien un vrai travail) |
|
||
| `backend/scheduler.py` (actions, schedules) | ✅ existe — actions `create_file`/`append_to_file`/`notify`, schedules `interval_hours`/`daily_time`/`once_at` |
|
||
| `backend/notify.py` (`broadcast`) | ✅ existe |
|
||
| `backend/mcp/server.py` (propose/apply) | ✅ existe |
|
||
| `data/secret.key`, chiffrement, `0600` | ✅ pattern présent (`auth/jwt_handler.py`) |
|
||
| **`backend/memory/`, `backend/connectors/`, `policies.py`, `runs.py`** | ❌ **inexistants** |
|
||
| **`memory.sqlite3`, `assistant.sqlite3`, `agent_runs`** | ❌ **inexistants** |
|
||
| Ollama dans les compose | ✅ **toujours présent** (les 3 files) |
|
||
|
||
Conclusion : les specs décrivent correctement le socle existant (bon signe), et tout ce qui est « nouveau » est effectivement à construire. Le statut « non implémenté » du doc V2 est exact.
|
||
|
||
---
|
||
|
||
## 5. Points forts de la conception
|
||
|
||
- **Réutilisation maximale de l'existant** : boucle agent, registre `@tool`, MCP, scheduler, notify, Web Push, recherche TF-IDF+sémantique — rien de tout cela n'est refait. La V2.1 branche proprement les nouvelles capacités.
|
||
- **Anti-boîte-noire** : mémoire auditable en markdown, éditions humaines re-parsées comme faits `source='user'` confiance 1.0. C'est la vraie différenciation face à ChatGPT-Memory.
|
||
- **Sécurité pensée tôt** : moteur de politiques déterministe, provenance/taint, whitelist des runs non interactifs, refus des envois externes sans relecture, traitement du contenu externe comme *données* (anti-injection), budgets durs.
|
||
- **Coût maîtrisé** : consolidation déterministe avant LLM, cheap model dédié, budgets tokens, règle « lire le cache pendant que sa sync dort ».
|
||
- **Dégradabilité** : chaque phase fonctionne sans les suivantes (la V2.1 insiste : phase 4 complète sans même un connecteur), connecteurs absents du registre si non installés (offline-first Tauri).
|
||
- **DoD aligné sur le dépôt** : golden tasks, i18n FR/EN, fiches features, CHANGELOG/ROADMAP, ruff/mypy.
|
||
|
||
---
|
||
|
||
## 6. Pistes d'amélioration
|
||
|
||
### 🔴 Bloquantes (à traiter avant d'écrire une ligne de code)
|
||
|
||
1. **Réécrire/écrire le document parent `ASSISTANT-V2.1.md`.** Sans lui, les schémas `tasks`/`inbox_items`/`facts`/`entities`/`agent_runs`, les règles de politique §15.2 et **les définitions des golden tasks G1→G14** n'existent pas. Options : (a) reconstituer le parent à partir des 5 phases + de la V2, ou (b) fusionner les phases en un document unique auto-suffisant. **Recommandé : (b)**, car maintenir 6 documents cohérents pour ~90 jours de travail va dériver.
|
||
2. **Renuméroter tout le bloc d'IDs.** #191, #192, #194 sont déjà pris (chat, user-home). Proposer un bloc contigu réservé (ex. `#215→#238`) et le figer, puis remapper V2 et V2.1. Décider aussi de la convention unique : les docs mélangent `#NNN` (roadmap) et `P0-Tnn`/`P2-Tnn` (tickets) sans mapping explicite — à trancher et documenter.
|
||
3. **Enregistrer le programme dans le Roadmap et la cartographie documentaire.** Créer les entrées `ROADMAP.md` (statut 🔵/⚪) et les fiches `docs/features/`, ajouter `docs/Assistant-V2/` à la table d'`AGENTS.md`. Aujourd'hui le programme viole la règle « ID stable avant de coder ».
|
||
4. **Décider du sort de la doc V2.** La V2 **contredit** la V2.1 : V2 dit « `gmail.send` non exposé v1 », V2.1 phase 3 l'expose en DANGEROUS. V2 propose une table `facts` sans bi-temporalité/entités que V2.1 remplace. Garder les deux crée un piège pour l'implémenteur. **Recommandé : marquer `ASSISTANT-V2.md` comme « superseded »** et pointer vers la V2.1.
|
||
|
||
### 🟡 Importantes (qualité d'implémentation)
|
||
|
||
5. **Trancher le séquençage par valeur, pas par phases.** Les phases sont bien dessinées, mais ~90 j avant le premier bénéfice visible est risqué. **Recommandé : livrer d'abord un « vertical slice » de la seule phase 0** (purge Ollama + mémoire + miroir + runs + politiques) — c'est là que vivent 80 % du risque technique et 100 % des prérequis de sécurité. Ne pas commencer les phases 1–5 avant d'avoir prouvé la phase 0.
|
||
6. **Concurrence SQLite / writer unique.** Les specs ajoutent 4–5 bases manipulées par la boucle agent, le watcher, le scheduler (tick 60 s) et les handlers HTTP, dans **un seul process**. À cadrer explicitement : mode WAL, discipline « un seul écrivain par store », verrous, et reprise. Ce n'est évoqué nulle part et c'est une source classique de corruption.
|
||
7. **Qualité de l'extraction de faits = le composant le plus risqué.** C'est le seul endroit où « le modèle décide ». Recommander : (a) un **dry-run de consolidation** obligatoire avant activation (existe pour automations, à généraliser), (b) validation Pydantic stricte + rejet des valeurs non sourcées, (c) métrique « faits rejetés/acceptés » dès la phase 0, (d) un mode « extracteur désactivé » par défaut la première semaine.
|
||
8. **Fuites multi-utilisateurs via le miroir.** La mémoire est `user_id` par utilisateur, mais le miroir vit dans **un vault** `99_Assistant/`. Si le vault est partagé, `Profil.md`/`Personnes.md` exposent la vie privée d'un user à un autre. À trancher : vault mémoire **par utilisateur** (le plus sûr, cohérent avec `home-<user>`), ou sections par user + ACL. À documenter et tester.
|
||
9. **Chiffrement au repos et `0600` sous Windows.** Le pattern `data/connector_secrets.json` en `0600` est POSIX. `os.chmod` ne pose pas d'ACL sous Windows, alors que le desktop Tauri est multi-OS. Prévoir une stratégie (ACL via `pywin32`, ou DPAPI, ou au minimum documenter la limite). #172 est cité comme dépendance mais pas défini ici.
|
||
10. **Golden tasks non branchées au CI.** `AGENTS.md` impose les 5 jobs CI (`lint/test/security/build/e2e`). Les golden tasks (`tests/golden/`) nécessitent un job dédié + des **simulateurs HTTP par fournisseur** (prévus en phase 3). À cadrer dès la phase 0 (harnais) pour ne pas découvrir le problème en phase 3. La phase 5 **oublie complètement l'E2E** alors qu'elle crée une UI (registre des packs) — non conforme à la DoD du dépôt.
|
||
11. **Friction OAuth.** Créer des apps Google Cloud / Entra ID est le principal frein d'installation. Bonne idée des specs : les **replis zéro-OAuth (iCal/CalDAV/IMAP)**. Recommander d'en faire le **chemin par défaut** et OAuth une option avancée, plutôt que l'inverse — cela dérisque toute la phase 3.
|
||
|
||
### 🟢 Confort / simplifications
|
||
|
||
12. **Mutualiser les stores.** `tasks.sqlite3`, `connectors_cache.sqlite3`, `memory.sqlite3` et `assistant.sqlite3` pourraient être **un seul** `assistant.sqlite3` (WAL) : moins de fichiers, moins de cycles de vie, un seul point de backup. Le « reconstructible séparément » se gère par table. À évaluer.
|
||
13. **FTS5 natif** pour l'index des tâches et la recherche mémoire, plutôt qu'un index plein-texte maison — SQLite le fournit déjà.
|
||
14. **Unifier rappel = tâche enrichie** (déjà proposé en V2.1 §7.2) : excellent, à confirmer comme décision figée pour éviter toute tentation de second store.
|
||
15. **Instrumenter les métriques #212 dès la phase 0** (budget de contexte mémoire, faits acceptés/rejetés, temps de décision quotidien). Les specs le promettent ; en faire un vrai tableau de bord tôt évite les optimisations à l'aveugle.
|
||
16. **Formaliser les critères de sortie de chaque phase** (les phases 0–4 en ont, la 5 non) et une **décision unique** sur les « décisions ouvertes » du parent (activation de l'envoi, fournisseur de transcription, gestionnaire de tâches externe) — ces 3 décisions conditionnent plusieurs tickets et ne sont pas tranchées.
|
||
17. **Points ambigus relevés par phase** (à lever dans le parent) : schéma `consolidation_runs` jamais défini (phase 2) ; format de `allowed_extra_tools` et de `ctx: rappel` ; emplacement du réglage `candidats connecteurs` (`off|candidats`) ; modalités MCP (stdio vs HTTP) et algorithme de plafonnement de risque ; dédup multi-calendriers (tolérance fuseaux/récurrences) ; granularité Notion→index ; format de persistance des packs (`data/` ?).
|
||
|
||
---
|
||
|
||
## 7. Recommandation de prochaines étapes
|
||
|
||
1. **Décider du plan de renumérotation** et réserver un bloc d'IDs contigu.
|
||
2. **Consolider la doc** : écrire le parent V2.1 (ou fusionner), marquer la V2 comme superseded, lever les ~15 ambiguïtés ci‑dessus.
|
||
3. **Enregistrer** le programme dans `ROADMAP.md` + `docs/features/` + `AGENTS.md`.
|
||
4. **Commencer par le vertical slice de la phase 0** (purge Ollama + mémoire + miroir + runs + politiques + harnais golden), et **ne pas** démarrer les phases 1–5 avant que la phase 0 soit verte en CI.
|
||
|
||
---
|
||
|
||
Souhaites-tu que je rédige :
|
||
- le **document de synthèse consolidé** (parent V2.1 auto-suffisant) à partir des 5 phases et de la V2, ou
|
||
- une **proposition de renumérotation** concrète (mapping `ancien ID → nouveau ID`) prête à coller dans le Roadmap ?
|
||
|
||
Je peux aussi produire un `docs/features/assistant-v2-index.md` qui sert de plan-maître et référence les 7 documents actuellement orphelins.
|