# CARTO CODE NON BRANCHÉ — carte de référence wiring (2026-07-02) > **But** : carte « existing-first » de référence. AVANT tout chantier/bench/proposition, > consulter ce doc pour savoir si une brique existe et si elle est **réellement branchée au > runtime**. Recadrage Dom 02/07 : « vérifier ce qui existe et non branché, c'est le BABA ». > > **Méthode** : verdict prouvé par chaîne d'imports depuis un point d'entrée actif > (fichier:ligne), imports lazy inclus, gates de config citées. Jamais de conclusion sur un > grep seul. Sources fusionnées : agent Claude « intelligence » + carto Qwen (volet 1 > détection) + `AUDIT_CODE_MORT_2026-07-02.md` (Qwen) + vérifs ponctuelles Claude. > > **Légende** : **WIRED** (chaîne prouvée) · **GATED** (branché mais derrière flag, défaut > cité) · **ORPHELIN** (0 appelant runtime, recherche exhaustive) · **INCERTAIN** (non tranché, > raison donnée). > > **Points d'entrée actifs runtime** : `api_stream.py` (streaming 5005, `rpa-streaming`) · > `run_worker.py` (worker VLM 5099) · VWB `app.py` (5002) · `web_dashboard/app.py` (5001) · > `agent_chat/app.py` (5004) · `server/api_upload.py` (8000). --- ## 0. Résumé exécutif — les découvertes qui changent une décision 1. **Self-healing = façade morte, malgré doc « wired ».** Chaîne d'import réelle (VWB → `core/healing`), routes REST répondent, MAIS déclenchement **impossible** : le code teste `hasattr(healing_integration, 'enable_healing')` et cette méthode **n'existe nulle part** (`execution_integration.py:421`). `handle_execution_failure` = 0 appelant d'exécution. Preuve d'inertie : `logs/healing/recovery.log` = **0 octet, mtime déc. 2025**. Le pont manquant tient à **une méthode**, pas un module. → `PLAN_MENAGE_CODE_MORT` le classait « wired — NE PAS TOUCHER » : **doc fausse**. 2. **`core/navigation` (commit du matin `f9a053132`) = write-only.** Le handler résout le login et écrit `navigate_login_coords` dans `replay_state["variables"]`, mais **aucun consommateur** : le compilateur `_edge_to_normalized_actions` n'a pas de branche `navigate` et produit des coords littérales, jamais de templates `{{navigate_login_coords.x_pct}}`. Détail : `docs/DESIGN_NAVIGATE_COORDS_CONSUMPTION_2026-07-02.md`. Décision D1 en attente Dom. 3. **AutonomousPlanner : coût sans usage.** Instancié au boot d'`agent_chat` (charge LLM + OWL detector via `autonomous_planner.py:36`), mais **aucune route n'appelle une méthode de planification** — seuls des setters. Type même du « code écrit jamais invoqué ». 4. **PaddleOCR installé, jamais importé.** `paddleocr 3.4.0` + `paddlepaddle 3.3.1` (CPU) présents dans `.venv`, **0 `import paddle` dans le code**, 0 requirements, 0 deploy. Piste bench en cours (Qwen), pas un composant actif. 5. **YOLO cascade de résolution = mort.** `_resolve_by_yolo` défini (`resolve_engine.py:458`) + importé (`api_stream.py:6114`) mais **jamais appelé** ; aucune branche `yolo` dans la cascade compilée. ⚠ À NE PAS confondre avec le YOLO de `som_engine` (OmniParser SoM), lui **WIRED**. 6. **`server/api_core.py`** : blueprint Flask complet (capture/detect/embed/faiss) **jamais enregistré** — orphelin absent du plan ménage. 7. **Nos propres cartos avaient 4 erreurs** (cf. §4). Re-prouver était justifié. --- ## 1. Chaîne détection / grounding / résolution | Module | Verdict | Preuve (fichier:ligne) | Remarque | |--------|---------|------------------------|----------| | `core/detection/som_engine.py` | **WIRED** | resolve_engine.py:1192 (replay) · stream_processor.py:643 (recording) · api_stream.py:1958 (temps réel) | 3 chemins indépendants, singleton thread-safe. Tire YOLO weights direct. | | `core/detection/omniparser_adapter.py` | **B-DORMANT** (branché lazy, fallback vide) | phase25_analyzer.py:388 · resolve_engine.py:437 · désactivé côté VWB (`_omniparser_available=False`) | Import lazy try/except, singleton. 7 zones cartographiées (§ audit Qwen). | | `core/detection/owl_detector.py` | **WIRED (via AutonomousPlanner) — mais planner inerte** | autonomous_planner.py:36 | Chargé au boot agent_chat pour rien (cf. §0.3). 4 méthodes internes C-MORT. | | `core/detection/ollama_client.py` | **WIRED partiel** | `classify_element_complete()` actif ; 5 vieilles méthodes + `check_ollama_available()` standalone = C-MORT | Duplicat VWB (D2). | | `_resolve_by_yolo` (resolve_engine.py:458) | **ORPHELIN** | importé api_stream.py:6114, **0 appel réel**, 0 branche cascade | ≠ YOLO de som_engine (wired). | | `core/grounding/bbox_parser.py` | **WIRED** | resolve_engine.py:29 | | | `core/grounding/smart_resize.py` | **ORPHELIN (C-MORT)** | 0 appelant prod, DETTE-007 triple impl (2 autres existent) | | | `core/grounding/server.py` | **WIRED** | service HTTP Flask port 8200 standalone | Upgrade C→A (Qwen). | | `visual_workflow_builder/.../api/ui_detection.py` | **WIRED** | VWB app.py:310 (blueprint) · fast_detector.py:117 | UI-DETR-1 du recording, modèle rfdetr RFDETRMedium, 5 endpoints `/api/ui-detection`. | | `core/semantic/phase25_analyzer.py` | **WIRED** | api_stream.py:7690 (route `lea_competence_persist:7435`) | | | `core/extraction/{field_extractor,vlm_client,role_mapper}` | **WIRED-transitif** | field_extractor ← input_handler.py:121/504/722 (lazy) · vlm_client+role_mapper ← core/navigation/__init__.py:69, action_resolver.py:109 | Le plan ménage 23/06 (« 4/5 morts ») précède navigation. | | `core/llm/` (ocr_extractor, extract_grid) | **WIRED** | api_stream.py:1766 · replay_engine.py:2115-2403 · resolve_engine.py:2597 | | | `core/navigation/` | **WIRED (boot) / write-only (fonctionnel)** | api_stream.py:440 top-level NON gardé · handler résout mais 0 consommateur coords | cf. §0.2. ⚠ import non gardé → si casse, 5005 ne boote pas (garde-fou test_navigate_wiring.py). | | PaddleOCR (venv) | **ORPHELIN** | 0 import, 0 requirements, 0 deploy | cf. §0.4. | --- ## 2. Modules « intelligence » | Module | Verdict | Preuve (fichier:ligne) | Remarque | |--------|---------|------------------------|----------| | `core/healing/` | **ORPHELIN de fait** (importé, indéclenchable) | chaîne VWB app.py:217 → api/self_healing.py → services/self_healing_integration.py, MAIS `enable_healing` inexistant (execution_integration.py:421) ; `handle_execution_failure` 0 appelant | cf. §0.1. `logs/healing/recovery.log` vide depuis déc. 2025. | | `core/coaching/` | **WIRED** | VWB app.py:284-285 (blueprint) → api/coaching_sessions.py:17,22 · exec : execution_integration.py:869 · front WebSocket | REST blueprint peut-être non consommé par l'UI (front = socket.io). | | `core/cognition/working_memory` | **WIRED-transitif** | observe_reason_act.py:30,506 · ORALoop ← VWB execute.py:1542,2075 | Les 4 autres sous-modules cognition = MORTS (tests only). | | `core/learning/` (4/5) | **WIRED** | target_memory_store: resolve_engine.py:1865 + api_stream.py:5132 · continuous_learner: stream_processor.py:3147 · learning_manager: VWB learning_integration.py:36, api/workflows.py:696 · feedback_processor: execution_loop.py:317 | `versioned_store` ORPHELIN. `record_observation` = **0 appelant** (learning_manager.py:54). | | `core/execution/` | **WIRED massif** | observe_reason_act ← execute.py:1542 · input_handler ← execute.py:69 · dag_executor+llm_actions ← dag_execute.py:33,40 · action_executor/target_resolver/error_handler/execution_loop ← agent_chat app.py:328-340 · +transitifs | Morts : spatial_index, target_memory, workflow_runner (⚠ encore exporté par `__init__.py:10`). | | `core/auth/` | **GATED — défaut OFF** | api_stream.py:278-286 : import lazy SSI `RPA_AUTH_VAULT_PATH` **et** `RPA_AUTH_VAULT_PASSWORD` définis (absents par défaut). Seul lieu qui les définit : CI `.gitea/workflows/tests.yml:35` | Vault inactif en prod. TOTP dans la même chaîne gated. | | `core/federation/` | **WIRED manuel, write-only** | routes actives non gated : GET learning-pack/export api_stream.py:6431 · POST import :6476 | `GlobalFAISSIndex.search()` = **0 appelant**. Aucun auto-déclenchement. | | `core/gpu/` (2/6) | **WIRED** | device_policy ← resolve_engine.py:1750 (hot-path) · gpu_resource_manager ← agent_chat app.py:53,266 | clip_manager, ollama_manager, vram_monitor, preflight = morts. | | `core/embedding/` | **WIRED (lazy)** | construction CLIP/FAISS ← stream_processor.py:2560 `_ensure_initialized` (appelé process_screenshot:2804 + finalize_session:2969) · lecture web_dashboard app.py:309+ | Se déclenche au 1er screenshot / finalisation, pas au boot. | | `agent_chat/autonomous_planner` | **INSTANCIÉ mais INERTE** | import app.py:48, instancié :358, mais seuls appels = setters :362,367 ; 0 route de planification | cf. §0.3. Tire owl_detector pour rien. | | `agent_chat/urgences_orchestrator` | **WIRED** | import lazy app.py:2740, routes `/api/urgences/*` | | | `agent_chat/gesture_catalog` | **WIRED ×2** | agent_chat app.py:377,955 · **api_stream.py:269,3598** (hot-path replay `optimize_replay_actions`) | Pas seulement le chat. | | `core/validation/` | **GATED — défaut OFF** | flag `RPA_VALIDATOR_V2_ENABLED` défaut OFF (api_stream.py:91), consommé report_action_result:4924 | | **WIRED confirmés (survol)** : capture, models, competences, corrections, data, graph, knowledge, monitoring, persistence, pipeline, system, workflow, visual, config.py, anonymisation (PII), matching/training (transitifs). **ORPHELINS confirmés** : variants, precision, supervision, interfaces (0 importeur non-test) · `core/evaluation/` (consommé seulement par `tools/lea_bench*.py`, outillage CLI) · `server/api_core.py` (blueprint jamais enregistré). --- ## 3. Zones GATED (flags + défaut) — activation supervisée | Flag | Défaut | Effet si ON | Preuve | |------|--------|-------------|--------| | `RPA_AUTH_VAULT_PATH` + `RPA_AUTH_VAULT_PASSWORD` | absents | active `core/auth` (vault Fernet + TOTP) | api_stream.py:278-286 | | `RPA_VALIDATOR_V2_ENABLED` | OFF | active validation V2 (report_action_result) | api_stream.py:91 | | `RPA_R1_AUTO_IMPORT` | OFF | active import auto core→DB VWB (R1) | api_stream.py:~4480 (revue en cours) | | `RPA_AUTO_UPDATE_ENABLED` | OFF | MAJ silencieuse client (DETTE-022) | agent_v1/config.py:103 | | `RPA_GROUNDING_ENGINE=qwen3vl_vllm` | legacy Qwen2.5-VL | grounder Qwen3-VL (override DGX runtime) | resolve_engine.py:1001-1007 | --- ## 4. Divergences corrigées avec les docs existants 1. **`core/healing` : doc `PLAN_MENAGE` = « wired, NE PAS TOUCHER » → FAUX.** Indéclenchable (`enable_healing` fantôme, log vide déc. 2025). Le pont est à une méthode près. 2. **`feedback_processor` : CARTO 16/06 = ORPHELIN → FAUX.** Instancié à chaque ExecutionLoop (execution_loop.py:317). 3. **`core/cognition` : CARTO 16/06 = tout orphelin → FAUX pour working_memory** (vivant au runtime VWB via observe_reason_act). 4. **`core/extraction` : plan ménage « 4/5 morts » → périmé.** vlm_client + role_mapper branchés via `core/navigation` (postérieur au doc). Upgrades C→A/B confirmés par Qwen : autonomous_planner (C→A, mais inerte cf. §0.3), seeclick_adapter (C→B), grounding/server.py (C→A), get_grounding_profile (C→A). --- ## 5. Code mort candidat suppression → voir `AUDIT_CODE_MORT_2026-07-02.md` Résumé : **8 C-MORT** (~843 lignes, ex. deploy_windows.py, smart_resize.py, 7 config classes dépréciées, agent_chat 410 endpoints) · **5 B-ORPHELIN** (à conserver, projections) · **4 duplicats** (décision Dom). Suppression = GO Dom par lot, worktree isolé + tests après chaque lot. ⚠ Prudence renforcée vu les 4 erreurs de doc du §4 : re-prouver chaque item avant suppression. --- ## 6. Cascade de résolution UI (`resolve_engine.py`) — ordre RÉEL prouvé Point d'entrée unique au replay : le client Léa (`executor.py:2847`, **`strict_mode=True` hardcodé** :2870) → route `resolve_target` (`api_stream.py:6131`) → `_resolve_target_sync` (`resolve_engine.py:1804`). `replay_engine.py` ne résout pas (il construit le target_spec). **Ordre réel au replay (mode strict VLM-first, `resolve_engine.py:1957`)** : ``` 0. Mémoire persistante (replay_memory.memory_lookup:1869) — hit → skip toute la cascade 0c. dialog_button → OCR seul (1920-1952) ── strict VLM-first (1957) ── S0a. Grounding VLM (_resolve_by_grounding:2019) si by_text_source ∈ {ocr, vlm} S0b. Template matching icônes (2057) sinon S0.5 OCR direct (_resolve_by_ocr_text:2105) si by_text S1. VLM Quick Find (_vlm_quick_find:2158) S1.5 SoM + VLM (_resolve_by_som:2207) S2. Template matching fallback (2238) S3. STOP replay resolved=False (2283) ``` Note : grounding VLM (S0a) et VLM Quick Find (S1) sont **deux appels VLM distincts**. **Statut resolvers** : `_resolve_by_grounding`, `_resolve_by_template_matching`, `_resolve_by_ocr_text`, `_vlm_quick_find`, `_resolve_by_som`, `replay_memory` = **WIRED** (preuves lignes ci-dessus). Grounder Qwen3-VL : bascule dans `_resolve_by_grounding:1006` (flag `RPA_GROUNDING_ENGINE=qwen3vl_vllm`, sinon legacy Qwen2.5-VL) — change modèle/endpoint/ prompt/parser, pas le flux. **3 branches MORTES dans la cascade** : - `_resolve_by_yolo` (:458) — importé api_stream.py:6114, **0 appel réel**. ORPHELIN. - **Vérification CLIP** (:1972-2008) — **dead gate** : lit `target_spec["clip_embedding"]` qui n'est **jamais peuplé** dans tout `agent_v0/` → branche jamais exécutée. - **V4 pré-compilé** (`_resolve_with_precompiled_order:1601`, ordre figé `["ocr","template", "vlm"]`) — **WIRED mais dormant en replay normal** : alimenté uniquement par l'endpoint `/replay/plan` (`execution_plan_runner.py:173`), jamais par le flux VWB→Léa. **Verdict README « OCR→template→YOLO→VLM » = FAUX** : (1) YOLO mort, (2) l'ordre est VLM-first, (3) la séquence `ocr,template,vlm` n'existe que dans le V4 dormant. ## 7. Zones restantes non re-vérifiées (honnêteté) - `core/analytics/` : ~13 sous-modules orphelins non re-vérifiés un par un (conforme doc). - Reste couvert : chaîne détection/grounding/résolution + intelligence = prouvés. **Carto considérée complète sur le périmètre runtime actif.**