# SPECS Phase 2.5 Sémantique — POC RPA Vision v3 **DRAFT specs pour implémentation — pas encore appliqué — alignement avec arbitrage Plato 2026-06-01 18:18** Date : 2026-06-01 Auteur : Claude (agent Plan), arbitrage Plato/Codex Statut : DRAFT — à valider par Dom avant implémentation Référence arbitrage : `docs/coordination/inbox_claude/2026-06-01_1818_codex-to-claude_ADDENDUM-agent-plato-archi-semantique.md` Référence addendum initial Claude : 17:45 (OmniParser systématique dans hot path replay) — **révoqué par Plato** ## Principes d'arbitrage retenus 1. Garder replay/click/OCR existant comme chemin principal (hot path inchangé) 2. Phase 2.5 = post-apprentissage uniquement, jamais en hot path replay 3. Demander à l'humain seulement les ambiguïtés utiles 4. Sémantique = contexte, pas prérequis de chaque clic 5. `ExternalDecisionClient` autour de `t2a_decision`, puis adaptation AIVA 6. OCR critique renforcé par régions annotées + escalade humaine ## Sommaire 1. Périmètre Phase 2.5 MVP 2. Endpoint à créer 3. Identification des écrans distincts 4. Stockage des annotations sémantiques 5. Réutilisation au replay (autopilote / autonome) 6. Compatibilité compétences existantes 7. Garde-fous anti-fragilité OmniParser 8. Coûts perf attendus 9. Tests à prévoir 10. Estimation effort implémentation 11. Hors scope MVP Phase 2.5 --- ## 1. Périmètre Phase 2.5 MVP - **Quand** : déclenchement à la fin de la phase d'observation, après `POST /api/v1/shadow/stop`, **avant** restitution Option C à l'humain. - **Sur quoi** : screenshots clés capturés (1 par écran distinct détecté), **pas tous les frames**. - **Avec quoi** : OmniParser réutilisé (déjà présent, adaptateur fragile mais isolé), encapsulé derrière garde-fou anti-fragilité §7. - **Pour quoi** : produire un payload structuré `{tables[], forms[], buttons[], text_blocks[]}` par écran clé, stocké dans un YAML sémantique séparé du YAML compétence principal. - **Non-objectif** : Phase 2.5 ne touche pas le chemin replay. Elle enrichit uniquement la compétence apprise. ## 2. Endpoint à créer `POST /api/v1/lea/screen/analyze` côté streaming server (port 5005). - **Entrée** : `{session_id: str, screenshot_indexes: int[]}` — index des frames capturées en mode léger pendant l'observation. - **Sortie** : `{screens: [{index, hash, structure: {tables, forms, buttons, text_blocks}}]}`. - **Idempotence** : cache disque sous `data/cache/omniparser//.json`. - **Timeout** : 30s par screenshot. Dépassement → fallback OCR-seul (docTR text_blocks seuls), flag `degraded: true`. - **Erreur OmniParser** (exception, modèle KO) : fallback OCR-seul + log `logs/omniparser_errors.log`. L'endpoint ne renvoie **jamais** 500 — toujours 200 avec flag dégradé. ## 3. Identification des écrans distincts Heuristique de regroupement, exécutée avant l'appel `/api/v1/lea/screen/analyze` : - Calcul `imagehash.phash` pour chaque frame capturée. - Grouping par similarité : Hamming distance ≤ 8 ⇒ même écran logique. - Sélection d'un frame représentatif par groupe (premier dans l'ordre temporel, ou celui avec le plus de détections OCR). - **Limite POC** : maximum **10 écrans distincts par session**. Au-delà, session marquée `too_complex` et l'humain est invité à scinder la compétence en sous-compétences (message explicite dans restitution Option C). ## 4. Stockage des annotations sémantiques Fichier séparé du YAML compétence principal, suffixe `.semantic.yaml`. Chemin : `data/competences/candidate/.semantic.yaml` Structure : ```yaml competence_id: facturation_urgence_simple semantic_version: 1 generated_at: 2026-06-01T18:30:00Z omniparser_version: degraded: false screens: - screen_id: screen_001 phash: "abc123..." representative_frame_index: 42 annotations: - region_id: region_3 bbox: [120, 80, 400, 150] semantic_label: motif_arrivee confidence: human_verified structure: tables: [...] forms: [...] buttons: [...] text_blocks: [...] ``` - Séparation stricte : YAML compétence principal reste lisible et minimal. `.semantic.yaml` est optionnel. - YAML compétence référence le fichier sémantique par clé `semantic_ref: .semantic.yaml` si présent. ## 5. Réutilisation au replay (autopilote / autonome) OmniParser au replay **uniquement** si la compétence référence un `.semantic.yaml` (présence de `semantic_ref`). Algorithme : 1. Au démarrage du replay d'un écran, calcul `phash` du screen courant. 2. Si Hamming distance ≤ 8 avec un `screen_id` connu OU même nombre de tables/buttons/forms structurellement → match, application des annotations. 3. Sinon → divergence : - **Autopilote** : escalade humaine via Option C runtime (« écran inattendu, valider ou annoter »). - **Autonome** : log incident `logs/replay_incidents.log`, **stop** avec code `semantic_mismatch`. Compétences sans `semantic_ref` → on saute totalement cette étape (rétrocompat §6). ## 6. Compatibilité compétences existantes - Compétences sans `.semantic.yaml` ⇒ pas de Phase 2.5 au replay, pas d'OmniParser, **chemin OCR + template + click inchangé**. - Phase 2.5 = **opt-in par compétence** : seule une compétence apprise après l'activation de Phase 2.5 possédera le fichier sémantique. - Aucune migration auto des compétences anciennes. Rétrocompat garantie par l'absence de `semantic_ref`. - Pas de breaking change sur le format YAML compétence principal — seulement une clé optionnelle. ## 7. Garde-fous anti-fragilité OmniParser Adaptateur OmniParser fragile (chemin absolu, dépendances lourdes). Mesures : - **Wrapper try/except global** autour de chaque appel OmniParser, fallback OCR-seul (docTR) systématique en cas d'exception. - **Log dédié** : toute erreur → `logs/omniparser_errors.log` avec stack trace, session_id, frame_index. - **Healthcheck au démarrage Phase 2.5** : appel test sur image bidon. Si échec → bascule auto en mode dégradé OCR-seul, log warning, restitution `degraded: true`. - **Test unitaire obligatoire** : mock OmniParser qui lève exception, vérifier que la chaîne aboutit à un `.semantic.yaml` dégradé valide. - **Isolation chemin absolu** : config OmniParser (chemin modèle, version) centralisée dans `config/omniparser.yaml`, jamais en dur. ## 8. Coûts perf attendus - **Dev (RTX 5070, OmniParser CPU)** : 2 à 5s par screen. Acceptable (principe 5 Dom, hors hot path). - **DGX Spark (cible prod)** : < 500ms par screen. - **Coût session typique** : 10 screens × 2-5s = 20-50s ajoutés à la fin d'une session d'apprentissage sur dev. Tolérable, asynchrone vis-à-vis humain (restitution Option C peut afficher spinner). - Pas d'impact sur replay (hot path) tant que pas de `semantic_ref`. Avec `semantic_ref`, surcoût = `phash` (négligeable) + OmniParser uniquement en cas de mismatch structure. ## 9. Tests à prévoir **Unitaires** : - Hash perceptuel + grouping : frames similaires/différentes, vérif Hamming threshold. - Fallback OCR-seul si OmniParser KO (mock exception, timeout, healthcheck KO). - Génération `.semantic.yaml` : structure valide, `degraded` correctement positionné. - Cap 10 écrans : session avec 15 → marquage `too_complex` propre. **Intégration** : - Flux complet : session shadow → stop → identification écrans → analyse → `.semantic.yaml` écrit → Option C. - Replay compétence avec `.semantic.yaml` : match nominal, mismatch déclenche escalade autopilote / stop autonome. - Replay compétence sans `.semantic.yaml` : chemin legacy intact, aucun appel OmniParser. **Sécurité** : - Injection chemins relatifs/absolus dans `session_id` ou `slug` refusée (regex strict `^[a-z0-9_]+$`). - Pas d'écriture hors `data/competences/candidate/` et `data/cache/omniparser/`. ## 10. Estimation effort implémentation - ~200-300 lignes Python (endpoint, grouping phash, wrapper OmniParser, écriture YAML, lecture replay). - ~150 lignes tests. - Effort **moyen**, étalable sur 1-2 jours. - **Risque régression faible** : ne touche pas hot path replay, opt-in par compétence, rétrocompat totale. ## 11. Hors scope MVP Phase 2.5 - Détection visuelle de changements d'écran en temps réel pendant le replay (= hot path, révoqué par Plato). - Annotations sémantiques automatiques par VLM (prérequis trop ambitieux POC). - Versioning sémantique multi-versions Easily (post-POC). - Recalcul auto annotations si interface change (post-POC, lié mode rééducation). - Annotations multi-langues (POC français uniquement). - Synchronisation `.semantic.yaml` entre agents distribués (post-POC). --- **Fin DRAFT — à valider par Dom avant implémentation. Aucune modification de fichier de prod. Aucun commit.**