From c9878f0a765221dc6fcbd947a6597539a87c1e14 Mon Sep 17 00:00:00 2001 From: Dom Date: Sun, 24 May 2026 17:59:35 +0200 Subject: [PATCH] fix(validator-v2): override success=False uniquement sur TERMINATE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptôme observé sur replay_sess_7a4c8e72 (24/05 17:57) : - Action act_setup_sess_verify (type=verify_screen) échoue 4x (+3 retries) - Logs: [VALIDATOR_V2] override success→False verdict=continue conf=0.30 failure_category=None reason='Aucun changement visible pour verify_screen (normal pour ce type d'action)' - Replay tombe en status=error à 7/15 (régression vs 12/15 sans V2) Cause: api_stream.py:3674 testait `if verdict != COMPLETE` (trop large) → toute action qui ne change pas drastiquement l'écran (verify_screen, wait, key_combo Ctrl+S avant ouverture dialog, etc.) renvoie verdict=CONTINUE conf=0.30 du PixelDiffChecker via le default_checker de l'orchestrator, ce qui était traité comme un échec à overrider. Fix: override SEULEMENT sur verdict=TERMINATE (échec certain avec failure_category). CONTINUE = faible signal = on laisse le pipeline historique trancher. COMPLETE n'a pas besoin d'être traité ici car on est déjà dans `if report.success:` (success initial vrai). Effet: - verify_screen/wait/key_combo non-interactif → orchestrator retourne CONTINUE conf=0.30 → V2 ne touche pas report.success (comportement legacy préservé) - click qui rate (act_raw_6c1432b3 type cible) → OcrRoiChecker retourne TERMINATE conf=0.85 failure_category=WRONG_APPLICATION → override OK Tests R1 inchangés (TERMINATE branch testée explicitement). Co-Authored-By: Claude Opus 4.7 (1M context) --- agent_v0/server_v1/api_stream.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/agent_v0/server_v1/api_stream.py b/agent_v0/server_v1/api_stream.py index 37c1bca78..860e438a4 100644 --- a/agent_v0/server_v1/api_stream.py +++ b/agent_v0/server_v1/api_stream.py @@ -3671,7 +3671,12 @@ async def report_action_result(report: ReplayResultReport): context={}, ) from core.validation import Verdict as _V2Verdict - if validator_v2_result.verdict != _V2Verdict.COMPLETE: + # Override success=False UNIQUEMENT sur TERMINATE (échec certain). + # CONTINUE (= "je ne sais pas, faible signal") ne doit PAS + # bloquer le pipeline historique — sinon les actions sans + # changement visuel attendu (verify_screen, wait, key_combo) + # échouent en cascade (cf. replay_sess_7a4c8e72 17:57). + if validator_v2_result.verdict == _V2Verdict.TERMINATE: validator_v2_failure_category = ( validator_v2_result.failure_category.value if validator_v2_result.failure_category else None