ROOT CAUSE: The bot was systematically sabotaging its own navigation.
The HD Map planned correct 2-step routes (Home→Profile→FollowList),
but _execute_action() validated each INTERMEDIATE step against the
FINAL goal. Step 1 (tap profile tab → OWN_PROFILE) got rejected
because the goal said 'following', triggering aversive learning
that permanently burned the only valid route.
SIX COMPOUNDING FIXES:
1. SSOT Consolidation (_is_goal_achieved):
Replaced 12-line hardcoded if-chain with ScreenTopology.goal_to_target_screen().
Single source of truth for all goal→screen mappings.
2. Step-Aware Navigation Validation (_execute_action):
Replaced goal_screen_map keyword-scan with
ScreenTopology.expected_screen_for_action(action, pre_action_screen).
Now validates: 'did this step land where IT should?' not 'did I reach my goal yet?'
3. Topology Guard (aversive learning):
ScreenTopology.is_structural_action() prevents burning HD Map actions.
VLM may fail to find the element, but the route itself is structurally valid.
4. Fast-Path Threshold Fix (telepathic_engine):
100% match threshold now applies only to NAV_TAB_KEYWORDS (actual tabs),
not NAV_ZONE_BYPASS_KEYWORDS. 'tap following list' was blocked because
'following' triggered the tab threshold on a non-tab action.
5. navigate_to_screen SSOT:
Replaced 8-entry goal_map dict with ScreenTopology.screen_name_to_goal().
6. QNavGraph Name Map Dedup:
Replaced 2 inline screen_name_map/name_to_screen dicts with
ScreenTopology.SCREEN_NAME_MAP reverse lookups.
Before: 4 competing goal→screen mappings. Self-sabotage loop.
After: 1 SSOT. Step-aware validation. Topology-protected routing.
141 unit tests pass. Zero regressions.