Files
IdeA/.ideai/memory/ticket28-firstrun-detect-hang-scoping.md
Blomios ffc458e477 docs(memory): notes projet du sprint UI rework et des tickets #7/#14/#16/#17/#18/#25/#28
Capitalise les notes durables produites pendant le sprint UI rework et les
tickets livrés depuis. Commit séparé du code : `.ideai/memory/` est le store
durable versionné, il ne doit jamais être mélangé aux commits de feature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 08:38:16 +02:00

3.3 KiB

name, description, metadata
name description metadata
ticket28-firstrun-detect-hang-scoping Cadrage hexagonal du bug bloquant first-run (#28) — panic block_on imbriqué dans detect + découplage busy/détection, contrats et point de vérité QA.
type
reference

Bug high #28 (build 0.3.0 / develop 3c6cd04) : au first-run, « Save and continue » ET « Detect installed CLIs » restent grisés → wizard impossible à terminer.

Cause racine unique (bloquante) — CONFIRMÉE source : AgentRuntime::detect est resté fn synchrone (domain/src/ports.rs:754, impl infrastructure/src/runtime/mod.rs:182) alors que le trait est déjà #[async_trait]. L'impl bridge le spawner async via futures_block_on/block_on (mod.rs:228-237), appelé DANS la commande async Tauri detect_profilesDetectProfiles::execute (async) → detect() sync sur la même task → tokio panic « Cannot start a runtime from within a runtime ». Un panic dans une commande async Tauri = aucune réponse IPC → promesse invoke jamais résolue/rejetée → le try/catch interne (useFirstRun.ts:79-90, n'attrape que les rejets) ne l'attrape pas → finally jamais atteint → busy figé true → boutons disabled: vm.busy grisés à vie. Se déclenche au 1er profil sondé, toute machine. Déclencheur nouveau de #14 : auto-détection à l'ouverture dans reload.

Cause secondaire (NON bloquante) : profil ollama-openai-compatible (command openai-compatible, detect:None) → fallback openai-compatible --version (binaire absent) → available:false erroné (spawn échoue vite, pas de hang). Endpoint HTTP sondé comme un CLI = catégorie-fausse. base_url dispo via HttpChatConfig (http://localhost:11434/v1). Précédent réutilisable : infrastructure/src/store/embedder.rs:401 detect_ollama (reqwest, timeout 800ms, feature vector-http).

Fix figé — Backend (DevBackend) : B1 promouvoir detect en async fn (supprimer futures_block_on entièrement), maj DetectProfiles::execute (.await) + commande. B2 tokio::time::timeout borné par probe. B3 brancher endpoint-kind (chat_http / StructuredAdapter::OpenAiCompatible) → probe HTTP best-effort borné de base_url (jamais d'erreur dure) ; CLI-kind = detection_spec INCHANGÉ (zéro-régression Claude/Codex). Aucun nouveau port/adapter.

Fix figé — Frontend (DevFrontend) : F1 découpler busy de la détection : busy n'entoure que firstRunState(), relâché dès rendu des lignes. Auto-détection = étape détachée non bloquante suivie par un flag distinct detecting (ne grise pas Save), avec timeout UI (~3s). Invariant : retour de busy à false ne dépend JAMAIS de detectProfiles.

Contrats : port AgentRuntime::detect sync→async (validé Architecture). DTO detect_profiles INCHANGÉ (available:bool). Catalogue ollama : detect reste None, détection décidée par nature endpoint.

Point de vérité QA : Backend = test #[tokio::test] multi-thread sur DetectProfiles::execute (échoue au panic sur code actuel, passe après B1) + endpoint sans spawn CLI + CLI Claude/Codex inchangé. Frontend = RTL avec mock detectProfiles jamais résolu → Save+Detect actifs dès firstRunState. Live = first-run machine sans Claude/Codex, Ollama coché, boutons actifs, Save termine (rebuild AppImage obligatoire). F1 seul débloque déjà ; B1 supprime la cause racine ; les deux requis pour vert.