fix: VLM guard rejects following-count as 'hallucinated nav tab' + back-press circuit breaker

Root cause: VLM Structural Guard enforced 'must be at bottom' for ALL
NAV_INTENT_KEYWORDS including 'following'/'follower'. But these are
profile stats at Y≈246 (top of screen), not nav tabs. The inner
_structural_sanity_check correctly checks for 'tab' in intent before
enforcing bottom-zone requirement — the VLM guard was inconsistent.

Fix 1: Align VLM guard with inner guard — only enforce bottom-zone
       requirement for intents explicitly containing 'tab'.

Fix 2: Add back-press circuit breaker (MAX_CONSECUTIVE_BACK=3). If GOAP
       presses back 3 times on the same screen without any transition,
       abort immediately to prevent exiting Instagram entirely.

95 unit tests pass.
This commit is contained in:
2026-04-24 21:58:52 +02:00
parent 8f8efe6f2a
commit 82bf931b0e
3 changed files with 133 additions and 5 deletions

View File

@@ -965,6 +965,8 @@ class GoalExecutor:
steps_taken = []
last_action = None
last_screen_type = None
consecutive_back_presses = 0
MAX_CONSECUTIVE_BACK = 3
explored_nav_actions = set()
for step_num in range(max_steps):
# PERCEIVE
@@ -976,6 +978,7 @@ class GoalExecutor:
f"📍 [GOAP State] Screen transitioned from {last_screen_type.name} to {screen_type.name}. Clearing explored actions."
)
explored_nav_actions.clear()
consecutive_back_presses = 0 # Progress was made
# ── Loop Prevention: Mask Failed Actions ──
MAX_RETRIES = 2
@@ -1044,6 +1047,19 @@ class GoalExecutor:
explored_nav_actions.add(action)
# Reset failures for this action since it eventually succeeded
self.action_failures[action] = 0
# ── Back-Press Circuit Breaker ──
if action == "press back":
consecutive_back_presses += 1
if consecutive_back_presses >= MAX_CONSECUTIVE_BACK:
logger.error(
f"🛑 [GOAP] Back-pressed {MAX_CONSECUTIVE_BACK} times with no screen transition. "
f"Aborting goal '{goal}' to prevent app exit."
)
self.path_memory.learn_path(goal, start_screen, steps_taken, False)
return False
else:
consecutive_back_presses = 0
else:
self.action_failures[action] = self.action_failures.get(action, 0) + 1
# Track failed actions in explored_nav_actions so the planner

View File

@@ -2085,11 +2085,10 @@ class TelepathicEngine:
# NAVIGATION TAB ENFORCEMENT:
# Real navigation tabs (Home, Search, Reels, Store, Profile) are ALWAYS in the bottom zone.
# If the bot is looking for a tab, forbid results that are too high up (likely hallucinations on comments/feed).
if is_nav_intent:
# Navigation tabs (Home, Search, Reels, News, Profile) are strictly at the bottom.
# On many devices with virtual buttons, they are roughly at 0.94 - 0.98.
# On full-screen gesture devices, they might be slightly higher.
# We use 0.92 as a firm structural boundary.
# IMPORTANT: Only enforce for intents explicitly containing "tab".
# "following"/"follower" are profile stats at the TOP of the screen, not tabs.
# This aligns with _structural_sanity_check which has the same "tab" guard.
if is_nav_intent and "tab" in intent.lower():
if match.get("y", 0) < screen_height * 0.92:
logger.warning(
f"🛡️ [Structural Guard] VLM hallucinated a navigation tab '{intent}' "