Files
ObsiGate/docs/ROADMAP.md
T
Spark fddbaec82e
CI / lint (push) Failing after 1s
CI / security (push) Failing after 0s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
feat: panneau Spark — version du service d'agents visible en mode sidebar #225
2026-10-26 16:56:28 +00:00

99 KiB
Raw Permalink Blame History

ObsiGate — Roadmap

Version : 2.79.0 | Dernière mise à jour : 2026-10-26 Ce fichier ne contient que le travail à venir (🔵 En cours + ⚪ Backlog) et un index compact vers les fonctionnalités livrées.


Légende

Icône Signification
✅ Terminé
🔵 En cours
⚪ Prévu / Backlog
🔴 Impact Critique / Bloquant
🟡 Impact Utile / Attendu
🟢 Impact Nice-to-have / Confort

Convention : chaque item porte un ID stable #NN (clé de jointure entre roadmap, changelog et commits). Une fonctionnalité livrée sort de ce fichier et entre dans l'index « Complété » ci-dessous, avec son détail dans docs/features/ ou l'archive.


🔵 En cours

225. Fusion — panneau Spark : version du service d'agents visible en mode sidebar

  • Effort : ~0,1 jour | Impact : 🟢 | Ouvert : 2026-10-26 | Statut : ✅ livré le 2026-10-26 (version du hook — voir CHANGELOG ; redéploiement Docker requis)
  • Fiche : features/fusion-panneau-version-agent-225.md
  • Description : demande de Bruno (2026-10-26, carte fusion #64) : la version « Service d'agents vX », déjà visible dans la console pleine page, doit se lire aussi dans le panneau natif des apps (mode sidebar). Le pied du panneau Spark affiche désormais cette ligne, discrète et permanente, lue en direct dans la santé du service (GET /healthz de l'origine injectée par l'hôte) à l'ouverture du panneau, avec cache de session — jamais une valeur codée en dur ; service injoignable = rien d'affiché. Même livraison : TikTak 0.61.3, Flowdeck 7.83.1, Kanbante 0.37.1.
  • Sous-tâches :
    • Ligne de version dans le pied du panneau (canonique TikTak, propagée aux 4 apps)
    • Test tests/test_draco_barre.py::test_panneau_version_service_affichee_225 + épreuve comportementale jsdom sur les 4 copies
    • Release publiée — CI verte à constater, redéploiement Docker (geste de Bruno)

224. Sécurité des dépendances — pip-audit vierge (brotli, filelock, opentelemetry-api, pypdf)

  • Effort : ~0,1 jour | Impact : 🔴 | Ouvert : 2026-10-25 | Statut : ✅ livré le 2026-10-25 (version du hook — voir CHANGELOG ; redéploiement Docker requis)
  • Fiche : features/securite-dependances-pip-audit-224.md
  • Description : le job security du run CI 2303 (2.78.0) échoue sur pip-audit : 17 vulnérabilités dans 4 paquets hérités de l'environnement du runner (toolcache « already satisfied », même piège que BUG-093). Planchers explicites dans backend/requirements.txt : pypdf relevé à >=6.21.2, nouveaux planchers brotli>=1.2.1, filelock>=4.2.1, opentelemetry-api>=1.45.1 ; garde-fou TestDependencySecurityFloors étendu. Aucun code applicatif, aucun nouvel ignore pip-audit.
  • Sous-tâches :
    • Planchers de sécurité dans backend/requirements.txt + commentaires
    • Garde-fou tests/test_ci_workflow.py::TestDependencySecurityFloors étendu (pypdf 6.21.2, brotli, filelock, opentelemetry-api)
    • pip-audit local : 0 vulnérabilité non ignorée (mêmes ignores que la CI)
    • Release publiée — CI verte à constater, redéploiement Docker (geste de Bruno)

223. Dev/prod sans noms publics en dur — URLs de l'écosystème par configuration

  • Effort : ~0,5 jour | Impact : 🟡 | Ouvert : 2026-10-25 | Statut : ✅ livré le 2026-10-25 (version du hook — voir CHANGELOG ; redéploiement Docker requis, et en dev déclarer les noms en -dev dans le .env du poste)
  • Fiche : features/devprod-urls-config-223.md
  • Description : aucun nom public de l'écosystème dracodev ne doit être figé dans le code vivant : les URL publiques (service d'agents, autres apps) viennent de la configuration (défauts = noms officiels sans suffixe ; l'environnement dev déclare ses noms en -dev dans son .env). CSP dérivée de l'origine de l'agent configurée, panneau Spark et liens inter-apps alimentés par l'hôte (injection window.DRACO_URLS au service de index.html), références croisées reconstruites depuis la config à l'affichage (aucune donnée migrée).
  • Sous-tâches :
    • Module backend/draco_config.py + .env.example
    • CSP connect-src/frame-src dérivée de la config (tests via config)
    • external_refs : hôtes reconnus + URL d'affichage construites par config
    • Frontend : panneau Spark, liens TikTak, onglets des apps via DRACO_URLS
    • WebAuthn : confirmation rp_id/origines dérivés de la requête / OBSIGATE_WEBAUTHN_*

222. Fusion — panneau Spark V3 : la console en surimpression pleine page

  • Effort : ~0,1 jour | Impact : 🟢 | Ouvert : 2026-10-23 | Statut : ✅ livré le 2026-10-23 (2.77.0, redéploiement Docker en attente)
  • Fiche : features/fusion-panneau-console-surimpression-222.md
  • Description : le panneau Spark (asset vendangé frontend/draco-panneau.js, octet-identique dans les 4 apps) passe en V3 (demande de Bruno, 2026-10-22) : le bouton « Console ⤢ » n'ouvre plus la console du service d'agents en nouvel onglet (#221) mais en surimpression pleine page dans la même page — montée à la largeur du panneau, étendue à toute la fenêtre par transition, iframe gardant le lien profond (?disc= / ?app=), et deux sorties dans sa barre : « Mode sidebar » (rétraction vers le panneau) et « Fermer l'agent ». Styles injectés par le panneau ; côté service, la console autorise l'encadrement par les 4 apps (0.20.0). Même livraison : TikTak 0.60.0, Flowdeck 7.81.0, Kanbante 0.29.0.
  • Sous-tâches :
    • Surimpression + barre « Mode sidebar » / « Fermer l'agent » dans le panneau canonique (TikTak), recopié octet-identique dans les 4 apps
    • Test tests/test_draco_barre.py::test_panneau_console_surimpression_222 (et révision du test #221 : le nouvel onglet disparaît)
    • Release v2.77.0 publiée — CI à constater, redéploiement Docker (geste de Bruno)

221. Fusion — panneau Spark : bouton « Console ↗ » vers la console du service

  • Effort : ~0,1 jour | Impact : 🟢 | Ouvert : 2026-10-22 | Statut : ✅ livré le 2026-10-22 (2.76.1, redéploiement Docker en attente)
  • Fiche : features/fusion-panneau-console-221.md
  • Description : le panneau Spark (asset vendangé frontend/draco-panneau.js, octet-identique dans les 4 apps) gagne un bouton « Console ↗ » dans sa barre des discussions (demande de Bruno, 2026-10-22) : il ouvre la console web du service d'agents (https://agent.dracodev.net/) dans un nouvel onglet, sur la discussion actuellement affichée (?disc=<id>, URL construite au clic) et avec l'app d'origine (?app=obsigate, déduite du sous-domaine og). La console consomme déjà ces deux paramètres (lien profond de discussion + puce « Ouvert depuis »). Même livraison : TikTak 0.59.1, Flowdeck 7.80.1, Kanbante 0.28.1.
  • Sous-tâches :
    • Bouton + ouvrirConsole() / appHote() dans le panneau canonique (TikTak), recopié octet-identique dans les 4 apps
    • Test tests/test_draco_barre.py::test_panneau_bouton_console_221
    • Release v2.76.1 publiée — CI à constater, redéploiement Docker (geste de Bruno)

220. Fusion — émission d'événements vers le journal du service d'agents (Lot 2, vague 5)

  • Effort : ~0,5 jour | Impact : 🟢 | Ouvert : 2026-10-22 | Statut : ✅ livré le 2026-10-22 (2.76.0, redéploiement Docker en attente)
  • Fiche : features/fusion-journal-evenements-220.md
  • Description : ObsiGate émet ses mutations de notes explicites vers le journal d'activité du service d'agents (contrat ACC-0.2, carte fusion-trois-apps #18) : obsigate.note.created / edited / moved / deleted, signées HMAC, en arrière-plan, inactives sans la clé AGENT_EVENEMENTS_CLE. Points d'accroche : les endpoints d'écriture de l'API web (acteur user) et la couche outils / serveur MCP (acteur agent:mcp). Garde-fou : jamais le watcher — seules les opérations explicites via l'API émettent.
  • Sous-tâches :
    • Module backend/agent_journal.py (enveloppe ACC-0.2, signature HMAC-SHA256, envoi « au mieux »)
    • Branchements backend/routers/files_write.py (créer, sauvegarder, renommer, déplacer, supprimer)
    • Branchements backend/tools/service.py (create/edit/ append/rename/move/delete, acteur selon le mode)
    • Tests tests/test_agent_journal.py — dont la preuve du garde-fou watcher (écriture disque + indexation = silence)

218. Fusion — panneau Spark intégré (agent commun)

  • Effort : ~0,5 jour | Impact : 🟢 | Ouvert : 2026-10-21 | Statut : ✅ livré le 2026-10-21 (2.74.0, redéploiement Docker en attente)
  • Fiche : features/fusion-panneau-spark-218.md
  • Description : le bouton Spark de la barre commune (#215) ouvre le panneau de l'agent commun (service d'agents dracodev : conversation, Aujourd'hui, approbations, missions longues), comme dans TikTak, Flowdeck et Kanbante. Assets partagés vendangés à l'identique ; la CSP nomme le service en connect-src.
  • Sous-tâches :
    • Assets frontend/draco-panneau.js / frontend/draco-panneau.css vendangés depuis le panneau partagé du programme
    • frontend/index.html : link CSS + script, action spark → DRACO_PANNEAU.toggle() (repli honnête si le panneau ne charge pas)
    • CSP connect-src : https://agent.dracodev.net ajouté (backend/main.py, seul hôte ajouté)
    • Tests test_draco_barre.py (intégration + CSP verrouillées)

219. Fusion — panneau Spark v2 (Lot 1)

  • Effort : ~0,5 jour | Impact : 🟢 | Ouvert : 2026-10-22 | Statut : ✅ livré le 2026-10-22 (2.75.0, redéploiement Docker en attente)
  • Fiche : features/fusion-panneau-spark-v2-219.md
  • Description : le panneau Spark (#218) passe en v2, à l'identique dans les quatre applications (carte fusion-trois-apps #17) : réponses de l'agent en Markdown rendu (HTML produit par le service d'agents 0.10.0, sanitizé côté serveur), largeur réglable persistée, thème clair/sombre aligné sur l'application hôte, discussions façon Muse (principale perpétuelle + parallèles créées/archivées/supprimées). Côté ObsiGate : assets vendangés uniquement, aucun code propre touché.
  • Sous-tâches :
    • Assets frontend/draco-panneau.js / frontend/draco-panneau.css remplacés par la v2 partagée du programme
    • Fiche de conception features/fusion-panneau-spark-v2-219.md

215. Fusion bloc 1 — barre d'apps commune et références croisées des notes

  • Effort : ~1 jour | Impact : 🟢 | Ouvert : 2026-10-20 | Statut : ✅ livré le 2026-10-20 (2.70.0)
  • Fiche : features/fusion-bloc1-barre-refs-215.md
  • Description : première tranche du programme Fusion (accès centralisé ObsiGate / Flowdeck / TikTak / Kanbante — dépôt programme Projets/fusion-trois-apps, épopée ACC-1 ; contrats versionnés dans Projets/dracodev-commons v0.1.0). ID 215 choisi hors des plages déjà utilisées ou proposées (#191–#201 livrées/Assistant V2, #202–#214 proposées par ASSISTANT-V2.1). Issues Gitea ObsiGate #5 (ACC-1.1), #6 (ACC-1.2), #7 (ACC-1.3).
  • Sous-tâches :
    • Barre d'apps commune vendangée du snippet figé de commons (frontend/draco-barre.css/.js, markup dans index.html) : ObsiGate marquée active, navigation vers les 4 apps, domaine mémorisé
    • Backend external_ref : stockage JSON par utilisateur (backend/external_refs.py), endpoints GET/POST /api/refs et DELETE /api/refs/{id} (schémas + tag OpenAPI), parseur d'URL profondes conforme au contrat figé
    • Section « Liens » dans la vue d'une note (module frontend/js/draco-liens.js, point d'extension obsigate:file-rendered émis par renderFile)
    • Notes projetées TikTak reconnues (frontmatter tiktak_id) : bandeau « Tâche TikTak projetée » + « Ouvrir dans TikTak »
    • i18n FR/EN (clés draco.links.*), tests test_external_refs.py

216. Fusion ACC-3.1 — émettrice SSO draco_session

  • Effort : ~1 jour | Impact : 🟢 | Ouvert : 2026-10-21 | Statut : ✅ livré le 2026-10-21 (2.71.0)
  • Fiche : features/fusion-acc31-sso-draco-session-216.md
  • Description : couche 2 (identité) du programme Fusion — décision C2 de Bruno : cookie de session partagé sous .dracodev.net (architecture v2.0 §5.2, option 2a). ObsiGate est l'unique émettrice ; les autres apps valideront localement (ACC-3.2). Issue Gitea ObsiGate #8 ; épopée Projets/fusion-trois-apps#7.
  • Sous-tâches :
    • Module backend/draco_session.py : JWS HS256, claims minimaux (sub, name, iat, exp 12 h, jti — aucun rôle), rotation par DRACO_SESSION_SECRET_PREV, inerte sans DRACO_SESSION_SECRET
    • Émission du cookie à chaque _issue_tokens (mot de passe ou MFA)
    • Renouvellement glissant (middleware ASGI DracoRenewalMiddleware, fenêtre 2 h, conditionné au cookie d'accès natif valide)
    • Déconnexion globale : révocation du jti (data/draco_revoked.json) + effacement du cookie ; GET /api/sso/revocations sous clé machine
    • GET /sso/authorize : return_to en liste blanche *.dracodev.net (anti open-redirect), retour post-connexion re-validé côté frontend (auth.js)
    • Tag OpenAPI « SSO », tests test_draco_session.py (22)

217. Fusion ACC-3.2 — validation locale du jeton draco_session

  • Effort : ~0,5 jour | Impact : 🟢 | Ouvert : 2026-10-21 | Statut : ✅ livré le 2026-10-21 (2.72.0)
  • Fiche : features/fusion-acc32-validation-locale-217.md
  • Description : pendant consommateur de #216 — get_current_user accepte le cookie partagé à défaut de jeton natif valide ; le sub étant l'identifiant ObsiGate, la correspondance vers le compte local est directe (compte actif exigé, garde-fou BUG-028 appliqué). Issue Gitea ObsiGate #9 ; épopée Projets/fusion-trois-apps#7.
  • Sous-tâches :
    • draco_session.user_for_draco() : résolution par id, _draco_sub
    • Repli _draco_fallback() sur toutes les sorties « non authentifié » du chemin natif (backend/auth/middleware.py)
    • Tests test_draco_session.py (+4 : cookie seul, révoqué, sub inconnu, inerte sans secret)

196. Partage dirigé entre utilisateurs (document → utilisateur)

  • Effort : 0,5-1 jour | Impact : 🟡 | Ouvert : 2026-10-10 | Statut : ✅ livré le 2026-10-10
  • Fiche : features/directed-shares-196.md
  • Description : un utilisateur peut partager un document à un ou plusieurs autres comptes (pas un lien public) : les pages /s/{token} exigent alors une session et n'acceptent que créateur + admin + destinataires (404 sinon, pas de fuite d'existence). Vue « partagé avec moi » dans le dashboard, destinataires listés dans le dialogue de partage, révocabilité réservée au créateur/admin, GET /api/shares scopé (un non-admin ne voit que ses partages créés/reçus — corrige une fuite préexistante). Rétrocompatible : les partages publics existants restent anonymes.
  • Sous-tâches :
    • Store shared_with + validation des destinataires à la création
    • Gate auth+appartenance sur /s/{token} (+/pdf, /raw) — 404 opaque
    • Scope de GET /api/shares ; révocation créateur/admin uniquement
    • UI : dialogue dirigé/public + destinataires, dashboard « partagé par X »
    • i18n FR/EN, tests test_directed_shares.py (9), fiche feature
    • Itération 2 (2026-10-11) : icône « partagé » (share-2 bleu) sur les fichiers porteurs d'un partage actif dans l'arborescence ; dossier virtuel Partage à la racine du home du destinataire (fichiers reçus, ouverture lecture seule /s/{token}) ; les documents reçus sont cherchables (merge dans search_vaults, résultats home-<user>/Partage/… avec share_token, clic → page de partage — jamais l'éditeur du vault d'autrui) ; cache front invalidé à la création/révocation. +2 tests (recherche trouvée par le destinataire, aucune fuite vers un non-destinataire).
    • Itération 3 (2026-10-11) : le dossier Partage ne déclenche plus la navigation (dossier virtuel — corrige « Directory not found: Partage ») ; un fichier reçu s'ouvre dans l'application en onglet (arbre, recherche, dashboard) via la résolution serveur home-<user>/Partage/<fichier> → fichier source dans /api/file (+ raw, download) ; validation path non-nulle à la création d'un partage. +2 tests.
    • Itération 4 (2026-10-11) : le partage dirigé EST l'autorisation — la résolution Partage/… court-circuite l'ACL du vault source (fix « Accès refusé à la vault … » : le destinataire n'a par définition pas accès au vault de l'émetteur) ; chemin virtuel canonique Partage/<token>/<nom> (lève l'ambiguïté de fichiers homonymes, fallback par nom conservé) ; « reçu » = adressé à moi (un admin ne voit plus les partages d'autres comptes comme reçus — fix 404 « File not found: Partage/… »). +3 tests.

194. Dossier personnel par utilisateur (<racine>/Home/<user>)

  • Effort : 1-2 jours | Impact : 🟡 | Ouvert : 2026-10-09 | Statut : 🔵 en cours
  • Cadrage : chaque utilisateur créé reçoit un dossier personnel monté en vault propre (home-<user>), isolé par l'ACL par vault existante — pas d'ACL par chemin à inventer.
  • Décisions validées : option A (un vault par utilisateur), nom home-<user>, dossier conservé à la suppression du compte, racine /NFS/OBSIDIAN_DOC/Home (montée /vaults/Home, exposée par OBSIGATE_HOME_ROOT).
  • Sous-tâches :
    • ID stable créé (avant codage, AGENTS.md)
    • Registre persistant des vaults dynamiques data/vaults.json (les vaults ajoutés à la volée sont aujourd'hui perdus au redémarrage / reindex — load_vault_config ne lit que les env VAULT_N_*)
    • Service ensure_user_home() idempotent : mkdir + vault + octroi, appelé à la création d'un user et au démarrage (réparation/migration)
    • Retrait au suppression de compte (index/watcher/registre) sans supprimer le dossier
    • Montage Docker + OBSIGATE_HOME_ROOT (prod et compose de test docker-compose.test-win.yml → test_home:/vaults/Home)
    • UI : vaults home-* en premier dans l'arborescence + icône maison lucide (getVaultIcon), vérifié live sur l'instance 2020
    • Isolation : « * » (admin) ne couvre plus les dossiers persos — check_vault_access + filtres des routes + /api/search (avant pagination) ; octroi du home aussi aux comptes « * »
    • Tests (création, persistance après rebuild, isolation 403 entre users) + docs

197. Listes de fichiers : mtime + size pour réconciliation externe (TikTak, Gitea #4)

  • Effort : 0,5 jour | Impact : 🟡 | Ouvert : 2026-10-14 | Statut : ✅ livré le 2026-10-14
  • Fiche : features/tiktak-integration-197-200.md
  • Description : un client de synchro doit détecter les fichiers modifiés en un seul appel de liste, sans relire chaque fichier. GET /api/vault/{vault}/paths n'exposait que vault/path/name/type.
  • Sous-tâches :
    • /paths : size/mtime/mtime_iso par fichier (index, même contrat que list_all_files) ; None sur les répertoires
    • /browse : modified/modified_iso ; outil MCP list_directory : size/mtime
    • Cohérence read-after-write : PUT …/save rafraîchit l'index en synchrone
    • Bug latent corrigé : update_single_file/remove_single_file exigeaient un absolu mais recevaient un relatif (no-op silencieux) — acceptent les deux
    • Tests tests/test_sync_lists.py (7 : métadonnées + scénario de réconciliation)

198. Webhooks : vault dans la charge + filtre vault / path_prefix (TikTak, Gitea #3)

  • Effort : 0,5-1 jour | Impact : 🟡 | Ouvert : 2026-10-14 | Statut : ✅ livré le 2026-10-14
  • Fiche : features/tiktak-integration-197-200.md
  • Description : un consommateur externe (retours de synchro TikTak, phase 3) recevait tout, de tous les vaults, sans pouvoir filtrer.
  • Sous-tâches :
    • Filtres optionnels vault (exact) + path_prefix (sous-arbre, old/new_path inclus) ; sans filtre = tout, comme avant ; webhook_matches() pur et testé
    • POST/PATCH/GET /api/webhooks : filtres acceptés, modifiables ("" = reset), exposés
    • PUT …/save émet enfin file_modified (souscrit mais jamais dispatché)
    • UI : champs filtre + badge, aide intégrée FR/EN mise à jour
    • Tests tests/test_webhook_filters.py (10 : matching, persistance, dispatch simulé)

199. Clés API à portée limitée — vault unique + fichiers seuls (TikTak, Gitea #2)

  • Effort : 1-2 jours | Impact : 🟡 | Ouvert : 2026-10-14 | Statut : ✅ livré le 2026-10-14
  • Fiche : features/tiktak-integration-197-200.md
  • Description : la clé que TikTak conservera ne doit toucher que le vault « TikTak » et que les fichiers — en cas de fuite, le reste de la mémoire reste hors de portée.
  • Sous-tâches :
    • POST /api/auth/tokens : vaults? (sous-ensemble du créateur, 400/403 sinon) + scope (full défaut | files) ; JWT + record portent la portée
    • Vault : check_vault_access/require_vault_access existants → 403 hors vault (REST + MCP)
    • Périmètre files : TokenScopeMiddleware (403 REST, stateless) + call_tool/ propose_*/list_tools/vault:// (token_scope_denied, FILES_SCOPE_TOOLS)
    • UI : sélecteur de portée + champ vaults, badge et vaults listés (i18n FR/EN)
    • Compatibilité : clés existantes = full, inchangées
    • Tests tests/test_scoped_tokens.py (13) + guides API_REST (§2.3, §5) / MCP

200. Provisionnement du vault dédié « TikTak » (exploitation, Gitea #1)

  • Effort : 0,5 jour | Impact : 🟡 | Ouvert : 2026-10-14 | Statut : ✅ livré le 2026-10-14 (runbook)
  • Fiche : features/tiktak-integration-197-200.md (§#200)
  • Description : opération unique côté hébergement, aucun code requis : dossier hôte + montage conteneur + POST /api/vaults/add (persisté, sans redémarrage) + ACL du compte de synchro + clé limitée (#199) + webhook filtré (#198) + recette curl d'acceptation. Reste à exécuter sur l'hôte (suivre le runbook, puis fermer Gitea #1).

201. Menu contextuel « Déplacer » / « Dupliquer » + réparation du drag & drop interne (sidebar, BUG-117)

  • Effort : 0,5 jour | Impact : 🟡 | Ouvert : 2026-10-15 | Statut : ✅ livré le 2026-10-15
  • Description : déplacement/duplication fichiers et répertoires via le menu contextuel (modal promptTargetFolder réutilisé et harmonisé, emplacement actuel pré-sélectionné, cross-vault refusé proprement) ; endpoint POST /api/duplicate/{vault} (duplicate_path : copie X copie.ext, collisions numérotées, refus de dupliquer un dossier dans lui-même, index incrémental, SSE + webhooks) ; drag & drop interne réparé (le drop était avalé en silence par la détection isExternalFiles qui comptait les formats string tree:* du glisser interne) ; i18n FR/EN ; 4 tests TestDuplicateApi + validation Playwright E2E.

77. Application Desktop native — Tauri (Windows / Linux / macOS)

  • Effort : 8-12 jours | Impact : 🟡 | Framework : Tauri v2 (Rust + Webview)
  • Statut : livré (A→F) — projet Tauri, backend Python embarqué, fonctionnalités natives, jumplist vaults, bannière 1er lancement, build CI, UX, 24 tests Rust. Détail complet : features/desktop-tauri.md
  • Reste à faire :
    • Signature de l'updater Tauri (gratuit) : paire de clés générée, pubkey renseignée, createUpdaterArtifacts activé, secrets CI câblés
    • Manifeste latest.json généré par scripts/updater_manifest.py (intégré à publish_release.py), endpoint updater pointé sur main
    • Signature de code Windows : non retenue — décision confirmée le 2026-09-26 : livraison non signée + documentation SmartScreen (« Exécuter quand même »). Alternatives écartées sauf retour utilisateur : SignPath.io (OSS gratuit), Certum OSS, Azure Trusted Signing, certificat EV
    • Exécuter les 6 tests E2E manuels — protocole documenté : DESKTOP_E2E_CHECKLIST.md

✅ Terminé — Visionneuse & édition Excel (P0/P1/P2)

153. Visionneuse & édition XLSX — complétude (fidélité, recherche, IA, UX, formats)

  • Effort : 8-13 jours (P0 ✅ 2-3 j · P1 : 4-6 j · P2 : 2-4 j) | Impact : 🟡
  • Statut : ✅ livré le 2026-09-28 — P0 le 2026-09-27 (BUG-085 → BUG-088), A5/A10/A12 le 2026-09-28 (avec BUG-089), A8/A9/A9bis le 2026-09-28 (avec BUG-090), puis v2.33.0 → v2.39.0 : A6, A7, A13, A14, A15, A16, A17 (+ A11 déjà au CI) — backlog #153 terminé
  • Analyse, risques et critères d'acceptation : features/xlsx-viewer.md
  • Description : #152 (visionneuse XLSX, 2.27.0) lit et édite correctement la grille de valeurs d'un .xlsx, mais l'ensemble supporté est étroit : valeurs seulement (ni structure, ni styles en écriture, ni formule recalculée), écriture destructive d'une partie du classeur, tableurs invisibles à la recherche et inutilisables par l'IA au-delà de la création. Ce lot suit ces ajouts ; les cases ci-dessous sont le suivi de référence, la fiche feature porte le détail.
  • Constat (points de départ) : MAX_ROWS = 500 / MAX_COLS = 40 sans indicateur (troncature silencieuse) · wb.save() non atomique et sans verrou (concurrence) · saisie =… stockée comme formule par openpyxl (injection DDE) · content="" à l'indexation (recherche TF-IDF et sémantique aveugles) · aucun outil IA de lecture/édition d'un classeur existant · aucun test frontend ni E2E sur le viewer.
  • Périmètre réel des pertes au round-trip (mesuré sur openpyxl 3.1.5, 2026-09-27) : graphiques, images, dessins et tableaux croisés sont préservés ; sont perdus les valeurs calculées en cache, slicers/chronologies, contrôles de formulaire, connexions/requêtes, custom XML, signature numérique, commentaires enrichis et macros.
  • Sous-tâches :
    • P0 — garde-fous d'écriture (🔴, 2-3 j) — 🟢 livré
      • A1 Alerte de fidélité avant écriture : inspect_workbook() → xlsx_lossy_features + bandeau FR/EN + 409 xlsx_lossy_content sans force (confirmation explicite puis reprise) — BUG-085
      • A2 Écriture atomique (wb.save(.tmp) + os.replace(), backup inchangé) — BUG-086
      • A3 Verrou par fichier autour du read-modify-write (timeout 15 s + 409 conflict) — BUG-087
      • A4 Neutralisation de l'injection de formule (=/@ stockés en texte, opt-in allow_formula + bouton f(x)) — BUG-088
    • P1 — recherche, IA, UX (🟡, 4-6 j) — 🟢 livré
      • A5 Indexation du contenu des feuilles (noms de feuilles + 20 premières lignes, plafond 5 k caractères) — les mots tapés dans une cellule rendent le fichier trouvable ; au passage BUG-089 (reindex manuel ne reconstruisait pas l'index inversé)
      • A6 Outils IA update_xlsx_cells / append_xlsx_rows / xlsx_to_markdown / list_xlsx_sheets (v2.33.0)
      • A7 Navigation clavier + barre de formule + nom de cellule (Tab/Entrée/flèches) (v2.34.0)
      • A8 thead sticky + bandeau « feuille tronquée » (lève la troncature silencieuse) — BUG-090
      • A9 Chargement paresseux par feuille (GET …/xlsx/sheet?offset&limit, défilement virtuel)
      • A10 Types & formats de saisie (nombre/texte, booléens TRUE/FAUX, dates FR JJ/MM/AAAA jour-first)
      • A11 Tests frontend (tests/frontend/xlsx-viewer.test.mjs) + E2E (tests/e2e/xlsx-viewer.spec.js) au CI (JSDOM dans le job lint depuis v2.31.0 ; spec E2E livrée avec A9bis)
      • A12 Valeur calculée affichée sous la formule (2ᵉ lecture data_only=True seulement si l'archive contient un <v>, info-bulle FR/EN)
    • P2 — étendu (🟢, 2-4 j) — 🟢 livré
      • A13 Tri / filtre / recherche dans la feuille + export CSV de la sélection (v2.35.0)
      • A14 CRUD de feuilles, lignes et colonnes (renommer, insérer, supprimer, dupliquer) (v2.36.0)
      • A15 Styles minimaux + lecture fidèle (gras, fond, formats, fusions, volets figés) (v2.37.0)
      • A16 Formats additionnels (.xlsm avec keep_vba, .xls/.ods lecture seule via xlrd/odfpy, .csv éditable) (v2.38.0)
      • A17 Vue « tableau de bord » (plages nommées, TCD/graphiques, KPI par feuille, hint actions IA) (v2.39.0)
  • Convention de suivi : chaque sous-tâche démarre par son ID stable (#153-A<n> dans cette Roadmap) ; celles qui sont des défauts sont aussi ouvertes comme BUG-NNN dans ISSUES_TODOLIST.md (A1→BUG-085, A2→BUG-086, A3→BUG-087, A4→BUG-088 ; A8 le sera à son tour).

✅ Terminé — Refonte UI/UX tableur (P2)

154. Refonte UI/UX de la visionneuse & éditeur XLSX (ruban, grille, inspecteur)

  • Effort : 6-9 jours (Lot 1 ✅ · Lot 2 · Lot 3 · Lot 4) | Impact : 🟡
  • Statut : ✅ livré le 2026-09-29 (Lots 1 → 5, A1-A5) — ruban de commandes groupé, onglets de feuilles permanents avec bouton « + », badges d'état lecture seule / formules non recalculées, tokens de grille et affordances ; dialogues thémés showConfirm/showPrompt, bandeau de conflit 409 non bloquant, indicateur dirty ; inspecteur droit repliable (tableau de bord + entrée Assistant IA, redimensionnable) ; undo/redo, chargement via IntersectionObserver, ARIA role="grid" ; extraction des unités sans état dans frontend/js/xlsx/*.
  • Analyse, architecture cible et plan par lots : features/xlsx-ui-redesign.md
  • Description : la visionneuse XLSX (#152/#153) est fonctionnelle mais peu conviviale : commandes à plat sans hiérarchie, en-têtes de grille indistincts des cellules, états avancés (tableau de bord, troncature, lecture seule, formules non recalculées, conflits) mal intégrés. La refonte s'appuie sur les standards Excel/Google Sheets/Airtable sans renier la contrainte vanilla JS, zéro framework, zéro build npm.
  • Sous-tâches :
    • A1 Coquille : barre de commandes groupée, onglets feuilles permanents + « + », badges d'état, tokens de grille et affordances visuelles (Lot 1)
    • A2 Dialogues thémés (modales + toasts) et feedback non bloquant des conflits 409 (Lot 2)
    • A3 Inspecteur droit repliable : Tableau de bord + entrée Assistant IA (Lot 3)
    • A4 Undo/redo, chargement via IntersectionObserver, sémantique ARIA (Lot 4)
    • A5 Découpage frontend/js/xlsx/*, lien dashboard → grille, inspecteur redimensionnable (Lot 5)

✅ Terminé — Ergonomie tableur

155. Ergonomie tableur — menu contextuel & sélection type Excel

  • Effort : 2-4 jours | Impact : 🟡
  • Statut : ✅ livré — 2026-09-29 (menu contextuel clic droit + appui long, sélection type Excel)
  • Analyse, conception et critères : features/xlsx-context-menu.md
  • Description : retours utilisateur après #154 — ajouter un menu contextuel (clic droit + appui long tactile) sur les cellules et en-têtes, et aligner la sélection/curseur sur le comportement d'Excel (plage par glisser, Maj, sélection de ligne/colonne par en-tête).
  • Sous-tâches :
    • A1 Menu contextuel thémé (clic droit + appui long) : insérer/supprimer ligne & colonne, trier, effacer le contenu
    • A2 Sélection type Excel : plage (glisser / Maj+clic / Maj+flèches), en-têtes ligne/colonne, curseur croix, zone Nom affichant la plage

✅ Terminé — Polish menus tableur

179. Éditeur tableur — icônes des menus & boutons, fermeture au focus, polish mobile

  • Effort : 1-2 jours | Impact : 🟡
  • Statut : ✅ livré le 2026-10-04 (v2.53.0) — ouvert le 2026-10-04
  • Fiche : features/xlsx-menus-179.md
  • Description : la grille (#155), les menus Structure/Mise en forme/Export (#156-A8/A11/A14) et les boutons du ruban (#154) sont textuels et restent ouverts quand le focus quitte le menu. Ajouter des icônes Lucide représentatives, fermer tout menu à la perte de focus (clic extérieur, focusout, Échap, défilement), naviguer au clavier dans le menu grille, et garantir des cibles tactiles ≥ 44 px + menus dans le viewport en mobile.
  • Sous-tâches :
    • A1 Icônes des entrées du menu contextuel de la grille (+ item.icon)
    • A2 Icônes des menus Structure / Mise en forme / Export + boutons Enregistrer / « + » onglet
    • A3 Fermeture à la perte de focus (helper partageable : extérieur, focusout, Échap, scroll/resize) + navigation clavier du menu grille
    • A4 Polish mobile (44 px tactile, menus bornés au viewport) + tests JSDOM + E2E xlsx-viewer.spec.js

✅ Terminé — Ergonomie & grille du tableur

186. Création d'un fichier Excel depuis « Créer un fichier »

  • Effort : 0,5 jour | Impact : 🟢
  • Statut : ✅ livré le 2026-10-05 - ouvert le 2026-10-05
  • Fiche : features/create-file-xlsx-186.md
  • Description : l'éditeur Excel étant disponible, la modale « Créer un fichier » ne proposait que des formats texte (.md, .txt, .py, .js, .json, .yaml, .sh, .ps1) + Excalidraw : impossible de démarrer un classeur depuis l'UI. Il fallait passer par l'assistant IA (create_xlsx) ou déposer un fichier existant.
  • Sous-tâches :
    • A1 Option Excel (.xlsx) dans la liste des types, et les 10 libellés du <select> passés en i18n FR/EN (modal.ext_*) — ils étaient codés en dur
    • A2 create_file() backend : un .xlsx est une archive OPC, pas du texte — le classeur est construit avec openpyxl (une feuille Feuille1) au lieu d'écrire la charge utile vide, sinon le fichier est illisible par la visionneuse
    • A3 Tests : non-régression pytest (test_api_main.py — classeur relu par openpyxl et servi en is_xlsx), E2E xlsx-viewer.spec.js (option présente, création depuis le menu contextuel, ouverture dans la grille)

✅ Terminé — Assistant IA

187. Assistant IA — mode agent toujours actif, retrait du bouton toggle

  • Effort : 0,5 jour | Impact : 🟢
  • Statut : ✅ livré le 2026-10-07 (v2.53.2) — ouvert le 2026-10-06
  • Description : le bouton « mode agent » du panneau (toggle persisté en localStorage, défaut OFF) n'était plus protecteur : Deep Research et les quick actions agent: true basculaient déjà le mode en silence. Un utilisateur pouvait donc voir l'assistant agir sans jamais avoir activé le bouton. Retiré au profit d'un agent toujours actif : toute requête texte part sur /api/ai/bookslm/agent (outils lire/lister/chercher/modifier ; les mutations gardent la confirmation two-step) ; les images seules restent sur /api/ai/bookslm/chat (endpoint multimodal, la boucle agent étant textuelle).
  • Sous-tâches :
    • A1 Frontend : bouton header, _agentMode, toggle/persistance et les auto-bascules (Deep Research, quick actions) supprimés ; _postChat route texte→/agent, images→/chat ; aide et i18n FR/EN mises à jour
    • A2 Optimisations requêtes AI : /agent résout désormais le provider comme /chat (avant : req.provider brut transmis au provider adapter → moteur réel ≠ étiquette SSE) ; schémas d'outils mis en cache (~27 ms de pydantic économisés par requête agent/MCP)
    • A3 Tests : ai.test.mjs adapté (100/100) ; non-régression pytest (test_bookslm.py provider résolu, test_tools.py cache sûr) ; ruff/mypy 0 erreur ; build + instance Docker locale à jour

✅ Terminé — Barre de menus & grille du tableur

185. Tableur — barre de menus Google Sheets (10 menus), ruban Sheets, grille unie

  • Effort : 1-2 jours | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-menus-185.md
  • Description : l'éditeur n'avait aucune barre de menus (ni Fichier, ni Modifier, ni Affichage, ni Insertion, ni Format, ni Données, ni Outils, ni Gemini, ni Extensions, ni Aide) : beaucoup de fonctions n'étaient atteignables que par clic droit. Le ruban gardait un chromer bordersé qui ne ressemblait à rien et la grille n'était bordée qu'en bas avec une couleur quasi identique au fond des cellules — le quadrillage se lisait comme une tache.
  • Sous-tâches :
    • A1 frontend/js/xlsx/menus.js : les dix menus de Google Sheets, dans l'ordre et avec les libellés exacts (161 entrées) ; sections en accordéon ; le menu Fichier quitte la barre d'onglets pour la barre de menus en conservant ses identifiants, seul Enregistrer reste épinglé
    • A2 Majorité des fonctions câblées : Partager, Renommer, Corbeille, Historique, Détails ; Annuler/Rétablir/Couper/Copier/Coller, Collage spécial (valeurs), Supprimer, Tout sélectionner, Rechercher-et-remplacer ; Figer, Afficher (barre de formule / grille / en-têtes / tableau de bord), Zoom, Plein écran ; Lignes / Colonnes / Cellules, Lien, Commentaire, Fonction ; Nombre, Thème, B/I/U/S, Taille, Alignement, Retour ligne, Rotation, Couleurs alternées, Effacer ; Trier, Filtre, Plages nommées, Nettoyage (doublons / espaces), Diviser le texte en colonnes ; Autocomplétion, Accessibilité ; Gemini ; Aide, Mises à jour, Raccourcis, Signalement. Les 36 options absentes d'ObsiGate sont listées et le disent au clic
    • A3 Ruban façon Sheets : boutons plats 30 × 30 sans chromer, survol discret, groupes par filets ; nouveau bouton grille piloté par le menu Affichage
    • A4 Grille unie et visible : 1 px sur les quatre côtés de chaque cellule (en-têtes compris) et un seul --grid-border dérivé du thème (color-mix texte → surface) au lieu de --border invisible
    • Tests JSDOM (xlsx-menus + xlsx-viewer), E2E xlsx-viewer.spec.js, i18n FR/EN (134 clés xlsx.m* / xlsx.mi_*)

184. Tableur — peinture de format, multi-lignes/colonnes, grille A→Z × 1000

  • Effort : 1 jour | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-sheet-input-181.md (§8)
  • Description : « Peindre le format » échouait quand la source n'avait pas de format propre ; il manquait la sélection de plusieurs lignes/colonnes depuis les marges ; la grille s'arrêtait aux dimensions réelles du fichier au lieu d'aller jusqu'à A → Z et 1000 lignes.
  • Sous-tâches :
    • A1 Peinture de format complète (toutes propriétés) + source sans format ⇒ réinitialisation de la cible ; fuite du handler annulé
    • A2 Sélection multi-lignes / multi-colonnes par glissement sur les marges et Maj+clic ; le geste de redimensionnement garde la priorité
    • A3 Grille étendue à A → Z × 1000 lignes, cellules vides éditables, padding à l'activation de l'onglet, pas de doublons
    • A4 Performance : index de cellules findTd, court-circuits formule/styles, marqueur data-wired

✅ Terminé — Panneau de couleurs du tableur

183. Panneau de sélection de couleurs façon Google Sheets (texte et fond)

  • Effort : 0,5-1 jour | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-sheet-input-181.md (§7)
  • Description : le sélecteur natif <input type="color"> du ruban et du menu Mise en forme est remplacé par un panneau conforme aux maquettes : Réinitialiser, palette 8 × 10, STANDARD, PERSONNALISÉ, pied de page. Un clic sur une pastille referme le panneau et applique la couleur.
  • Sous-tâches :
    • A1 Module frontend/js/xlsx/color-picker.js : palette 8 × 10 (8 gris puis 8 teintes × 9 nuances), sortie en #rrggbb
    • A2 Coche de sélection blanche/noire selon la luminance
    • A3 Câblage ruban + menu Mise en forme, fermeture au clic, application sur cellule ou plage, réinitialisation, « + » / crayons vers le sélecteur natif
    • A4 Chrome du panneau thémé (variables CSS), i18n FR/EN (21 clés), pied de page honnête (message explicite pour les fonctions absentes)

✅ Terminé — Correctifs éditeur tableur

182. Tableur — désélection fiable & couleurs sur une plage

  • Effort : 0,5 jour | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-sheet-input-181.md (§6)
  • Description : suite de #181 — la sélection multiple se dessinait mais ne s'effaçait plus, et l'application d'une couleur de texte / de fond sur une plage paraissait inerte.
  • Sous-tâches :
    • A1 Le clic simple efface toujours la plage, sans dépendre de l'événement focus (cause : Maj+clic + preventDefault() figeait le focus, donc aucun focus ne partait au clic suivant)
    • A2 Après Maj+clic, le focus suit la cellule cliquée ; la zone Nom affiche la plage après un glissement
    • A3 Couleurs de texte et de fond vérifiées sur les 3 chemins (menu Mise en forme, nuanciers du ruban, Maj+flèches et glissement)
    • A4 Pastille de couleur sur les nuanciers du ruban (retour visuel)
    • A5 Contours de plage qui s'empilaient : le sélecteur de nettoyage oubliait le . des classes (querySelectorAll("xlsx-sel-top") cherche une balise) — rien n'était effacé, les encadrés restaient et s'ajoutaient à chaque changement de cellule. Même famille de faute sur les en-têtes reflétés
    • A6 Pendant la saisie, les flèches valident et déplacent la sélection (au lieu de déplacer le curseur), comme Google Sheets ; Alt+flèche garde le saut de ligne
    • Tests JSDOM xlsx-viewer 152/152 (+6), suites frontend vertes

✅ Terminé — Polish éditeur tableur (mise en page & thèmes)

181. Éditeur tableur — modèle de saisie Google Sheets (sélection ≠ édition) & écarts fonctionnels

  • Effort : 1 jour (A1-A3) + inventaire des écarts (A4) | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-sheet-input-181.md
  • Description : l'éditeur ne distingue pas sélectionner une cellule et l'éditer : le curseur de texte est visible en permanence, Entrée valide puis perd le focus, et l'indicateur de plage est discret. Aligner le modèle de saisie sur Google Sheets / Excel (A1-A3) et inventorier précisément ce qui manque encore face à un tableur de référence (A4) — le rapprochement exhaustif n'est pas réalisable en une tranche.
  • Sous-tâches :
    • A1 Deux états distincts : sélection (clic / flèches, pas de curseur via caret-color: transparent, contour visible) et édition (double-clic en place, première frappe qui remplace, F2, Alt+flèche pour un saut de ligne, Échap qui restaure)
    • A2 Sélection multiple : glisser, Maj+clic, Maj+flèches, avec contour de plage (.xlsx-sel-* sur les 4 bords réels) + en-têtes A/B… et 1/2… reflétés
    • A3 Entrée contextuelle : en édition → valide et passe à la cellule du dessous ; en sélection → bascule en mode édition
    • A4 Inventaire des écarts vs Google Sheets / Excel et priorisation (P1 poignée de recopie / remplacer / validation de données / filtre auto / tri multi-critères ; P2 mise en forme conditionnelle / création de graphiques / TCD éditables / protection ; P3 analyse de données, historique, macros) — voir fiche
    • Tests JSDOM (xlsx-viewer 146/146, +10 cas #181), suites frontend vertes, build + déploiement de l'instance Docker locale

180. Éditeur tableur — redimensionnement au curseur, grille thémée, menu Fichier & barre épinglée

  • Effort : 1-2 jours | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 (v2.54.0) — ouvert le 2026-10-05
  • Fiche : features/xlsx-sheetbar-180.md
  • Description : retours utilisateur après #179 — (1) le redimensionnement des colonnes/lignes par les marges (A, B, C… / 1, 2, 3…) doit afficher un curseur iconique (col-resize / row-resize) quand le pointeur est sur le bord ; (2) la grille doit suivre le thème de l'utilisateur (15 thèmes × 4 modes + importés : tokens dérivés, plus de fond figé) ; (3) regrouper Télécharger / CSV / Exporter dans un menu Fichier en haut à droite, au niveau des onglets de feuilles, avec Enregistrer juste à côté ; (4) retirer l'indicateur « Formules calculées localement » ; (5) épingler la barre de boutons en haut, au bord de la marge, et étendre l'éditeur à la largeur de la page.
  • Sous-tâches :
    • A1 Curseur de redimensionnement sur les marges d'en-têtes (en-tête de bord miroité en ligne + classe de repaint .xlsx-resize-col/row)
    • A2 Grille compatible tous thèmes (--grid-* dérivés dans themes.js, replis CSS, modes contraste élevé / sépia, menu Export sur --surface)
    • A3 Menu Fichier + Enregistrer au niveau des onglets (.xlsx-sheetbar, identifiants des contrôles conservés)
    • A4 Retrait de l'indicateur de formules + barre épinglée pleine largeur (position: sticky, :has(.xlsx-viewer) en plein cadre)
    • Tests JSDOM (xlsx-viewer 136/136, xlsx-menus 12/12), E2E xlsx-viewer.spec.js, i18n FR/EN, 8 tests réalignés sur l'application locale des écritures

✅ Terminé — Navigation

158. Navigation — vue répertoire en onglet, filtres & tris, retour Home complet

  • Effort : 1-2 jours | Impact : 🟡
  • Statut : ✅ livré — 2026-10-02 (A1 onglet, A2 contenu/filtres/tris, A3 retour Home + BUG-100)
  • Détail de conception : features/navigation-tab-158.md
  • Description : la vue « chemin + Récents + fichiers du répertoire » (vault home) n'apparaît qu'en mode focus vault, disparaît dès qu'un fichier est ouvert, n'expose ni sous-répertoires ni filtres, et le clic sur le titre ne redonne pas la vraie page d'accueil (section Raccourcis & Astuces manquante, recherche/filtres non effacés).
  • Sous-tâches :
    • A1 — onglet de navigation. Tout clic sur un répertoire de l'arbre (en mode focus vault et en mode All) ouvre/actualise un onglet de navigation dédié, qui coexiste avec les onglets de fichiers ouverts. La ligne d'un vault dans l'arbre garde son rôle d'expansion ; la racine du vault s'atteint depuis la vue (fil d'Ariane, facette Vaults) ou le sélecteur de vault.
    • A2 — contenu de la vue. Liste des sous-répertoires cliquables, panneau de facettes Vaults · Tags · Extensions (même mécanisme/visuel que la page de recherche), boutons de tri Pertinence / Date et bouton Sauver.
    • A3 — retour Home complet. Clic sur le titre = page d'accueil d'un refresh (section Raccourcis & Astuces restaurée) + effacement de la recherche globale et de la barre de filtre de la sidebar gauche.
    • A4 — onglet Accueil. Le clic sur le titre affiche la page d'accueil dans un onglet (icône Maison) épinglé en tête de barre, réactivable à tout moment.
    • A5 — menus contextuels de la page de navigation. Clic droit identique à la sidebar sur les répertoires et les fichiers de la vue ; la ligne d'un vault dans l'arbre ouvre la page de navigation (racine du vault).
    • A6 — icône des répertoires de la section Répertoires à la couleur de l'arbre (var(--accent)).

✅ Terminé — Tableur Excel (complétude)

156. Éditeur Excel — complétude fonctionnelle (presse-papiers, mise en forme, calcul, robustesse)

  • Effort : 15-22 jours (P0 2-3 j ✅ · P1 4-6 j ✅ · P2 5-7 j ✅ · P3 4-6 j ✅) | Impact : 🟡
  • Statut : ✅ livré le 2026-09-30 — P0 (4 défauts BUG-096 → BUG-099 corrigés), P1 (A5-A7 : presse-papiers de plage, clavier complet, zone Nom éditable), P2 (A8 mise en forme en écriture, A9 décision « pas de moteur de formule, annoncée dans l'UI », A10 undo/redo unifié conservé au re-rendu) et P3 (A11 export sélection/ Markdown/HTML/impression + recherche multi-feuilles, A12 concurrence optimiste If-Match, A13 cache des métadonnées, A14 outils IA .xlsm/.csv + recherche/analyse/structure)
  • Analyse, défauts, risques et critères d'acceptation : features/xlsx-editor-completeness.md
  • Description : #153 a rendu l'éditeur correct sur la grille de valeurs, #154/#155 l'ont rendu convivial (ruban, inspecteur, undo/redo des cellules, sélection et menu contextuel type Excel). Il reste l'écart avec un vrai éditeur tableur : coller une plage, écrire la mise en forme, calculer, sortir le résultat, et détecter un écrivain concurrent. La fiche porte l'audit ; les cases ci-dessous sont le suivi de référence.
  • Défauts corrigés le 2026-09-29 (cf. ISSUES_TODOLIST.md) :
    • ✅ BUG-096 — enregistrer un .csv depuis la visionneuse levait un TypeError (sheet: sheets[…].name alors qu'un CSV n'a pas de xlsx_sheets) : aucun PUT …/csv/save n'était émis (reproduit en JSDOM, corrigé + test) ;
    • ✅ BUG-097 — feuille .xlsm tronquée : « Charger la suite » échouait en 415 — GET …/xlsx/sheet accepte désormais .xlsx et .xlsm ;
    • ✅ BUG-098 — délimiteur CSV détecté (;/,/tabulation) et réutilisé à l'écriture : un CSV français s'affiche en colonnes et le reste après édition ;
    • ✅ BUG-099 — sonde de perte par feuille + signal cached_values_unverified quand le budget est épuisé : plus de perte silencieuse possible des valeurs calculées.
  • Sous-tâches :
    • P0 — défauts (🔴, 2-3 j) — ✅ livré le 2026-09-29
      • A1 Sauvegarde .csv depuis la visionneuse — BUG-096 (test JSDOM : PUT …/csv/save émis)
      • A2 Chargement paresseux des .xlsm — BUG-097 (GET …/xlsx/sheet accepte .xlsx/.xlsm)
      • A3 Délimiteur CSV détecté et réutilisé à l'écriture — BUG-098 (sniff_csv_delimiter)
      • A4 Sonde de perte par feuille + signal cached_values_unverified — BUG-099
    • P1 — presse-papiers & clavier (🟡, 4-6 j) — ✅ livré le 2026-09-29
      • A5 Presse-papiers de plage — copier/couper/coller un bloc TSV (Ctrl+C/Ctrl+X/Ctrl+V, menu contextuel), presse-papiers interne + système, remplissage multi-cellules (tests JSDOM : A1:B2 → D5:E6)
      • A6 Clavier complet — Ctrl+S, Ctrl+A, Suppr, F2, Ctrl+Home/End, Home/End, PgUp/PgDn, Ctrl+flèches, Maj+Entrée (saut de ligne en cellule)
      • A7 Zone Nom éditable (« Atteindre » : B12, A1:B3, Feuille!A1) + aide à la saisie des fonctions
    • P2 — mise en forme, calcul, undo (🟡, 5-7 j) — ✅ livré le 2026-09-30
      • A8 Mise en forme en écriture — bouton Mise en forme (gras/italique/souligné, alignements, couleurs, formats de nombre, fusions, volets figés, largeur/hauteur) via PUT …/xlsx/style (verrou, backup, garde de perte, If-Match)
      • A9 Calcul — décision documentée : pas de moteur de formule, l'enregistrement annonce « enregistrée comme texte » (la garde anti-DDE reste)
      • A10 Undo/redo unifié (cellules, effacement, tri/filtre, structure) et conservé au re-rendu (_xlsxHistory par fichier)
    • P3 — sortie, robustesse, performances (🟢, 4-6 j) — ✅ livré le 2026-09-30
      • A11 Sortie & recherche : export de la sélection / Markdown / HTML / impression, recherche sur toutes les feuilles (compteur n/m · k feuilles)
      • A12 Concurrence optimiste inter-processus (ETag/If-Match, 409 réparable, bouton « Réessayer » qui relit)
      • A13 Performances : cache des métadonnées par (chemin, mtime, taille) (LRU 8), invalidé à chaque écriture (axe des colonnes > MAX_COLS : hors périmètre)
      • A14 Outils IA étendus — .xlsm/.csv acceptés, search_workbook, analyze_range, edit_xlsx_structure

✅ Terminé — Secrets masqués

188. Secrets masqués — couverture universelle des clés API & mots de passe + clic pour copier

  • Effort : 1 jour | Impact : 🟡
  • Statut : ✅ livré le 2026-10-08 — ouvert le 2026-10-08
  • Fiche : features/secret-mask-188.md
  • Description : le redacteur (secret_redactor.py) ne couvrait que les JWT, clés sk-/AKIA/ghp_, connection strings et affectations key=value de 20+ caractères — la plupart des clés API réelles et tous les mots de passe courts passaient en clair dans l'aperçu markdown, et un masque affiché n'était pas récupérable sans ouvrir la source. #188 couvre la majorité des formats de clés, masque les mots de passe quelle que soit leur longueur et rend chaque masque cliquable dans l'aperçu authentifié (copie dans le presse-papiers) sans jamais exposer la valeur à l'extérieur (partages, PDF, IA/MCP).
  • Sous-tâches :
    • A1 Détection universelle : table de formats fournisseur (OpenAI, Stripe, GitLab, GitHub, Google, AWS, Slack, SendGrid, Hugging Face, npm, Docker, Resend, Square, Atlassian, Discord, Telegram, Bearer …) + plancher des affectations génériques 20 → 8 caractères
    • A2 Mots de passe : [MOT DE PASSE MASQUÉ] toute longueur / quote (password=, "passwd":, db_password=, mot de passe=) ; PWD= shell épargné
    • A3 Clic → copie : placeholders markdown-safe (blocs de code compris) réécrits en <span class="secret-mask" data-secret> côté aperçu authentifié (listener délégué, toast + infobulle i18n FR/EN) ; libellé seul pour partages / PDF / IA / MCP ; code masqué non re-coloré (highlight.js perdrait le badge)
    • A4 Guide in-app FR/EN, GUIDES/AUTHENTIFICATION_SECURITE.md, README FR/EN, tests TestSecretRedactor (+33)

✅ Terminé — Mise en page mobile du tableur

189. Tableur — mise en page mobile (barres repliées, grille prioritaire)

  • Effort : 0,5-1 jour | Impact : 🟡 | Framework : CSS vanilla + frontend/js/viewer.js
  • Statut : ✅ livré le 2026-10-08 — ouvert le 2026-10-08
  • Fiche : features/xlsx-mobile-layout-189.md
  • Description : sur mobile, la barre de menus + le ruban + la barre de formule s'empilaient et occupaient plus de 50 % de la hauteur d'écran. Sous 768 px, .xlsx-menubar, .xlsx-cmdbar et le groupe Recherche sont repliés par défaut (la barre de formule fx et les onglets restent visibles) et un bouton unique #xlsx-tools-toggle dans la barre des feuilles déplie/replie l'ensemble (aria-expanded, état actif) — desktop inchangé (bouton masqué).
  • Sous-tâches :
    • A1 Repli CSS par défaut ≤ 768 px + révélation via .xlsx-toolbar.xlsx-tools-open (menubar, ruban, Recherche)
    • A2 Bascule #xlsx-tools-toggle dans .xlsx-sheetbar (aria-expanded + classe active + i18n xlsx.tools_toggle FR/EN)
    • A3 Tactile : cibles ≥ 44 px, onglets en défilement horizontal, champs de la barre de formule en 16 px (anti-zoom iOS), barre de formule en 2 lignes quand les outils sont ouverts
    • A4 Tests : JSDOM xlsx-viewer.test.mjs (+2, 165/165) et E2E mobile (repli par défaut, dépliage, no-overflow ruban, 44 px) ; openXlsx() déplie automatiquement ≤ 768 px pour les tests desktop

⚪ Backlog — Priorité 4 (P4)

73. Synchronisation multi-appareils — Obsidian Sync compatible

  • Effort : 6-8 jours | Impact : 🟢
  • Décision 2026-09-26 : reporté (P4) — axe prioritaire = dette & sécurité (#85/#87) ; #73 hors chemin critique. Si réactivé : partir d'un MVP export/hash/LWW adossé à #59 (PWA offline) + #62 (collab Yjs/CRDT) plutôt qu'un protocole parallèle.
  • Périmètre élargi le 2026-10-04 (liste v1.2 Ph.3) : la synchronisation des favoris (répertoires compris, cf. #161) et la synchronisation des préférences utilisateur (thèmes #65/#174, langue, historique de recherche et de modifications, recherches sauvegardées #162) sont fusionnées dans cet item plutôt que portées par des items séparés — même API de sync, même résolution de conflits. Store local actuel : JSON par utilisateur dans data/ (pas de table user_preferences distincte ; un addendum de schéma suffirait si #73 est réactivé).
  • Description : Synchronisation des vaults entre plusieurs instances d'ObsiGate via un protocole de synchronisation décentralisé ou compatible Obsidian Sync. Alternative self-hosted à Obsidian Sync.
  • Sous-tâches :
    • Protocole : évaluation CRDT vs OT vs diff/patch pour fichiers markdown
    • Transport : WebSocket ou polling HTTPS avec compression
    • Merge strategy : LWW (Last Writer Wins) avec historique des deux versions
    • Détection de changements : hash SHA-256 par fichier, journal des modifications
    • UI : page « Synchronisation » avec statut par appareil, historique des syncs
    • Conflits : UI de résolution manuelle (diff côte à côte entre version locale et distante)
    • Chiffrement : optionnel, chiffrement AES-256-GCM avant transmission
    • Pairing : échange de clé publique + code QR pour appairage des appareils
    • Périmètre v1.2 : sync des favoris (#161) et des préférences (thème, langue, historique, recherches sauvegardées) avec résolution de conflits (priorité à la dernière modification) + indicateur « préférences synchronisées »

⚪ Backlog — Sécurité, architecture & performance (P0/P1)

87. Amélioration continue — tests, CI/CD, revues de sécurité (phase 4)

  • Effort : 3-5 jours | Impact : 🟡 | Zone : .gitea/workflows/, tests/
  • Décision 2026-09-26 : prioritaire (axe Dette & sécurité).
  • Statut : 🔵 en cours depuis 2026-09-26 — par tranches. T1 livrée (v2.28.1) : bandit bloquant (nosec justifiés B324/B404/B603/B607/B406, B105 exclu comme pyproject), npm audit bloquant (0 vulnérabilité), 5 suites frontend intégrées au CI (upload, pretty, media-viewer, mfa-settings, config-ai-keys). pip-audit reste consultatif (montées starlette/weasyprint à qualifier).
  • T6 livrée (v2.28.15) : dépendances qualifiées — mistune 3.3.3, python-multipart 0.0.31, weasyprint 70, mcp 1.28.1, fastapi 0.141.1 + starlette 1.7.0, setuptools 84 (cast mistune 3 sites) — suite 1359 passed, ruff/mypy 0, pip-audit bloquant, 0 vulnérabilité (seule exception documentée : PYSEC-2026-1325 ecdsa, sans correctif upstream, JWT HS256 uniquement).
  • T7 livrée (v2.28.15) : semgrep bloquant sur ruleset 100 % local semgrep-rules/ (8 règles, 0 finding, contrôle négatif OK) ; trivy écarté (binaire + DB réseau, couche Python couverte).
  • T8 livrée (v2.28.15, fin BUG-034) : cookies Secure auto (true|false|auto, X-Forwarded-Proto sous TRUST_PROXY, warning affiné, TRUST_PROXY=true en prod) ; CORSMiddleware same-origin explicite ; style-src 'unsafe-inline' conservé assumé (189 style= + 343 el.style, T5c ayant verrouillé script-src).
  • Description : renforcer le pipeline (.gitea/workflows/ci.yml, desktop-build.yml) pour le rendre bloquant par défaut et accompagner les phases 1 → 3. Constat 2026-09-26 : job security non bloquant (bandit/pip-audit en || echo, ni semgrep ni trivy), E2E limité à chromium-desktop, 5 suites frontend hors CI.
  • Sous-tâches :
    • Jobs CI sécurité bloquants (bandit/semgrep/trivy, audits pip/npm) + tests E2E XSS (page de partage + lecteur markdown) — T4 livrée : tests/e2e/xss.spec.js (BUG-021/022, 2/2 vert) + scripts/e2e-server.ps1 (cycle de vie serveur E2E avec progression start|stop|status|logs) + validation locale projet chromium-desktop : 108/108 verts (obsigate 44, split 37, viewers 24, xss/header 3), mobiles ciblés 10/10
    • Tests de concurrence (users.json), fuzzing de timing regex, couverture des composants critiques ; intégrer au CI les 5 suites frontend hors CI (upload, pretty, media-viewer, mfa-settings, config-ai-keys) — T2 livrée (v2.28.2) : tests/test_hardening_concurrency.py (users.json concurrent + budget temps regex) ; 5 suites au CI (T1)
    • Finir BUG-034 (migration CSP nonce, conversion des handlers inline), Secure cookies à true par défaut, politique CORS same-origin explicite ; confirmer la rotation de la clé DeepSeek (BUG-006, clé dans l'historique Git) — T3 livrée (v2.28.3) (helper + avertissement + CORS attesté) ; T5a livrée (v2.28.6) (16 handlers inline → listeners, CSP inchangée) ; T5b livrée : nonce frais par réponse (backend/csp.py, script-src), injection dans les 6 pages HTML (dont nouvelle route /excalidraw-editor.html), unsafe-inline conservé (inerte) ; T5c livrée (v2.28.13) (script-src sans unsafe-inline) ; T8 livrée (v2.28.15) (fin BUG-034 : Secure auto + CORS explicite ; style-src résiduel assumé ; rotation DeepSeek BUG-006 toujours côté utilisateur)
    • Revue périodique des dépendances ; documentation utilisateur FR/EN synchronisée ; contrôle automatisé de la conformité au DoD — T6/T9 livrées (v2.28.15) (pip-audit 0, npm audit 0, locales FR/EN 2213 clés parité testée test_i18n_parity.py, gardes test_version.py + test_ci_workflow.py)
    • Revue périodique des dépendances ; documentation utilisateur FR/EN synchronisée ; contrôle automatisé de la conformité au DoD

⚪ Backlog — Améliorations produit & évolutions agent IA (liste v1.2) — P1/P2

Ouvert le 2026-10-04 à partir de la liste « Roadmap ObsiGate – Développement des Fonctionnalités » v1.2 (phases 1-3 + suggestions agent IA numérotées 161-180 dans la liste source). Évaluation croisée avec le code réel (2026-10-04) : 7 propositions sont déjà livrées et n'ouvrent donc pas d'ID ; seul le périmètre manquant reçoit un ID ObsiGate stable #161 → #178. Les numéros de la liste source ne sont pas repris tels quels (règle du dépôt : un ID n'est jamais attribué à du déjà-fait ni réutilisé). Chaque item doit passer par DELIVERY_WORKFLOW.md (DoD) à son ouverture.

Table de correspondance (liste v1.2 → ObsiGate)

Proposition v1.2 Verdict 2026-10-04 (vérifié dans le code) ID ObsiGate
Ph.1 — Sauvegarde des recherches fréquentes Sauvegarde déjà livrée (backend/saved_searches.py, store data/{user}_saved_searches.json, bouton « Sauver » #158) ; fréquence & rappels manquants ⚪ #162
Ph.1 — Liens de répertoires aux favoris Marque-page existant sur fichiers uniquement (dashboard) ; répertoires absents ⚪ #161
Ph.1 — Recherche dans la page Déjà livrée en vue lecture (FindInPageManager, Ctrl+F + navigation + regex, tableur via #153-A13) ; reste l'intégration Forge ⚪ #163
Ph.2 — Auto-complétion intelligente Déjà livrée (frontend/js/autocomplete.js : Mermaid, code fence, frontmatter, wikilinks, table — partagé Forge/CodeMirror) ✅
Ph.2 — Suggestions contextuelles (historique & préférences) Non livré ⚪ #164
Ph.3 — Synchronisation favoris + préférences multiplateforme Fusionné dans le périmètre de #73 (reporté P4, décision 2026-09-26) ⚪ #73
161 — Synchronisation Git automatique des vaults Non livré (les outils git_* #92 ciblent Gitea/GitHub pour l'IA, pas la sync de vault) ⚪ #165
162 — Génération de résumés automatiques Déjà livrée (POST /api/ai/summarize, actions instantanées #106, skills backend/skills.py) ✅
163 — Détection & fusion de doublons Non livré (brique embeddings/TF-IDF #70 disponible) ⚪ #166
164 — Traduction automatique Déjà livrée (toolbar IA « Traduire », #106) ✅
165 — Analyse de ton/style Déjà livrée (toolbar IA « Ton », #106) ✅
166 — APIs tierces (Google Drive, Notion) Partiel : sources connectées Gitea/GitHub livrées (#103, backend/tools/connected.py) ; Drive/Notion manquants ⚪ #167
167 — Notifications externes (Slack, Discord, Email) Partiel : webhooks #9 + Push API #67 livrés ; canaux Slack/Discord/SMTP et choix des déclencheurs à câbler ⚪ #168
168 — Édition collaborative temps réel Déjà livrée (#62 — Yjs/CRDT, WebSocket, awareness, v2.3.0) ✅
169 — Scripts personnalisés sandboxés Déjà livrée (#61 — plugins en sandbox Web Worker, hooks, 9 endpoints, v2.2.0) ✅
170 — Planification de tâches automatiques (cron) Non livré ⚪ #170
171 — Audit des accès Partiel : backend/audit.py + /api/admin/audit + dashboard admin #71 existent ; historique par fichier, filtres avancés et export CSV manquants ⚪ #171
172 — Chiffrement/déchiffrement de fichiers Non livré (AES-GCM interne réservé aux tokens) ⚪ #172
173 — Vues personnalisées (Kanban, Calendrier) Non livré ⚪ #173
174 — Optimisation mobile Base largement livrée (#69 éditeur mobile, #83 ruban mobile, #114 config responsive 44 px) ; reste un audit du solde ⚪ #178
175 — Chat intégré Livré le 2026-10-08 (SSE, panneau latéral, historique, toast) ✅ #169
176 — Thèmes dynamiques (règles heure/date) Base livrée (#65 thèmes + import/export) ; règles automatiques manquantes ⚪ #174
177 — Export formats propriétaires (OneNote, Evernote) Base livrée (#66 HTML/MD bundle/ePub + PDF #74) ; formats tiers manquants ⚪ #175
178 — Webhooks pour événements Déjà livrée (#9 — backend/webhooks.py, événements + secrets + validation d'URL SSRF-safe) ✅
179 — Gestion fine des permissions Non livré (ACLs par vault/dossier racine seulement) ⚪ #176
180 — Historique des révisions visuel Partiel : gestion des backups avec diff livrée (#40-46, outil IA diff_backup) ; UI côte à côte manquante ⚪ #177

161. Favoris — répertoires et liens de vault (menu contextuel)

  • Effort : 0,5-1 jour | Impact : 🟡 | Ouvert : 2026-10-04 | Statut : ⚪ non commencé
  • Description : le marque-page actuel ne couvre que les fichiers ; ajouter les répertoires aux favoris (proposition « liens de répertoires », liste v1.2 Ph.1).
  • Sous-tâches :
    • Étendre le modèle de favoris aux répertoires (vérification d'accès backend via _resolve_safe_path(), permissions)
    • Entrée « Ajouter aux favoris » dans le menu contextuel de l'arbre et de la page de navigation (#158-A5)
    • Section « Favoris » dans la sidebar (répertoires + fichiers)
    • i18n FR/EN, tests (unit + E2E si UI), fiche docs/features/

162. Recherches fréquentes — fréquence d'utilisation & rappels

  • Effort : 1-2 jours | Impact : 🟢 | Ouvert : 2026-10-04 | Statut : ⚪ non commencé
  • Cadrage : la sauvegarde des recherches existe déjà (backend/saved_searches.py, bouton « Sauver » de #158). Cet item n'ouvre que l'incrément manquant de la liste v1.2 Ph.1.
  • Sous-tâches :
    • Compteur d'utilisation par recherche sauvegardée (horodatage + fréquence)
    • Section dédiée « Recherches fréquentes » (page de résultats + sidebar) et épinglage
    • Rappel optionnel (« Vous avez souvent cherché X ») via notifications #67, interruptible en Configuration
    • i18n FR/EN + tests

163. Recherche dans la page — éditeur Forge

  • Effort : 0,5-1 jour | Impact : 🟡 | Ouvert : 2026-10-04 | Statut : ⚪ non commencé
  • Cadrage : FindInPageManager (Ctrl+F, surbrillance, navigation ↑/↓, casse / mot entier / regex) est livré pour la vue lecture ; le tableur a sa propre recherche (#153-A13). Reste à raccorder la recherche à l'éditeur Forge et à l'exposer en commande /.
  • Sous-tâches :
    • Raccorder FindInPageManager à Forge (textarea et CodeMirror) : surbrillance dans le contenu édité, navigation avec boucle, conservation du curseur
    • Commande /recherche-dans-page (mécanisme de commandes #81)
    • Non-régression des raccourcis existants (Ctrl+F vs recherche globale, Échap) ; i18n ; tests JSDOM + E2E

164. Suggestions contextuelles dans l'éditeur (historique & préférences)

  • Effort : 3-5 jours | Impact : 🟢 | Ouvert : 2026-10-04 | Statut : ⚪ non commencé
  • Cadrage : l'auto-complétion contextuelle (Mermaid, code, Markdown, wikilinks, frontmatter) est déjà livrée (frontend/js/autocomplete.js) — la proposition v1.2 Ph.2 « Auto-complétion intelligente » est couverte. Cet item n'ouvre que les suggestions apprises du contexte utilisateur.
  • Sous-tâches :
    • Mesure locale des snippets les plus utilisés par l'utilisateur (fréquence, sans cloud)
    • Suggestions basées sur l'historique de modification (termes récurrents, patterns du type « souvent inséré après … ») — option locale, IA légère si disponible
    • Bascule on/off en Configuration ; intégration à la complétion existante
    • i18n FR/EN + tests

⚪ Évolutions agent IA (liste v1.2 « Phase 4 », IDs ObsiGate #165 → #178)

ID Fonctionnalité Effort Impact Dépendances / socle à étendre
165 Synchronisation automatique des vaults avec Git (add/commit/push/pull, résolution de conflits, auth SSH/token, option planification X heures) 4-6 j 🟡 subprocess/gitpython ; UI dans Configuration (#160) ; distinct des outils git_* #92 (IA, Gitea/GitHub)
166 Détection & fusion de doublons (score de similarité, liste des paires potentielles, outil de fusion) — ✅ livré le 2026-10-04 (fiche) 3-4 j 🟢 embeddings/TF-IDF #70 ; jamais de fusion sans confirmation explicite (+ backup préalable)
167 Connexions tierces — Google Drive & Notion (import/export, OAuth2, respect des quotas) 5-7 j 🟡 page « sources connectées » #103 ; rate-limit existant
168 Notifications externes — canaux Slack/Discord (webhooks) et Email (SMTP) + choix des déclencheurs — ✅ livré le 2026-10-04 (fiche ; périmètre : Discord, Telegram, SMTP, webhook générique — Slack via webhook générique) 3-4 j 🟢 backend/webhooks.py #9 ; Push API #67
169 Chat intégré par fichier (panneau latéral, historique, notifications de nouveaux messages) — ✅ livré le 2026-10-08 (fiche ; transport SSE #62, pas de 2ᵉ WebSocket) 3-4 j 🟢 transport SSE #62
170 Planification de tâches automatiques (type cron ; actions = outils existants create_file/append_to_file ; notifications d'échec) — ✅ livré le 2026-10-04 (fiche ; tick asyncio 60 s, API + outils, sans UI dédiée) 3-4 j 🟢 scheduler backend (APScheduler ou asyncio) ; UI de création de tâches
171 Audit des accès — extension : historique lecture/édition par fichier, filtres (utilisateur/fichier/date), export CSV 2-3 j 🟡 backend/audit.py + /api/admin/audit (#71)
172 Chiffrement/déchiffrement de fichiers sensibles (AES-256-GCM, gestion de clés, confirmation) 3-4 j 🟡 backup automatique préalable ; clés hors dépôt (jamais de secret committé)
173 Vues personnalisées Kanban & Calendrier (glisser-déposer, colonnes/date par tags & métadonnées) 5-6 j 🟢 facettes/tags #157-#158 ; store JSON par utilisateur (pattern data/*.json)
174 Thèmes dynamiques (règles heure/date, ex. mode sombre 18h-8h, règles personnalisables) 2-3 j 🟢 thèmes #65 ; préférence persistée (candidate à la sync #73)
175 Export vers formats propriétaires (OneNote, Evernote) avec conservation des métadonnées (tags, liens, images) 3-4 j 🟢 export.py #66 (HTML/MD bundle/ePub) + PDF #74
176 Permissions fines par fichier/dossier (utilisateur/groupe + actions, héritage, journal des changements) 4-5 j 🟡 ACLs vaults/dossiers existantes ; passerelle obligatoire par _resolve_safe_path()
177 Historique des révisions visuel (diff côte à côte, surlignage ajouts/suppressions, navigation Précédent/Suivant) 3-4 j 🟢 backups + diff #40-46 (diff_backup) ; difflib backend
178 Optimisation mobile — solde (audit cibles tactiles ≥ 44 px, lazy-loading images/médias, raccourcis clavier virtuel) 4-5 j 🟡 base livrée #69/#83/#114 ; lazy-loading déjà partiel (#153-A9)
  • Critères d'acceptation transverses (liste v1.2 harmonisée avec la DoD du dépôt) : test desktop et mobile ; documentation utilisateur FR/EN dans docs/GUIDES/ (l'appel « Guide_MCP_ObsiGate.md » de la liste source est ramené à la cartographie documentaire du dépôt) ; backup automatique avant toute modification destructive ; i18n FR/EN systématique ; passage de l'ID à « en cours » avant codage (AGENTS.md, « Avant de commencer »).

✅ Complété — index

Détail complet dans docs/archive/COMPLETED_v1-v2.md et docs/features/. Cette table est la seule source de navigation ; ne pas re-détailler les items livrés ici.

# Domaine / fonctionnalité Version Détails
152 Viewer XLSX — affichage multi-feuilles, édition des cellules, téléchargement 2.27.0 archive
154 Tableur — Refonte UI/UX (ruban groupé, onglets permanents, badges d'état, inspecteur droit, undo/redo) 2.40.0→2.43.1 features/xlsx-ui-redesign.md
155 Tableur — Menu contextuel (clic droit / appui long) & sélection type Excel 2.44.0 features/xlsx-context-menu.md
156 Tableur — Complétude éditeur : presse-papiers/clavier (A5-A7), mise en forme (A8), décision calcul (A9), undo unifié (A10), export + recherche multi-feuilles (A11), concurrence optimiste (A12), cache méta (A13), outils IA .xlsm/.csv (A14) + BUG-096 → BUG-099 2.45.0 features/xlsx-editor-completeness.md
179 Tableur — icônes des menus & boutons, fermeture au focus, polish mobile 2.53.0 features/xlsx-menus-179.md
180 Tableur — redimensionnement au curseur, grille thémée, menu Fichier, barre épinglée 2.54.0 features/xlsx-sheetbar-180.md
181 Tableur — modèle de saisie Google Sheets (sélection ≠ édition) & inventaire des écarts 2.54.0 features/xlsx-sheet-input-181.md
182 Tableur — désélection fiable, contours non empilés, couleurs sur une plage 2.54.0 features/xlsx-sheet-input-181.md
183 Tableur — panneau de couleurs façon Google Sheets (texte et fond) 2.54.0 features/xlsx-sheet-input-181.md
184 Tableur — peinture de format complète, multi-lignes/colonnes, grille A → Z × 1000 (croissance par blocs) 2.54.0 features/xlsx-sheet-input-181.md
185 Tableur — barre de menus Google Sheets (10 menus), ruban Sheets, grille unie 2.54.0 features/xlsx-menus-185.md
186 Création d'un fichier Excel (.xlsx) depuis la modale « Créer un fichier » 2.54.0 features/create-file-xlsx-186.md
188 Secrets — détection universelle des clés API & mots de passe, masque cliquable (clic = copie) Unreleased features/secret-mask-188.md
189 Tableur — mise en page mobile : barres repliées par défaut, bascule unique, cibles tactiles 44 px 2.56.0 features/xlsx-mobile-layout-189.md
169 Chat intégré par fichier (panneau latéral, historique, temps réel SSE, toast de notification) 2.57.0 features/file-chat-169.md
190 Chat — suivi du document, chat général en onglet sidebar (pièces jointes, non lus, recherche), onglets au-dessus du filtre 2.58.0 features/file-chat-169.md
191 Chat — suppression de post, messages privés 2 utilisateurs (canaux), boîte d'édition compacte, link preview OG 2.60.0 features/file-chat-169.md
192 Chat — boîte de saisie auto-agrandissante + accusé de réception ✓✓ (retour live SSE, notification de lecture) · BUG-109 (image de tuile de lien) 2.61.0 features/file-chat-169.md
159 Desktop — gestion des vaults & dossiers : retrait par menu contextuel + section Configuration (ajout vault/dossier racine) 2.50.0 features/desktop-tauri.md
160 Desktop — premier lancement professionnel (répertoire %USERPROFILE%\ObsiGate + Prise en main.md) et section Configuration harmonisée 2.51.0 features/desktop-tauri.md
BUG-047 Versionnage — source unique VERSION + bump SemVer automatique au commit (hooks + tag) 2.3.0 DEVELOPMENT_AND_RELEASES.md
90 Barre d'actions du document — regroupement fonctionnel + spacers 2.3.0 archive
89 Drag & drop complet de fichiers/dossiers & intégration Assistant IA 2.3.0 features/drag-and-drop-ai.md
1–8 Fondations (FastAPI, TF-IDF + stemming, watchdog, SPA, sécurité, path traversal, gzip, PWA) 1.0.0→1.4.0 archive
9–20 UX & productivité (share, webhooks, dashboard, conflits, backlinks, redaction, backups, graphe, header, aperçu) 1.5.0→1.6.0 archive
21–22 Architecture (split app.js → 16 modules, validateur imports CI) 1.5.1 archive
23–25 CI/CD & qualité (Gitea Actions, Ruff/Mypy/Bandit/Pip-audit, pytest) 1.6.0 archive
26–29 AI Editor (toolbar, multi-provider, 16 endpoints, auto-save) 1.7.0 archive
30–39 Fonctionnalités avancées (export PDF, palette, mobile, drag & drop, filtres, indexation non-bloquante) 1.8.0→1.9.0 archive
40–46 Gestion des backups (diff, gestionnaire, purge, auto, rétention) 1.9.0 archive
47–57 Mermaid.js (22 templates, live preview, thèmes, zoom, plein écran, pré-processeur Obsidian) 2.0.0 archive
58 Tests E2E Playwright (44 desktop + 12 mobile, CI) 2.0.0 archive
59 Mode hors-ligne PWA complet (IndexedDB, file de synchro, conflits) 2.0.0 archive
63 Internationalisation i18n FR/EN 2.0.0 archive
65 Thèmes personnalisés (light/dark/high-contrast/sepia, import/export) 2.0.0 archive
66 Export multi-formats (HTML, MD bundle, ePub) 2.0.0 archive
71 Tableau de bord administrateur 2.0.0 archive
64 MFA (TOTP + WebAuthn + recovery codes) 2.1.0 archive
74 Support complet des documents PDF 2.1.0 features/pdf.md
75 Éditeur multi-panneaux (Split View) 2.1.0 features/split-view.md
61 Plugins système (sandbox Web Worker, hooks, 9 endpoints) 2.2.0 archive
67 Notifications web — Push API 2.2.0 archive
68 Health check enrichi 2.2.0 archive
72 API publique documentée — OpenAPI 3.1 2.2.0 archive
76 BooksLM — Console AI contextuelle par répertoire 2.2.0 features/bookslm.md
78 Éditeur Excalidraw 2.2.0 features/excalidraw.md
62 Collaboration temps réel — Édition simultanée (Yjs/CRDT, WebSocket, awareness) 2.3.0 features/collaboration.md
79 Assistant IA — Outils (function calling) & serveur MCP 2.3.0 features/ai-tools-mcp.md
80 Assistant IA — Rendu Markdown, liens fichiers/paths & sessions 2.3.0 features/ai-assistant-ux.md
81 Assistant IA — Commandes (@, /), skills, images & capacités des modèles 2.3.0 features/ai-assistant-commands.md
82 Assistant IA — Section « Fournisseur & modèle » compacte (recherche modèle + info capacités, BUG-043) 2.3.0 features/ai-provider-picker.md
69 Éditeur mobile natif — Interface tactile optimisée 2.3.0 features/mobile-editor.md
70 Recherche sémantique — Embeddings vectoriels (hybride TF-IDF + RRF) 2.3.0 features/semantic-search.md
77 Application Desktop native — Tauri 🔵 en cours features/desktop-tauri.md
84 Consolidation & sécurité — revue statique 2026-09-13 (phase 1, BUG-021→034) 2.3.0 archive
83 Barre d'outils d'édition mobile — ruban style Obsidian Android 2.3.0 archive
88 Assistant IA — contexte applicatif (documents ouverts, répertoire, recherche, fichiers récents) & liens de fichiers fiables (BUG-041, BUG-042) 2.3.0 features/ai-app-context.md
91 Assistant IA — Zone de discussion façon Notion : post ancré en haut, fournisseur/modèle discret & barre d'actions 2.3.0 features/ai-assistant-conversation-ux.md
93 Édition inline — « Editer » et « Forge » remplacent la vue lecture (assistant IA qui met le document à jour) 2.3.0 features/editeur-inline.md
94 Assistant IA — Bouton de soumission arrondi + icône renouvelée (arrow-up) 2.4.0 features/ai-assistant-history.md
95 Assistant IA — Historique permanent des conversations (persistance backend) 2.4.0 features/ai-assistant-history.md
96 Assistant IA — Accès rapide à l'historique depuis la sidebar de navigation 2.4.0 features/ai-assistant-history.md
97 Assistant IA — Panneau « + » extensible (fichiers, Deep Research, contextes, skills…) 2.4.0 features/ai-assistant-history.md
98 Assistant IA — Filtre de recherche dans la sidebar « Historique IA » 2.5.0 features/ai-assistant-history.md
99 Sidebar — Filtrage des vues « Récents » et « Sauvegardes » 2.6.0 features/sidebar-filters.md
100 Assistant IA — Deep Research en pastille (au lieu du texte injecté) 2.6.0 features/ai-assistant-history.md
101 Forge — Assistant IA partagé (bouton AI Panel = assistant, fournisseur/modèle configuré, autocomplétion) + plein écran Forge/Editer 2.8.0 features/forge-assistant.md
BUG-057 Assistant IA — bouton « Ajouter » fonctionnel dans l'éditeur Forge (en plus d'« Editer ») 2.9.0 archive
102 Assistant IA — bouton « Ajouter la section » par bloc de code (insertion du bloc seul) 2.9.0 archive
92 Assistant IA — Écosystème d'outils phase 2 (recherche à clé, cache/retry, Playwright, crawl, Gitea/GitHub, documents XLSX/DOCX/CSV/PDF) 2.10.0 features/ai-tools-roadmap.md
103 Configuration — clés utilisateur des sources connectées & recherche à clé (page Configurations, data/api_keys.json, priorité sur l'env) 2.11.0 features/ai-tools-roadmap.md
104 Configuration — Redesign UI de la section « Clés API IA » : recherche fournisseurs, carte défaut 2 colonnes + badges de capacités, cartes dépliables, footer d'actions sticky 2.12.0 features/ai-keys-ui.md
105 Guide d'utilisation — audit de couverture complet, téléchargement Markdown/PDF, guide desktop élargi, section Architecture (Mermaid) + BUG-067 2.13.0 features/guide-coverage-105.md
106 Assistant IA — Actions instantanées contextuelles, catalogue « Toutes les actions » & frontmatter complet 2.14.0 features/ai-quick-actions.md
107 Configuration — Gestion des clés API & MCP : création/révocation de jetons longue durée (1 j, 1 mois, 6 mois, 1 an, sans fin), une seule clé pour l'API REST et le serveur MCP, « dernière utilisation », store data/api_tokens.json sans secret persisté 2.15.0 features/api-mcp-tokens-107.md
86 Optimisation globale des performances (phase 3) — scan différentiel, excalidraw différé, garde-fou replace (inverted index / PDF lazy / caps regex déjà livrés via BUG-033/040/025) 2.16.0 features/perf-phase3-86.md
108 Support complet des images — arborescence, visionneuse (zoom/pan/navigation/miniatures), indexation nom+métadonnées, media_types.py, filtre ext:, SVG sandbox 2.17.0 features/image-support.md
109 Support audio & vidéo — lecteurs HTML5 intégrés, streaming HTTP Range (/api/media), fallback codec/taille 2.18.0 features/media-viewers-109.md
110 Lecteur média persistant « Now Playing » — élément partagé téléporté (inline ⇄ dock), Media Session, mini-vidéo PiP, mobile, reprise 2.19.0 features/media-viewers-109.md
111 Visionneuse d'images — navigation fluide : image ajustée au cadre, navigation en place (cache annuaire + préchargement), pellicule persistante, flèches latérales au survol 2.20.0 features/image-navigation-111.md
112 En-tête allégé & compte en sidebar — version dans le menu Options, retrait utilisateur/déconnexion du header, section compte en bas de la sidebar, pellicule d'images défilable (molette + flèches) 2.21.0 features/header-user-sidebar-112.md
113 Configuration — ordre naturel des sections (Profil 1er, À propos dernier, TOC = page) & avatar utilisateur (import PNG/JPG/WEBP, persistance serveur, cercle sidebar) 2.22.0 features/settings-order-avatar-113.md
114 Configuration — refonte mobile-responsive (modale plein écran 100dvh, sommaire en drawer coulissant, cibles tactiles ≥ 44 px, inputs 16 px anti-zoom, sauvegarde sticky, MFA 1 colonne, purge i18n/HTML) 2.23.0 features/settings-mobile-114.md
BUG-078 Fichiers de code — coloration syntaxique restaurée (feuilles highlight.js basculées sur le mode de thème et non la clé) 2.25.0 features/viewer-toolbar-highlight-avatars.md
115 Viewer — barre d'outils de lecture épinglée au défilement 2.25.0 features/viewer-toolbar-highlight-avatars.md
117 Configuration — avatars prédéfinis dans le profil utilisateur (12 images) 2.25.0 features/viewer-toolbar-highlight-avatars.md
85 Refonte architecturale — découpage du monolithe (14 routers, main.py 4 827 → ~750 lignes), stores JSON verrouillés, rate-limit SQLite optionnel 2.27.2→2.27.13 features/archi-refonte-85.md
157 Recherche — facette « Extensions » dans les résultats (3ᵉ filtre avec Vaults et Tags) + panneau repliable 2.46.0→2.47.0 archive
158 Navigation — clic répertoire → onglet de navigation (sous-répertoires, facettes Vaults/Tags/Extensions, tri Pertinence/Date, Sauver), onglet Accueil, menus contextuels + retour Home complet (BUG-100 → BUG-102) 2.48.0→2.49.0 features/navigation-tab-158.md
166 Assistant IA — détection & fusion de doublons (score déterministe, paires candidates, fusion backup + confirmation) Unreleased features/agent-phase4-166-168-170.md
168 Assistant IA — notifications externes Discord / Telegram / SMTP / webhook (déclencheurs, secrets hors config, SSRF-safe) Unreleased features/agent-phase4-166-168-170.md
170 Assistant IA — tâches planifiées type cron (create/append/notify, interval/daily/once, tick 60 s, échec notifié) Unreleased features/agent-phase4-166-168-170.md
BUG-119 Panneau Spark — « mode console » bloqué par la CSP (frame-src sans l'origine du service d'agents) 2.77.1 ISSUES_TODOLIST.md
BUG-120 Menu inter-apps — les URL sœurs (window.DRACO_URLS) dérivent l'environnement de l'hôte de l'agent (-dev en dev), explicite prioritaire, Gitea inchangée (suite de #223) 2.78.2 ISSUES_TODOLIST.md
225 Panneau Spark — version du service d'agents visible en mode sidebar (pied du panneau, lue en direct via GET /healthz) 2.79.0 features/fusion-panneau-version-agent-225.md

📊 Résumé des efforts

Priorité Items Effort total estimé
✅ Complété #1 → #59, #61–72, #74–76, #78–86, #88–93, #94–100, #102–115, #117, #92 ~141 jours réalisés
🔵 Finitions #77 Desktop : 6 tests E2E manuels (protocole) — signature Windows non retenue (décision 2026-09-26) ~0,5-1 jour
⚪ P4 reporté #73 Sync — reporté (décision 2026-09-26), hors chemin critique ; périmètre élargi 2026-10-04 (favoris #161 + préférences) 6-8 jours si réactivé
⚪ P1/P2 nouvelles (liste v1.2) #161 favoris répertoires · #162 recherches fréquentes · #163 recherche Forge · #164 suggestions contextuelles ~5-9 jours
⚪ Évolutions agent IA (#165 → #178) Git sync, doublons, Drive/Notion, notifications, chat, cron, audit, chiffrement, Kanban, thèmes dynamiques, OneNote/Evernote, permissions, diff visuel, mobile ~45-63 jours si tout activé (à prioriser par tranches)
⚪ P0/P1 prioritaire #87 CI/CD (BUG-035 → BUG-040 corrigés, #86 livré) ~3-5 jours
✅ Terminé #153 Visionneuse & édition XLSX — complétude (A1-A17 toutes livrées, v2.27.0 → v2.39.0) 0 jour restant
✅ Terminé #154 Refonte UI/UX tableur (A1-A5 toutes livrées, v2.40.0 → v2.43.1) 0 jour restant
✅ Terminé #155 Ergonomie tableur — menu contextuel & sélection type Excel 0 jour restant
✅ Terminé #156 Éditeur Excel — complétude — P0-P3 ✅ livrés le 2026-09-30 (BUG-096 → BUG-099, A5-A14) 0 jour restant
Total chemin critique #77 fin + #87 ~4-6 jours

Notes

  • Décisions 2026-09-26 : axe prioritaire = dette & sécurité (#85/#87) ; #73 Sync reporté (P4, hors chemin critique) ; desktop livré non signé + doc SmartScreen.
  • Ajout 2026-09-27 : #153 ouvert à la suite de l'audit de la visionneuse XLSX (limitations, risques de perte de données, périmètre IA/recherche) — détail et critères dans features/xlsx-viewer.md.
  • Ajout 2026-09-29 : #154 ouvert — refonte UI/UX de la visionneuse/éditeur XLSX (audit UX, architecture cible, plan par lots) dans features/xlsx-ui-redesign.md ; livré en 5 lots (ruban groupé, onglets permanents + « + », badges d'état, tokens de grille, dialogues thémés, inspecteur droit, undo/redo, extraction frontend/js/xlsx/*).
  • Ajout 2026-09-29 : #155 livré — menu contextuel (clic droit / appui long) et sélection type Excel sur la grille (features/xlsx-context-menu.md) ; au passage BUG-094 corrigé (feuille vide/nouvelle désormais éditable, quadrillage vierge 20×8).
  • Clôture 2026-09-30 : #156 livré (P0 → P3) — A8 mise en forme en écriture (bouton Mise en forme : gras/italique/souligné, alignements, couleurs, formats de nombre, fusions, volets figés, largeur/hauteur — via PUT …/xlsx/style), A9 décision « pas de moteur de formule, annoncée dans l'UI », A10 undo/redo unifié conservé au re-rendu, A11 export de la sélection / Markdown / HTML / impression + recherche sur toutes les feuilles, A12 concurrence optimiste (If-Match, 409 réparable), A13 cache des métadonnées par mtime, A14 outils IA .xlsm/.csv + search_workbook/analyze_range/edit_xlsx_structure — détail dans features/xlsx-editor-completeness.md.
  • Ajout 2026-09-29 : #156 P1 livré — A5 presse-papiers de plage (copier/couper/coller un bloc, presse-papiers interne + système, entrées du menu contextuel, remplissage multi-cellules), A6 clavier complet (Ctrl+S/Ctrl+A/Suppr/F2/Ctrl+Home|End/PgUp|PgDn/Ctrl+flèches/Maj+Entrée) et A7 zone Nom éditable + aide à la saisie ; restent P2 (mise en forme, calcul, undo unifié) et P3 (sortie, concurrence optimiste, performances, outils IA).
  • Ajout 2026-09-29 : #156 ouvert — audit de complétude de l'éditeur Excel : 4 défauts recensés (BUG-096 enregistrement .csv, BUG-097 lazy-load .xlsm, BUG-098 délimiteur CSV, BUG-099 sonde de perte), corrigés le jour même (P0 ✅) avec tests de non-régression ; restent P1-P3 (presse-papiers, clavier, mise en forme, calcul, export, concurrence optimiste) puis presse-papiers de plage, clavier complet, mise en forme en écriture, calcul, undo/redo unifié, export/impression, concurrence optimiste — détail dans features/xlsx-editor-completeness.md.
  • Ajout 2026-10-04 : intégration de la liste « Roadmap – Développement des Fonctionnalités » v1.2 (phases 1-3 + suggestions agent IA). Évaluation croisée avec le code : 7 propositions déjà livrées (auto-complétion autocomplete.js, résumés/traduction/ton #106, édition collaborative #62, scripts/plugins #61, webhooks #9, recherche dans la page en vue lecture) → pas d'ID ; périmètre manquant ouvert en backlog #161 → #178 avec table de correspondance en tête de la nouvelle section ; sync favoris/préférences fusionnée dans #73 (reporté P4). Les numéros 161-180 de la liste source ne sont pas repris tels quels (règle dépôt : ID jamais attribué au déjà-fait) ; la correspondance figure item par item.
  • Clôture #85 (v2.27.13) : monolithe découpé (T1→T9), stores verrouillés + rate-limit SQLite (T10), fiche docs/features/archi-refonte-85.md.
  • Les items P3/P4 ne sont pas ordonnés par priorité interne — à raffiner selon les retours utilisateurs.
  • L'effort inclut le développement + tests unitaires + intégration CI, mais pas la documentation utilisateur.
  • Les items marqués 🟢 (nice-to-have) sont de bons candidats pour des contributions externes.
  • Maintenance de ce fichier : quand un item passe à ✅, déplacer son détail vers docs/features/<slug>.md (grosse feature) ou docs/archive/COMPLETED_v1-v2.md (item court), ajouter une ligne dans l'index « Complété », et consigner la version dans le CHANGELOG.