Bug observé sur replay_sess_63a1313b 2026-05-24 18:31-18:32 :
_capture_human_correction() côté Léa retourne des human_actions sans
clic humain réel (cause racine côté agent à investiguer = P0.6).
En cascade, memory_record_success était appelé avec coords (0.0, 0.0)
et stockait des entrées poison dans target_memory.db.
Le sanity check existant rejetait < 0 ou > 1 mais laissait passer (0,0)
qui est mathématiquement valide. Au prochain replay, memory_lookup
trouvait l'entrée poison et faisait cliquer Léa au coin haut-gauche.
Patch : rejet explicite de (0,0) + warning au lieu de debug pour les
coords hors [0,1] (besoin de tracabilité runtime).
Filet en aval — la vraie cause côté Léa reste à corriger (P0.6).
Tag rollback : rollback/pre-P0.7-2026-05-24_1850
P0-B — /api/v1/traces/stream/image retiré de _PUBLIC_PATHS :
- Bearer token obligatoire pour upload d'image
- Évite uploads anonymes de contenu arbitraire
P0-C — Fail-closed si RPA_API_TOKEN absent :
- sys.exit(1) au démarrage avec message fatal
- Mode dev : RPA_AUTH_DISABLED=true pour désactiver explicitement
- Log INFO des 8 premiers chars du token (diagnostic)
Fix target_memory prefix empilé :
- Strip "memory_" répétés avant stockage dans replay_memory.py
- Évite "memory_memory_memory_template_matching" en base
live_session_manager : améliorations mineures de la gestion sessions.
10 tests auth API stream.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greffe minimale du mécanisme d'apprentissage persistant (Fiche #18,
target_memory_store.py) sur le pipeline streaming V4 sans toucher à V3.
Architecture (docs/PLAN_APPRENTISSAGE_LEA.md) :
- Lookup mémoire AVANT la cascade résolution coûteuse OCR/template/VLM
dans _resolve_target_sync → hit = <10ms, miss = overhead zéro
- Record APRÈS validation post-condition (title_match strict)
dans /replay/result → 2 succès → cristallisation par répétition
- Single source of truth : l'agent remplit report.actual_position avec
les coords effectivement cliquées, le serveur les lit directement.
Pas de cache intermédiaire (option C du plan).
Signature écran V4 : sha256(normalize(window_title))[:16]. Robuste aux
données variables, faux positifs rattrapés par le post-cond qui
décrémente la fiabilité via record_failure().
Fichiers :
- agent_v0/server_v1/replay_memory.py : nouveau wrapper 316 lignes
exposant compute_screen_sig/memory_lookup/record_success/failure,
lazy-init du store, normalisation texte stable, garde sanity coords
- agent_v0/server_v1/resolve_engine.py : lookup mémoire en tête de
_resolve_target_sync (30 lignes)
- agent_v0/server_v1/replay_engine.py : _create_replay_state stocke
une copie slim des actions (sans anchor base64) pour retrouver le
target_spec par current_action_index
- agent_v0/server_v1/api_stream.py : 4 callers passent actions=...,
record success/failure dans /replay/result lit actual_position
du rapport (click-only), correction du commentaire Pydantic
- agent_v0/agent_v1/core/executor.py : remplit result["actual_position"]
après self._click(), transmis dans le report de poll_and_execute
Tests : 56 E2E + Phase0 passent, zéro régression. Cycle Phase 1 validé
en simulation : miss → record → miss → record → HIT au 3ème passage.
Le deploy copy executor.py a une divergence pré-existante de 1302
lignes non committées — traité séparément lors du cleanup prochain.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>