docs: add POC specs, handoffs, and research notes

This commit is contained in:
Dom
2026-06-02 16:28:34 +02:00
parent 18ed6cb751
commit f2e9aac6b7
86 changed files with 27615 additions and 25 deletions

View File

@@ -0,0 +1,279 @@
# Index — Specs opérationnelles replay (transport / validator / popups)
**Date :** 2026-05-24
**Auteur :** Claude (session principale) à partir des 3 specs ciblées + 6 docs de recherche préalables.
**Public :** humain ou agent qui doit prendre en charge l'un des 3 chantiers de fiabilisation replay post-démo GHT.
**Statut :** lecture seule. Aucune décision figée. Plan d'action proposé à valider par Dom.
---
## 0. Comment lire ce document
Tu prends en charge un chantier replay → tu lis §1 (TL;DR) et tu sautes directement à la spec correspondante (§3.1, §3.2 ou §3.3). Tu reviens à §2 (croisements) si ton chantier touche les deux autres. Les décisions ouvertes Dom sont consolidées §4.
Les 3 specs s'appuient sur des **recherches préalables** déjà livrées (`AXE_B1`, `AXE_B1_DEEP`, `AXE_B2`, `AXE_B2_DEEP`, `AXE_D2`, `AXE_D2_DEEP`). Les specs ne refont pas l'étude — elles produisent le contrat opérationnel.
---
## 1. TL;DR
**3 chantiers replay à mener en parallèle pour fermer les bugs racines post-démo GHT (~3 j homme MVP cumulés)** :
| # | Chantier | Bug racine fermé | Spec | Code prêt | Effort MVP |
|---|---|---|---|---|---|
| **B1** | Transport + watchdog | Désync 8 mai (9 actions perdues en 33s) | `SPEC_TRANSPORT_CONTRAT.md` | `replay_watchdog.py` ~270 LOC + patches `api_stream.py` | **3h30** |
| **B2** | Validator post-action | Step 10 (clic Imagerie dans Edge, REPORT success=True) | `SPEC_VALIDATOR_MATRICE.md` | package `core/validation/` ~590 LOC (MVP P0 ~190 LOC) | **8h** |
| **D2** | Chaîne popup propre | `_handle_possible_popup` orphelin + auto-dismiss risqué | `SPEC_POPUPS_CATALOGUE.md` | package `core/dialog/` ~700 LOC + 59 entrées catalogue | **1j** |
**Résultat attendu cumulé** : démo prochaine sans contournement `static_result/static_text`, sans `cancel-replays.sh` manuel, sans pause humaine sur dialogs métier connus.
**Contraintes invariantes respectées** :
- 100% vision (aucun raccourci système inventé)
- Healthtech (jamais d'auto-accept UAC / Hello / SmartScreen / suppression non déclarée)
- Backward compatible (kill-switches env var par défaut OFF sur chaque chantier)
---
## 2. Croisements entre les 3 specs
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ B1 Transport │◄────────│ B2 Validator │ │
│ │ + Watchdog │ ack │ + 6 Checkers │ │
│ └───────────────┘ └───────────────┘ │
│ ▲ │ │
│ │ purge si paused │ failure_category= │
│ │ ▼ UNEXPECTED_DIALOG │
│ │ ┌───────────────┐ │
│ └──────────────────│ D2 Popup │ │
│ │ Resolver │ │
│ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Dépendances et contrats inter-modules
| Source | Cible | Contrat | Quand |
|---|---|---|---|
| B1 | B2 | Action arrive bien côté serveur (REPORT non perdu) | Prérequis. Sans B1, B2 vote sur du vide. |
| B2 | D2 | `failure_category=UNEXPECTED_DIALOG/NO_VISUAL_CHANGE/WRONG_APPLICATION``DialogResolver.resolve()` | Au verdict d'échec d'un Checker |
| D2 | B1 | Si modal détecté pendant qu'une action est en `_retry_pending`, watchdog doit purger | v1.1 du watchdog (déjà partiel via `cancel_replay` ligne 4489) |
| D2 | B2 | `DialogPresenceChecker` (Checker B2) fournit la bbox utilisée par `DialogClosedChecker` | Coordination intra-Validator |
| B2 | B1 | Verdict `WRONG_APPLICATION` (bug step 10) → override `success=True → False` → relance watchdog | Au report client |
### Orthogonalité
- **B1 ↔ B2** : techniquement orthogonaux (peuvent être codés en parallèle), mais **les deux ensemble** = fermeture totale du bug du 8 mai (transport + validation).
- **D2** : indépendant de B1 et B2 pour l'implémentation, mais consomme leurs interfaces au runtime.
---
## 3. Résumé par spec
### 3.1. SPEC_TRANSPORT_CONTRAT.md
**Chemin** : `/home/dom/ai/rpa_vision_v3/docs/recherche/SPEC_TRANSPORT_CONTRAT.md`
**Volume** : 766 lignes, 169 lignes de tables.
**Recherches sources** : `AXE_B1_REPLAY_TRANSPORT.md`, `AXE_B1_DEEP_WATCHDOG.md`.
**Contenu** :
- 2 state machines ASCII (serveur PENDING → DISPATCHED → ORPHAN → ACKED → ABANDONED → PAUSE | client POLLING → RECEIVED → DEDUP → EXECUTING → REPORTING → ACKED) avec invariants I1-I6 et C1-C5.
- Contrats JSON DISPATCH / REPORT / re-dispatch / pause / resume / cancel, avec lignes de code source précises (`api_stream.py:626-651` schema, `3354-3359` retry_pending, `4361-4474` resume, `4489` cancel).
- **Matrice 21 cas limites** (a→u) couvrant timeout pré-réponse, déconnexion post-réception, report perdu, watchdog race, client mort, server restart, polls concurrents, idempotence double-clic, pause pendant action en vol, cancel UI, abandon MAX_RESENDS, etc.
- Sémantique d'idempotence à 7 couches + spec `dedup_set` client copy-paste + idempotence par type d'action.
- 18 timeouts/seuils tabulés avec env vars (`RPA_WATCHDOG_ORPHAN_TIMEOUT_S=30`, `RPA_WATCHDOG_SCAN_INTERVAL_S=10`, `RPA_WATCHDOG_MAX_RESENDS=2`, etc.).
- Transitions pause supervisée & resume (5 déclencheurs `paused_need_help`).
- Compatibilité transport polling ↔ SSE (table d'invariance).
- 7 fiches précédents externes (SQS, NATS, Skyvern, browser-use, Anthropic CU, Playwright MCP) + table comparative.
**Code production-ready dans le doc** : module `agent_v0/server_v1/replay_watchdog.py` (~270 lignes), 4 patches diff unified `api_stream.py`, 8 tests pytest `tests/integration/test_replay_watchdog.py`.
**Effort intégration** : **3h30** (45min schéma+watchdog, 30min câblage, 1h tests pytest, 1h chasse races sur E2E réel, 15min DETTE).
---
### 3.2. SPEC_VALIDATOR_MATRICE.md
**Chemin** : `/home/dom/ai/rpa_vision_v3/docs/recherche/SPEC_VALIDATOR_MATRICE.md`
**Volume** : ~1300 lignes denses.
**Recherches sources** : `AXE_B2_VALIDATOR_PATTERN.md`, `AXE_B2_DEEP_VALIDATOR.md`, `AXE_A4_OCR_TEMPLATE_PHASH.md`.
**Contenu** :
- Matrice principale **27 types d'action × 9 colonnes** (signal primaire / secondaire / fallback / verdicts possibles / latence cible / coût / Checker à utiliser).
- **4 fiches détaillées** pour les cas listés explicitement par Dom :
- `switch_tab` (le bug step 10) : signal primaire = `OcrRoiChecker` ROI 120×40 autour du tab attendu cherchant label exact dans words OCR ; secondaire = pHash de la zone contenu sous les tabs a changé ≥ 5%.
- `close_tab` : `TabAbsenceChecker` + visibilité tab voisin actif.
- `save` : disparition indicateur "modifié" + apparition toast "Enregistré".
- `dialog_button` : disparition du dialog (handoff D2 via `DialogClosedChecker`).
- 5 fiches secondaires (`click_anchor`, `type_text`, `extract_text`, `t2a_decision`, `keyboard_shortcut`).
- **6 Checkers production-ready** : `PixelDiffChecker` (15ms), `OcrRoiChecker` (80ms, **résout step 10**), `TitleBarChecker` (130ms wrapper existant), `JsonSchemaChecker` (10ms), `LlmJudgeChecker` (3s wrapper `verify_with_critic` existant `replay_verifier.py:367`), `TabActiveChecker`/`TabAbsenceChecker`/`SaveSuccessChecker`/`DialogClosedChecker` (nouveaux).
- Confidence scoring + règles d'agrégation multi-checker (`switch_tab` → SUCCESS si primaire ≥ 0.85 OU primaire ≥ 0.65 AND secondaire ≥ 0.70).
- **Anti-patterns table 12 entrées** : pHash global pour switch_tab, title-bar seule pour SPA, `success=True` parce que coords envoyées, SSIM global dialog, etc.
- 6 précédents externes (Skyvern `complete_verify`, browser-use `evaluation` agent, Playwright assertions, Selenium `expected_conditions`, SikuliX `waitVanish`, PyImageSearch).
- Plan d'intégration en 3 étapes graduées (1j MVP / 2 sem couverture complète / 1 mois bench).
**Réutilisation existant** : `OcrRoiChecker` réutilise le singleton EasyOCR de `TitleVerifier._get_ocr()` (zéro coût d'init).
**Reproduction offline du bug step 10** : script `repro_bug_step10_validator.py` fourni + test pytest `test_validator_step10.py`, sur capture `visual_workflow_builder/backend/data/anchors/anchor_0438bd2d9bdd_1778161174_full.png`.
**Wiring** : diff unified format insertion à `api_stream.py:3447-3582` derrière flag `RPA_VALIDATOR_V2_ENABLED=false` (default OFF, aucune régression flag off).
**Budget latence démo 46 steps** : **+11s cumulés** (vs 33s perdus en pause/reprise step 10).
**Effort intégration P0** : **8h** (création package 4h + tests 1.5h + patch api_stream 2h + smoke 30min).
---
### 3.3. SPEC_POPUPS_CATALOGUE.md
**Chemin** : `/home/dom/ai/rpa_vision_v3/docs/recherche/SPEC_POPUPS_CATALOGUE.md`
**Volume** : 1758 lignes après enrichissement.
**Recherches sources** : `AXE_D2_DIALOG_POPUP.md`, `AXE_D2_DEEP_POPUP_CHAIN.md`.
**Contenu** :
- **Section 2bis — Catalogue compact (format Dom)** avec exactement 5 colonnes : `ID | Titre exact (FR/EN) | Appli source | Boutons attendus | Politique`.
- **Politique trichotomie stricte** :
- **`auto`** = Léa clique un bouton précis (action explicite définie)
- **`pause`** = Léa s'arrête et attend décision humaine
- **`skip`** = Léa ignore le modal (ne clique rien, ne s'arrête pas)
- **59 entrées catalogue** réparties en 5 catégories (A SYSTÈME, B NAVIGATEUR, C MÉTIER, D APP TIERS, E INCONNU) :
- **44 `pause`** : toute la catégorie A SYSTÈME + identification + suppression + warnings cliniques
- **10 `auto`** : save/confirm Easily, dialogs métier connus, dialogs disposables avec clic explicite
- **5 `skip`** : `browser-translate-prompt`, `easily-toast-saved`, `outlook-reminder`, `chrome-update`, `edge-update`
- 10 fiches détaillées des modaux critiques (UAC, Hello, SmartScreen, save unconfirmed, browser perms, etc.) avec capture-type ASCII.
- **Workflow VWB déclaratif** `expected_modal` (YAML + Pydantic schema) avec validateur `system_modals_cannot_be_overridden` qui **rejette toute politique ≠ `pause` sur préfixes `windows-` / `defender-`** — un workflow VWB ne peut pas forcer un UAC en auto.
- Snippet Python `KNOWN_DIALOGS` étendu (781 lignes, syntaxe valide `ast.parse` OK) avec champs `window_title`, `app_source`, `policy` (`auto`/`pause`/`skip`), `declarative_override: bool`. Helpers `get_metadata()` et `can_be_overridden()`.
- Tests offline pytest + protocole de capture.
- 7 précédents externes (Skyvern issue #69, browser-use issue #1996, Anthropic CU human takeover, OpenAI Operator watch mode, AutoIt/Sikuli, pywinauto, Selenium JS alerts).
**Décisions tranchées par les agents** :
- `_handle_possible_popup` orphelin **supprimé** (0 site d'appel + antipattern Tab+Enter aveugle).
- `_handle_popup_vlm` actif **conservé mais simplifié** → devient client léger d'un nouvel endpoint `POST /api/v1/dialog/resolve`.
- DialogResolver côté **serveur** (pas client) pour mutualiser avec `dialog_handler.py` existant.
**Couverture estimée** : **~85%** des modaux courants sans intervention humaine. Les 15% restants = pause supervisée par design healthtech.
**Effort intégration** : **1j MVP** (P0 démo) → 1 sem couverture complète + tests fixtures (P1) → 1 mois bench injection + apprentissage catalogue (P2).
---
## 4. Décisions ouvertes consolidées pour Dom
Les 3 specs remontent des points qu'un agent ne peut pas trancher seul. Regroupés ici par thème.
### 4.1. Transport / watchdog (8 décisions — `SPEC_TRANSPORT_CONTRAT.md` §12)
| ID | Question | Recommandation auteur |
|---|---|---|
| D1 | Persistance `_retry_pending` au restart serveur ? | Non par défaut (cas extrême ; restart démo = redémarrage replay manuel) |
| D2 | Politique d'abandon par type d'action (click vs wait) ? | Différenciée : click MAX_RESENDS=2, extract_text MAX_RESENDS=1 |
| D3 | Retry des actions server-side (`extract_text`, `t2a_decision`) ? | Non (idempotence non garantie : LLM peut diverger) |
| D4 | Purge `_retry_pending` à la complétion workflow ? | **Oui** (recommandé) |
| D5 | `dedup_set` client : taille LRU + clé ? | LRU 50 entrées, clé = `action_id` + `attempt_id` |
| D6 | Génération `attempt_id` côté serveur ? | UUID4 court 8 chars, incrémenté à chaque resend |
| D7 | Backward-compat client v1 ↔ serveur v2 ? | Header `X-Replay-Protocol-Version` côté client |
| D8 | `cancel_in_flight` (annuler action en cours sur le client) ? | **Non** (recommandé) — trop de risques |
### 4.2. Validator (7 actions où le signal "qui fait foi" reste flou — `SPEC_VALIDATOR_MATRICE.md` §10)
| Action | Question |
|---|---|
| `paste_and_execute` | Vérif côté Léa Windows ou côté SSH VM (cas NoMachine pixel intermédiaire) ? |
| `screenshot_evidence` | `TitleBarChecker` suffit ou exiger netteté image ? |
| `pause_for_human` mode autonome | Aujourd'hui silencieusement ignorée (`api_stream.py:3011-3017`) — laisser ou changer ? |
| `t2a_decision = NA` | Verdict métier vs erreur LLM (hors-scope médical Claude) — qui décide ? |
| Tab déjà actif au moment du clic | Idempotence (SUCCESS) ou NO_VISUAL_CHANGE ? |
| `drag_drop_anchor` | Whitelist serveur mais pas de handler Léa — implémenter ou retirer du whitelist ? |
| Animations longues > 1s | `wait_after_action_ms` par type d'action vs généralisé ? |
### 4.3. Popups (5 modaux ambigus — `SPEC_POPUPS_CATALOGUE.md` §10)
| Modal | Politique proposée | Risque à valider |
|---|---|---|
| `easily-required-field` | `auto` | Peut masquer un bug de grounding réel |
| `outlook-reminder` | `skip` | Risque clinique de masquer un rappel pro |
| `chrome-update` / `edge-update` | `skip` | À confirmer si ne prend pas le focus après inactivité |
| `easily-clinical-warning` | `pause` non surchargeable | Volontairement strict, à valider |
| `browser-perm-microphone` (Easily dictée vocale) | `pause` | Déclaration globale `declared_dialogs` ou par-workflow ? |
---
## 5. Plan d'attaque concret proposé (~3 jours homme cumulés)
### Vague 1 (jour 1) — Transport + start Validator
- **Matin (3h30)** — Watchdog `replay_watchdog.py` + patches `api_stream.py`. Kill-switch `RPA_WATCHDOG_ENABLED=false` par défaut → activable progressivement. Tests pytest sans Windows. Smoke E2E réel.
- **Après-midi (4h)** — Validator MVP P0 : `PixelDiffChecker` + `OcrRoiChecker` + orchestrateur, sans `LlmJudgeChecker`. Flag `RPA_VALIDATOR_V2_ENABLED=false`. Test offline du bug step 10 sur fixture du 8 mai.
### Vague 2 (jour 2) — Finir Validator + Popup chain MVP
- **Matin (4h)** — Compléter Validator : `TabActiveChecker`, `SaveSuccessChecker`, `DialogClosedChecker`, `JsonSchemaChecker`. Tests par type d'action.
- **Après-midi (4h)** — Chaîne popup MVP : signatures FR+EN, `ChangeDetector` + `DialogClassifier` + `DialogResolver` côté serveur. Endpoint `/api/v1/dialog/resolve`. Simplification `_handle_popup_vlm` client.
### Vague 3 (jour 3) — Intégration et démo
- **Matin (3h)** — Coordination Validator → DialogResolver (handoff `UNEXPECTED_DIALOG`). Test bout-en-bout démo MOREL Catherine avec les 3 chantiers actifs.
- **Après-midi (3h)** — Bench latence sur démo réelle (cible : +20s overhead max sur 46 steps). Activation progressive des flags. Mise à jour `DETTE_TECHNIQUE.md` (DETTE-001, 008 closables).
**Sortie attendue** : démo prochaine `Demo_urgence_3_db` qui tourne **sans** `static_result/static_text`, **sans** `cancel-replays.sh` manuel, **sans** pause humaine sur dialogs métier connus.
---
## 6. Hors-périmètre de ces 3 specs (rappel)
Ces 3 specs **ne traitent pas** :
- Migration grounding VLM (`AXE_A1`, `AXE_A2`, `AXE_A3` — Qwen3-VL, smart_resize, bench bbox).
- Bug capture client Y `mss.monitors[N]=2560×60` (`AXE_B5_D1_CAPTURE_REMOTE.md` — fix DPI 8 lignes en tête de `main.py`).
- Shadow learning / fine-tuning / memory store (`AXE_C_LEARNING_SHADOW.md`).
- Packaging / code signing / multi-tenant (`AXE_D4_MULTI_TENANT_DEPLOY.md`).
- Veille frameworks externes (`AXE_E_FRAMEWORKS_BENCHMARKS.md`).
- Bug recapture anchor VWB silencieuse (P0 — non couvert par cette vague).
- Bug skip ord 13 orchestration (P0 — non identifié, NOT REPRO 100%).
Ces sujets sont couverts par les autres docs `docs/recherche/AXE_*.md`. Voir `SYNTHESE_TECHNOS_REPLAY_2026-05-23.md` pour la carte d'ensemble.
---
## 7. Cartographie complète des livrables de recherche
### Vague 1 — Panorama 13 axes (23 mai 2026)
```
docs/SYNTHESE_TECHNOS_REPLAY_2026-05-23.md (synthèse croisée initiale)
docs/recherche/AXE_A1_VLM_GROUNDING_SOTA.md (état art VLM grounding)
docs/recherche/AXE_A2_SMART_RESIZE_BBOX.md (DETTE-014/010/007/006)
docs/recherche/AXE_A3_BENCH_PROTOCOL.md (script bench reproductible)
docs/recherche/AXE_A4_OCR_TEMPLATE_PHASH.md (cascade déterministe)
docs/recherche/AXE_A5_SCREEN_TOKENIZATION.md (OmniParser / SoM)
docs/recherche/AXE_B1_REPLAY_TRANSPORT.md (SSE / WS / pull-poll)
docs/recherche/AXE_B2_VALIDATOR_PATTERN.md (Planner-Actor-Validator)
docs/recherche/AXE_B4_ORA_VS_REPLAY.md (autonomous vs déclaratif)
docs/recherche/AXE_B5_D1_CAPTURE_REMOTE.md (mss / DXGI / NoMachine)
docs/recherche/AXE_C_LEARNING_SHADOW.md (Shadow + FT + memory)
docs/recherche/AXE_D2_DIALOG_POPUP.md (chaîne dialog handling)
docs/recherche/AXE_D4_MULTI_TENANT_DEPLOY.md (packaging + code signing)
docs/recherche/AXE_E_FRAMEWORKS_BENCHMARKS.md (delta veille + benchmarks)
```
### Vague 2 — Approfondissement 3 axes replay (24 mai 2026)
```
docs/recherche/AXE_B1_DEEP_WATCHDOG.md (watchdog production-ready)
docs/recherche/AXE_B2_DEEP_VALIDATOR.md (Validator package)
docs/recherche/AXE_D2_DEEP_POPUP_CHAIN.md (chaîne popup complète)
```
### Vague 3 — Specs opérationnelles (24 mai 2026)
```
docs/recherche/SPEC_TRANSPORT_CONTRAT.md (contrat dispatch→ack→retry→orphan→resume)
docs/recherche/SPEC_VALIDATOR_MATRICE.md (matrice action → signal qui fait foi)
docs/recherche/SPEC_POPUPS_CATALOGUE.md (catalogue 59 entrées + politique auto/pause/skip)
```
### Vague 4 — Index (ce document)
```
docs/recherche/INDEX_REPLAY_SPECS_2026-05-24.md (point d'entrée brief agent / humain)
```
---
*Index maintenu par Dom. À mettre à jour quand de nouvelles specs replay sont livrées ou quand une décision §4 est tranchée.*