32 KiB
AXE D2 — Gestion des modaux & popups imprévus
Date : 2026-05-23 Auteur : agent recherche (dispatch session principale) Périmètre : stratégie pour gérer en 100% vision les modaux Windows / navigateur / métier qui interrompent un replay Léa. Statut : brief de recherche — aucune modification de code proposée. Décisions = Dom.
1. TL;DR + recommandation architecture
1.1. Diagnostic
- Le projet a déjà 80% de l'outillage :
core/grounding/dialog_handler.py(EasyOCR + InfiGUI + fallback OCR direct) couvre la résolution d'un dialog connu. - Trois lacunes documentées :
- Côté client Léa,
_handle_possible_popupest défini avec 0 site d'appel (LESSONS_LEARNED_GHT_2026-05.md, F5.5.1) — il existe également un_handle_popup_vlmqui prend le relais mais sans déclencheur générique. - Pas de détecteur d'apparition (la cascade ne sait pas qu'un modal vient d'apparaître — elle continue à viser l'élément initial, qui est désormais masqué).
- Pas de politique de fail-safe différenciée par type de modal (UAC ≠ "fichier déjà existe" ≠ Windows Hello).
- Côté client Léa,
- Anti-pattern interdit (
feedback_100pct_visual.md) : inventer un raccourci Win+R / Ctrl+X / Échap-systématique. La cascade reste OCR → template → VLM, jamais "réflexe magique".
1.2. Recommandation
Une stack en trois couches, branchée APRÈS chaque action (et au démarrage du tick d'observation), réutilisant le code existant :
ChangeDetector ──► DialogClassifier ──► DialogResolver
(léger, < 50ms) (OCR titre + LLM) (catalogue déclaratif
+ InfiGUI/OCR + escalation)
- ChangeDetector — détecte qu'un modal vient d'apparaître. Combinaison foreground-window-change (Windows API côté client) + screenshot diff région centrale + heuristiques visuelles (ombre, centrage). Latence cible < 50 ms.
- DialogClassifier — décide quoi faire (catalog match → action déterministe ; sinon → VLM pour catégoriser). Réutilise
_read_title+KNOWN_DIALOGSdudialog_handler.pyactuel, étend avec une catégorisation par type (UAC/HELLO/SMARTSCREEN/BROWSER_PERM/METIER_SAVE/INCONNU). - DialogResolver — applique la matrice modal → action (§5). En santé : aucun auto-accept système (UAC/Hello/SmartScreen) — uniquement pause supervisée. Auto-dismiss déterministe uniquement pour les modaux métier déclarés dans le workflow (ex. "fichier déjà existe → Oui").
Cette stack résout mécaniquement la dépendance avec AXE_B2 (Validator) : un modal non détecté = un Validator post-action raté ; un Validator sémantique strict force le détecteur à être appelé avant le verdict.
2. Taxonomie des modaux Windows 11 / navigateur (mai 2026)
Sept catégories qui couvrent ~95% des cas terrain healthtech.
2.1. UAC (User Account Control)
- Quand : installation, élévation
runas, modification système. - Aspect visuel : fond bleu ou assombri global (secure desktop), titre
Contrôle de compte d'utilisateur, deux boutonsOui/Nonou champ mot de passe administrateur. - Particularité : sur secure desktop, screenshot Léa peut être noir/inaccessible (
pyautoguine voit rien). Microsoft a livré des fixes UAC en oct. 2025 → janv. 2026 (KB5063878 / KB5074109) — quelques replays plantent encore sur 24H2 idle/locked. - Politique healthtech recommandée : JAMAIS auto-accept. Pause supervisée immédiate.
2.2. Windows Hello / WebAuthn / FIDO2
- Quand : déverrouillage app sensible (gestionnaire de mots de passe, Outlook), site avec WebAuthn, élévation UAC configurée pour exiger biométrie.
- Aspect visuel : popup système centré, icône empreinte ou caméra, message "Touchez le capteur" ou "Saisissez votre code PIN".
- Particularité : nécessite interaction physique humaine par construction. Aucune solution 100% vision ne peut résoudre. Anti-pattern absolu : tenter de cliquer "Annuler" pour passer outre.
- Politique : pause supervisée + tip suggérant "désactiver Windows Hello pour la session de démo" en config préalable.
2.3. Microsoft Defender SmartScreen
- Quand : exe non signé, téléchargement suspect, premier lancement Léa.
- Aspect visuel : bandeau bleu ciel "Windows a protégé votre PC", lien "Informations complémentaires" qui révèle le bouton "Exécuter quand même".
- Politique : pause supervisée + log security. Notre
feedback_auth_dialogs_runtime.mdrappelle d'anticiper AVANT démo client (signature code, allowlist hash SHA256 — voirproject_code_signing.md).
2.4. Permissions navigateur (caméra, micro, notifications, géoloc, clipboard)
- Quand : première visite site
https://, démo Easily Assure si elle demande accès clipboard / notifications. - Aspect visuel : popup ancrée à l'URL bar (Chrome/Edge), boutons
Autoriser/Bloquer. Variant inline overlay (Edge 2026). - Particularité critique sécurité (CVE-2026-0628 janv. 2026) : malveillances via extensions Chrome qui détournent des permissions. Auto-accept = risque RGPD/HDS.
- Politique : déclaratif dans le workflow ("À cette étape, autoriser le micro") ou pause supervisée. Aucun auto-accept générique.
2.5. Dialog métier (sauvegarde, écrasement, perte de modifications)
- Quand : fermeture document non sauvé, "fichier existe déjà", "Voulez-vous quitter ?".
- Aspect visuel : popup applicative au-dessus de la fenêtre parente, OCR titre fiable, boutons texte clair (
Oui/Non/Annuler/Enregistrer). - Politique : catalogue déclaratif. C'est exactement ce que
KNOWN_DIALOGSdudialog_handler.pyactuel gère. Résolution InfiGUI + fallback OCR direct.
2.6. Avertissements / erreurs applicatives (popup OK)
- Quand : timeout réseau, validation backend KO, message info-utilisateur.
- Aspect visuel : popup centré, icône triangle/croix, un seul bouton
OK/Fermer. - Politique : auto-dismiss déterministe SAUF si message critique (regex blocklist "données perdues", "supprimé"). Log obligatoire.
2.7. Modaux inattendus / inconnus (notification push Teams, Outlook reminder, popup mise à jour, cookie banner, newsletter)
- Quand : tout le temps, surtout en démo live (Slack ping, Outlook reminder à xx:00, popup Windows Update).
- Aspect visuel : très variable. Souvent en coin (toast) plutôt que centré, mais peut voler le focus.
- Politique : VLM classifier (catégoriser : "publicité" / "système" / "métier inconnu") → pause supervisée avec proposition humaine ou auto-dismiss conservateur (Échap visuel via clic croix détectée).
3. Comparaison frameworks 2026
| Framework | Détection modal | Politique | Pause humaine | Catalogue déclaratif |
|---|---|---|---|---|
| Anthropic Computer Use (avril 2026) | classifiers anti-prompt-injection détectent screenshots suspects → demande confirmation user | permission-first par défaut, refuse "high-risk", monitor model peut pause | oui (Auto Mode mai 2026 = classifier décide auto-approve vs prompt) | non public |
| OpenAI Operator / ChatGPT Agent (juillet 2025 → 2026) | "monitor model" surveille comportement suspect ; CAPTCHA / login → cède le contrôle à l'humain (screenshots OFF pendant ce temps) | confirme avant action critique, prend la main sur prompts sécurité | oui, prend-le-relais explicite | non |
| Skyvern 2.0 (oct. 2025) | Validator regarde écran post-action, détecte "popup blocked the click", redonne main au Planner pour retry | retry visuel ; built-in TOTP / 2FA / file downloads | non documenté publiquement | implicite via Validator |
| browser-use (issue #1996 ouvert mai 2026) | pas de solution intégrée — la communauté demande explicitement une infra générique | au cas par cas | non | non |
| Cradle (R&D fin 2025) | screenshot-only, demande au VLM principal d'identifier popup à chaque tick | dépend prompt | non | non |
| PopSweeper (recherche acad. 2024, applicable mobile) | classifier deux étages ResNet50 + MobileNetV2 + YOLO-World pour bouton croix ; image-diff 100 ms tick ; 60 ms par frame | auto-dismiss centré sur close-button | non | non |
| rpa_vision_v3 (actuel) | aucun détecteur ; dialog_handler.py ne s'exécute que si appelé explicitement |
catalogue déclaratif + InfiGUI/OCR fallback | feedback_failure_is_learning oui | oui (KNOWN_DIALOGS) |
Lecture :
- Skyvern et OpenAI Operator valident l'idée centrale : un Validator strict détecte le modal indirectement (action attendue échoue → l'écran a changé sans cause connue → modal).
- Anthropic et OpenAI convergent sur le "monitor model" parallèle qui pause sans toucher au workflow principal.
- PopSweeper démontre qu'un détecteur léger spécialisé (CNN custom < 60 ms) suffit pour ne PAS ajouter de coût VLM à chaque tick.
- L'écosystème open source (browser-use) n'a toujours pas de solution générique — le sujet est ouvert.
4. Architecture proposée pour rpa_vision_v3
4.1. Vue d'ensemble
┌───────────────────────────────────────────┐
│ Léa (Windows client) │
│ │
action click ───►│ executor │
│ │ │
│ ▼ │
│ perform_click │
│ │ │
│ ▼ │
│ ChangeDetector ◄─── screenshot t+1 ──┐ │
│ │ │ │
│ ▼ │ │
│ is_modal_appeared? │ │
│ │ │ │
│ no ┴ yes │ │
│ │ │ │
│ ▼ │ │
│ DialogClassifier │ │
│ │ │ │
│ ▼ │ │
│ type ∈ {UAC, HELLO, SMART, PERM, │ │
│ SAVE, OK, INCONNU} │ │
│ │ │ │
│ ▼ │ │
│ DialogResolver │ │
│ │ │ │
│ ▼ │ │
│ policy(type, workflow_ctx) │ │
│ │ │ │
│ ▼ │ │
│ ┌─ AUTO_DISMISS (OK trivial) │ │
│ ├─ DECLARATIVE (catalog match) │ │
│ ├─ ASK_HUMAN (pause supervisée) │ │
│ └─ ESCALATE_SECURITY (log + pause) │ │
│ │ │
│ ▼ │ │
│ resume_or_wait │ │
│ │ │
└───────────────────────────────────────┘
│
▼
serveur (api_stream)
│
▼
report dialog event + replay state
4.2. Étendre core/grounding/dialog_handler.py existant
Le fichier actuel (lecture seule pour ce doc, voir Read) fait déjà :
_read_title(EasyOCR full-screen,fr+en, GPU)- catalogue
KNOWN_DIALOGSordonné (popups modaux prioritaires avant fenêtres parents) _click_via_infigui(UI-TARS / InfiGUI grounder déjà branché)_click_via_ocr(fallback OCR direct)- retour
dictavechandled / title / dialog_type / action / position / time_ms
À ajouter (esquisses, pas de code à committer) :
# core/grounding/change_detector.py — nouveau fichier proposé
from dataclasses import dataclass
from typing import Optional, Tuple
import time
import numpy as np
@dataclass
class ChangeSignal:
"""Signal qu'un changement écran significatif vient d'apparaître."""
is_modal: bool # heuristique modal vs scroll normal
foreground_hwnd_changed: bool # côté Windows uniquement
diff_ratio: float # 0.0 = identique, 1.0 = tout différent
central_diff_ratio: float # diff zone centrale (modaux centrés)
timestamp: float
class ChangeDetector:
"""Détecte qu'un modal *vient d'apparaître* sans appeler le VLM principal.
Stratégie :
1) foreground window change (Windows API, ~1 ms)
2) screenshot diff centre vs périphérie (numpy diff sur sous-region, ~10 ms)
3) heuristique "centré + bordure assombrie" (modal pattern, ~5 ms)
Budget total cible : < 50 ms pour ne PAS ralentir la boucle replay.
"""
def __init__(self):
self._last_screenshot = None
self._last_hwnd = None
def detect(self, screenshot_pil) -> ChangeSignal:
t0 = time.time()
arr = np.asarray(screenshot_pil.convert("L"))
fg_changed = self._check_foreground_changed()
diff_ratio = 0.0
central_diff = 0.0
if self._last_screenshot is not None:
prev = np.asarray(self._last_screenshot.convert("L"))
if prev.shape == arr.shape:
diff = np.abs(prev.astype(int) - arr.astype(int))
diff_ratio = float((diff > 25).mean())
# zone centrale = modaux Windows typiques
h, w = arr.shape
cy0, cy1 = h // 4, 3 * h // 4
cx0, cx1 = w // 4, 3 * w // 4
central_diff = float((diff[cy0:cy1, cx0:cx1] > 25).mean())
is_modal = (
fg_changed
or (central_diff > 0.10 and diff_ratio < 0.40) # changement centré
)
self._last_screenshot = screenshot_pil
return ChangeSignal(
is_modal=is_modal,
foreground_hwnd_changed=fg_changed,
diff_ratio=diff_ratio,
central_diff_ratio=central_diff,
timestamp=t0,
)
def _check_foreground_changed(self) -> bool:
"""Côté Windows uniquement — sinon retourne False."""
try:
import ctypes # noqa
hwnd = ctypes.windll.user32.GetForegroundWindow()
changed = (self._last_hwnd is not None) and (hwnd != self._last_hwnd)
self._last_hwnd = hwnd
return changed
except Exception:
return False
Note importante : feedback_popup_vlm.md documente que GetForegroundWindow est non fiable seul (retourne 0 en SSH, popups Windows modernes partagent hwnd du parent). On l'utilise comme signal complémentaire, jamais comme source unique. La détection finale repose sur le diff écran (vision).
4.3. DialogClassifier — extension du dialog_handler.py
# core/grounding/dialog_classifier.py — proposition
from enum import Enum
class DialogType(str, Enum):
UAC = "uac"
HELLO = "windows_hello"
SMARTSCREEN = "defender_smartscreen"
BROWSER_PERMISSION = "browser_permission"
METIER_SAVE = "metier_save" # match catalog KNOWN_DIALOGS
METIER_CONFIRM = "metier_confirm"
OK_TRIVIAL = "ok_trivial" # popup avec 1 seul bouton OK
INCONNU = "inconnu"
# Signatures texte par type (extension du catalogue actuel)
TYPE_SIGNATURES = {
DialogType.UAC: [
"contrôle de compte d'utilisateur",
"user account control",
"voulez-vous autoriser cette application",
],
DialogType.HELLO: [
"windows hello", "saisissez votre code pin",
"touchez le capteur d'empreintes",
],
DialogType.SMARTSCREEN: [
"windows a protégé votre pc",
"smartscreen", "informations complémentaires",
],
DialogType.BROWSER_PERMISSION: [
"autoriser", "bloquer",
"souhaite utiliser votre caméra",
"souhaite utiliser votre microphone",
"souhaite afficher des notifications",
],
# METIER_SAVE et METIER_CONFIRM = KNOWN_DIALOGS existant
}
class DialogClassifier:
"""Classifie un dialogue détecté en type connu.
Stratégie cascade :
1) match signatures texte (OCR titre) — ~150 ms (EasyOCR cache)
2) si pas de match → VLM compact (qwen3-vl:8b) avec prompt
"Classify this dialog: uac / hello / smartscreen / browser_perm /
metier / unknown" — ~1.7 s
3) fallback : INCONNU
"""
def classify(self, screenshot_pil, ocr_text: str) -> DialogType:
text = ocr_text.lower()
for dtype, signatures in TYPE_SIGNATURES.items():
for sig in signatures:
if sig in text:
return dtype
# Catalogue métier existant (KNOWN_DIALOGS du dialog_handler.py)
from core.grounding.dialog_handler import KNOWN_DIALOGS
for key in KNOWN_DIALOGS:
if key in text:
return DialogType.METIER_SAVE # ou METIER_CONFIRM selon key
# Fallback VLM si rien ne matche et qu'on a un signal modal fort
return self._classify_via_vlm(screenshot_pil) or DialogType.INCONNU
def _classify_via_vlm(self, screenshot_pil) -> Optional[DialogType]:
# Appel qwen3-vl:8b via Ollama LAN (port 11434)
# Prompt court, format=json strict
# ⚠ qwen3-vl:8b ignore parfois format=json — fallback regex sur stdout
...
4.4. DialogResolver — politique par type
Voir matrice §5 ci-dessous. Le resolver applique la politique et émet un événement structuré au serveur :
@dataclass
class DialogEvent:
type: DialogType
title_ocr: str
policy_applied: str # "auto_dismiss" / "declarative" / "ask_human" / "escalate_security"
action_taken: Optional[str] # "click 'Oui' (123,456)" / "paused"
duration_ms: float
screenshot_path: str # toujours archivé pour audit
5. Matrice modal → action
| Type | Détection signature | Politique healthtech | Action concrète | Audit |
|---|---|---|---|---|
| UAC | "contrôle de compte", "user account control" | escalate_security + ask_human — JAMAIS auto-accept | pause_for_human ; toast "élévation requise — opérateur valide" |
log full + screenshot |
| Windows Hello | "windows hello", "code pin", "touchez le capteur" | ask_human — interaction physique requise par construction | pause + tip pré-démo : "désactiver Hello pour la session" (paramètres Windows) | log |
| Defender SmartScreen | "windows a protégé votre pc", "smartscreen" | escalate_security + ask_human | pause + log security ; rappel project_code_signing.md (signature SHA256) |
log full |
| Permission navigateur (cam/mic/notif/geoloc) | "souhaite utiliser votre", "autoriser / bloquer" | declarative si déclaré dans workflow ; sinon ask_human | catalog match → click Autoriser ; sinon pause |
log + screenshot |
| Métier sauvegarde ("Voulez-vous enregistrer ?", "Enregistrer sous") | KNOWN_DIALOGS existant |
declarative | InfiGUI click Enregistrer (catalog priority basse — fenêtre parent) |
log standard |
| Métier confirmation ("Voulez-vous remplacer ?", "Existe déjà", "Écraser") | KNOWN_DIALOGS priorité HAUTE |
declarative | InfiGUI click Oui ; fallback OCR direct (code actuel) |
log standard |
| OK trivial (erreur app, info) | 1 seul bouton détecté, mots-clés "erreur/error/warning" ; pas de mot blocklist | auto_dismiss | click OK |
log standard |
| OK trivial SUSPECT (mots-clés "supprimé", "perdu", "irréversible") | blocklist regex | ask_human | pause | log full |
| INCONNU | aucun match | ask_human par défaut (pas d'auto-dismiss aveugle) | pause + capture VLM pour catégorisation a posteriori → enrichit catalogue | log full |
Garde-fou healthtech : tout dialog non métier listé dans KNOWN_DIALOGS ou dans le workflow déclaratif escalade en pause supervisée par défaut. C'est cohérent avec feedback_failure_is_learning.md (échec = pause, pas stop) et le constat OpenAI/Anthropic 2026 (login/sécurité → cède la main à l'humain).
6. Détection rapide d'apparition de modal
Trois pistes, à composer plutôt qu'à choisir :
6.1. Foreground window change (Windows API)
- Coût : ~1 ms.
- Fiabilité : faible seul (
feedback_popup_vlm.md27 mars 2026 : popups Windows modernes partagent hwnd du parent, retourne 0 en SSH). - Usage : signal complémentaire dans
ChangeSignal, jamais source unique.
import ctypes
hwnd = ctypes.windll.user32.GetForegroundWindow()
title_buf = ctypes.create_unicode_buffer(256)
ctypes.windll.user32.GetWindowTextW(hwnd, title_buf, 256)
# Comparer hwnd_n vs hwnd_n-1 ; titre dans title_buf.value
6.2. Screenshot diff zone centrale vs périphérie
- Coût : ~10 ms (numpy
abs(prev - curr) > seuil, downscale 1/4). - Fiabilité : bonne pour modaux centrés (UAC, dialog métier, Hello). Faible pour toasts en coin.
- Heuristique :
central_diff_ratio > 0.10ETdiff_ratio < 0.40→ modal centré probable (le centre change beaucoup, le reste peu). - Pattern visuel auxiliaire : zone "assombrie" en bordure (
secure desktopUAC = pixels < 50 en luminance sur > 60% de l'écran).
6.3. PopSweeper-style classifier (option future, si latence VLM trop forte)
- ResNet50 + MobileNetV2 deux étages → 60 ms/frame, 91.7% précision sur RICO (mobile).
- À envisager uniquement si la détection diff+heuristique laisse passer trop de cas. Pour l'instant, surcoût d'un modèle dédié non justifié — l'OCR titre + signatures couvre 80%.
6.4. Pas de pHash global pour détection modal
feedback_phash_vs_dialog_in_vm.md est explicite : pHash global est inadapté à la cascade de modaux en VM. Le pHash compare des images entières, masquant les changements locaux qui sont précisément l'indice d'un modal. Utiliser screenshot diff zoné OU OCR titre — pas pHash global.
7. Activation de _handle_possible_popup orphelin
7.1. État actuel
- Côté client (Léa Windows) :
_handle_possible_popupdéfini, 0 site d'appel (LESSONS_LEARNED_GHT_2026-05.md, F5.5.1). Un_handle_popup_vlmexiste en parallèle (le "remplacement" mentionné dans l'audit) mais sans déclencheur générique. - Côté serveur :
core/grounding/dialog_handler.py(étudié pour ce doc) — handler complet, ne se déclenche que si on l'appelle explicitement. - Constat memoire 27 mars 2026 :
qwen3-vl:8bdétecte popup en 3.6 s avec coordonnées précises depuis le client (appel direct LAN port 11434), pas via le serveur. Donc le VLM-post-clic est techniquement validé.
7.2. Câblage proposé (sans modifier le code dans ce doc)
Le pattern à brancher dans agent_v1/core/executor.py ressemble à :
def perform_click(self, x, y, ...):
screenshot_before = grab()
do_click(x, y)
time.sleep(short_delay)
screenshot_after = grab()
signal = ChangeDetector().detect(screenshot_after)
if signal.is_modal:
ocr_text = read_ocr(screenshot_after)
dtype = DialogClassifier().classify(screenshot_after, ocr_text)
event = DialogResolver(policy).resolve(dtype, screenshot_after, workflow_ctx)
report_to_server(event)
if event.policy_applied == "ask_human":
return WAIT_HUMAN
return OK
Sites d'appel à brancher (à valider avec Dom avant tout commit) :
- Après chaque
_replay_actioncôté client (suit la mémoire 27 mars). - Avant chaque vérification de Validator post-action (cohérence AXE_B2).
- Au démarrage du tick d'observation
observe_reason_actcôté serveur (capture un modal apparu pendant un wait long).
7.3. Décision sur _handle_popup_vlm vs _handle_possible_popup
À trancher avec Dom : garder UN seul handler (probablement _handle_popup_vlm qui appelle l'extension proposée ici), supprimer l'orphelin. Sinon dette technique persistante (DETTE-XXX à créer si décision prise).
8. Anti-patterns à proscrire
8.1. Hardcoder un raccourci système "fix"
feedback_100pct_visual.md est sans appel : JAMAIS :
keyboard.press_and_release('escape')pour "fermer un popup".keyboard.press_and_release('win+r')pour "ouvrir un truc rapidement".keyboard.press_and_release('ctrl+x')pour "annuler".
Raisons :
- Casse le récit "Léa comprend visuellement". Démontage immédiat face à un DSI healthtech.
- Échappe à la cascade de validation (OCR → template → VLM).
- Effets de bord imprévisibles : Échap dans un formulaire peut purger des données saisies ; Win+R sur un secure desktop ne fait rien et perd l'état.
Exception unique : gesture_catalog.py autorise les réflexes système explicitement référencés (voir feedback_lea_reflexes_catalog.md). Mais c'est une composition orchestrée, pas un "fix popup ad hoc".
8.2. Auto-accept système (UAC, Hello, SmartScreen)
Interdit en healthtech. Toujours pause supervisée. Cohérent avec FDA / RGPD / HDS — un agent qui élève des privilèges seul est un risque inacceptable.
8.3. pHash global pour détecter un modal
Voir §6.4. Utiliser screenshot diff zoné + OCR titre.
8.4. Polling VLM principal à chaque tick
Latence Qwen2.5-VL = 8-11 s par appel (synthèse MIGRATION_VLM_PLAN_2026-05-09.md). Détection modal doit rester < 100 ms — sinon on bloque la boucle replay. Le VLM est appelé uniquement quand le ChangeDetector signale is_modal=True ET que le catalogue texte n'a pas matché.
8.5. Tenter de "désactiver" Windows Hello programmatiquement
Solution = config humaine pré-démo, pas action runtime de l'agent. L'agent détecte et escalade, il ne modifie pas la config sécurité Windows.
9. Liens forts avec les autres AXES et la dette projet
- AXE_A4 (OCR/Template/pHash) : la détection modal réutilise screenshot diff zoné — surface à coordonner avec la décision pHash de A4 (pas pHash global ici).
- AXE_A5 (Screen Tokenization) : un parser d'écran qui produit la liste de regions interactives détecte aussi les "boutons de modaux" — la classification peut bénéficier de cette liste sans coût VLM supplémentaire.
- AXE_B2 (Validator) : dépendance forte. Un Validator strict (texte attendu présent dans la zone visée) force l'appel au DialogResolver quand le check post-action échoue. Sans ce couplage, un modal non vu reste un échec silencieux (cf. bug step 10 démo 8 mai : Imagerie cliqué dans bandeau Edge, REPORT success=True).
- AXE_A3 (Bench Protocol) : ajouter un harness "modal injection" — pendant un replay test, injecter UAC simulé / popup métier / SmartScreen factice, mesurer detect→classify→resolve latency et taux pause vs auto-dismiss.
- DETTE existante : DETTE-008 (
if False:pré-check VLM par-clic,observe_reason_act.py:1704-1713) sera résolue par le ChangeDetector léger — on n'a plus besoin d'un VLM par clic, le détecteur fait le filtrage en amont. feedback_capture_purge_policy.md: screenshots de DialogEvent à conserver pour audit (RGPD / HDS) — politique de rétention à valider avec Dom.
10. Sources (liens cliquables)
Frameworks comparés (publications, blogs, papers)
- Anthropic Computer Use tool — docs API
- Anthropic Claude Desktop browser permissions controversy (avril 2026)
- Anthropic — Auto Mode permission classifier (mars 2026)
- OpenAI Operator System Card
- OpenAI ChatGPT Agent System Card — juillet 2025
- ChatGPT Agent — login takeover + screenshot OFF
- Skyvern — AI RPA Guide (oct. 2025)
- Skyvern — API-less Legacy System Automation (mai 2026)
- Skyvern GitHub — Planner-Actor-Validator
- browser-use — Issue #1996 : Need Robust Strategy for Handling Dynamic Popups (ouvert mai 2026)
- OmniParser V2 — Microsoft Research
- OmniParser arXiv 2408.00203
- UI-TARS arXiv 2501.12326
Détection popup, classifiers légers
- PopSweeper — arXiv 2412.02933 (déc. 2024)
- PopSweeper — HTML lecture directe
- ShowUI — arXiv 2411.17465 (2B GUI grounding)
- ZonUI-3B cross-resolution GUI grounding
Sécurité Windows 11 / browser
- Microsoft KB UAC fixes oct. 2025 → janv. 2026 — Microsoft Q&A
- NinjaOne — Change UAC Behavior Windows 11
- CVE-2026-0628 Chrome Gemini Live panel takeover
- AI-powered phishing leveraging camera/mic permissions (2026)
Safety gates / human-in-the-loop healthcare
- Agentic Workflow Approval Gate Framework (4 gate types)
- AI Agents for Healthcare — Architecture and Safety Guide (Momentum)
- Human-in-the-Loop Agentic AI (Elementum)
Références internes (à charger en parallèle de ce doc)
docs/SYNTHESE_TECHNOS_REPLAY_2026-05-23.md(synthèse maîtresse)docs/LESSONS_LEARNED_GHT_2026-05.md(zones popup F5.5.1, F6.1.1, DETTE-008)core/grounding/dialog_handler.py(commit487bcb861)memory/feedback_popup_vlm.md(VLM post-clic, pas ctypes seul)memory/feedback_lea_reflexes_catalog.md(gesture_catalog autorisé, pas hardcode ad hoc)memory/feedback_phash_vs_dialog_in_vm.md(pas pHash global)memory/feedback_100pct_visual.md(jamais raccourci inventé)memory/feedback_auth_dialogs_runtime.md(anticiper Hello/UAC/Basic Auth AVANT démo)
11. Hors-périmètre de ce doc
À demander à Dom si besoin avant action :
- Décision finale sur unification
_handle_possible_popuporphelin vs_handle_popup_vlm(les deux côté client). - Politique de rétention RGPD/HDS des screenshots
DialogEvent(par défautdata/runner_captures/dialogs/purge ACK serveur). - Choix exact du modèle VLM compact pour la classification fallback (qwen3-vl:8b acceptable mais ignore parfois
format=jsonOllama — voir §2.4 synthèse). - Bench de la latence
ChangeDetectorsur capture réelle 2560×1600 (cible < 50 ms à vérifier empiriquement). - Politique sur la suppression auto de toasts (Teams, Outlook) pendant démo : déclaratif "do not disturb" en amont vs détection runtime.
Document de recherche. Lecture seule. Toute mise en code = décision explicite Dom puis chirurgie itérative supervisée (CLAUDE.md projet).