docs: add POC specs, handoffs, and research notes
This commit is contained in:
169
docs/POC/SPECS_PHASE_25_SEMANTIQUE_2026-06-01.md
Normal file
169
docs/POC/SPECS_PHASE_25_SEMANTIQUE_2026-06-01.md
Normal file
@@ -0,0 +1,169 @@
|
||||
# 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/<session>/<index>.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/<slug>.semantic.yaml`
|
||||
|
||||
Structure :
|
||||
|
||||
```yaml
|
||||
competence_id: facturation_urgence_simple
|
||||
semantic_version: 1
|
||||
generated_at: 2026-06-01T18:30:00Z
|
||||
omniparser_version: <hash adaptateur>
|
||||
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: <slug>.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.**
|
||||
Reference in New Issue
Block a user