FOLLOW PLUGIN SAFETY GUARD:
- Added pre-click XML guard: checks button text before clicking
- If button says 'Following'/'Requested'/'Message' → SKIP
(prevents opening dangerous Unfollow/Add-to-Favorites bottom sheet)
- Changed intent from 'tap Follow or Following button' to 'tap follow button'
- This was the root cause of adding users to Close Friends/Favorites
VLM VERIFICATION RESILIENCE:
- VLM false no longer shortcircuits to return False
- VLM verdict is now a SOFT SIGNAL that falls through to structural
delta verification as ground-truth tiebreaker
- Small local VLMs (7B llava) systematically return false for everything
- This was THE root cause of memory poisoning: every action got penalized
because VLM always said 'failed', regardless of actual screen state
- 22 total poisoned Qdrant entries purged across two sessions
ROOT CAUSE CHAIN:
VLM always says false → penalties on every action → confidence < 0.2 →
circuit breaker blocks ALL core actions → bot can't like/follow/comment
→ bot clicks random things → adds to favorites, opens bottom sheets
TDD: 4 new tests, full suite 110/111 (1 infra flake)
CLOSE FRIENDS GUARD:
- Replaced broken text-only detection ('enge freunde'/'close friend')
with STRUCTURAL resource-id marker detection:
* friendly_bubbles_component (feed posts)
* profile_header_close_friend (profile view)
* close_friends_badge (Reels)
* close_friends_star (green star)
- Kept legacy text fallback for edge cases
- TDD: 5 tests including meta-test enforcing structural detection
CONTEXT MEMORY CIRCUIT BREAKER:
- Old system: single failure permanently blocks action (confidence < 0.2 = dead)
- New system: time-based decay — failures older than 1 hour are auto-forgiven
and the poisoned entry is DELETED, allowing re-exploration
- This prevents catastrophic self-sabotage where the bot blocks its own
core actions (tap like, tap follow, tap comment) permanently
- Purged 14 poisoned entries from live Qdrant that were blocking ALL
fundamental interactions
- TDD: 2 meta-tests enforcing time-decay and no permanent blocking
Full suite: 106/107 passed (1 infra flake)
- Removed hardcoded (540,150) fallback in _plan_escape_via_llm
- Added _find_structural_dismiss_target: scans raw XML for clickable
dismiss/cancel/close buttons and extracts coords from bounds attrs
- LLM repeat detection now falls back to structural scan (not magic numbers)
- Temperature increases progressively when LLM is stubborn (0.1 → 0.7)
- Failure history injected as CRITICAL block into LLM system prompt
- Extended pre-commit test discovery to include tests/tdd/
- TDD: 7 new tests including meta-tests proving zero hardcoded coords
- Full suite: 100/100 passed
1. Add long_clickable and class_name to SpatialNode and box_legend.
2. Inject strict guardrails into the SoM prompt to prevent EditText, Recents gallery, and long_clickable hallucinations.
3. Update text-based resolver with equivalent extreme fallback rules.
4. Ensures VLM explicitly rejects non-deterministic edge cases (e.g., Select Album).
- Updated e2e_workflow_ctx in conftest to structurally parse screen_type
- Fixed StoryViewPlugin to gracefully handle pre-existing story screens
- Resolved 'LIE DETECTED' failure in story test suite
- Validated structural path transitions for story ring and story exit
P0-2: Kill blank_start: true in config — the nuclear option that wipes ALL learned
knowledge on every run. Replaced with memory_hygiene() selective amnesia that
prunes low-confidence entries while preserving high-confidence learned patterns.
P0-3: Purge all root-level garbage scripts (scratch.py, test_run.py, profile_dump.xml,
resp_dump.json, pytest_output.log, test_output.log, coverage.xml, coverage_e2e.json).
Updated .gitignore to prevent reaccumulation.
P2-2: Replace piecemeal BANNED_SCREENS/REQUIRED_MARKERS with complete Action
Compatibility Matrix (VALID_SCREENS whitelist). Every interaction intent now has
an explicit set of valid screens. Covers like, comment, follow, unfollow, save,
repost across all 14 screen types.
P2-3: Remove non-deterministic 'press back' transitions from HD Map topology for
OTHER_PROFILE, POST_DETAIL, and SEARCH_RESULTS. Add tab transitions to POST_DETAIL.
P2-4: Replace ScreenMemoryDB nuclear 200-entry wipe with LRU eviction.
store_screen() now accepts confidence parameter.
TDD: 22 new tests (all GREEN), 240 unit/tdd/integration passed, 0 regressions.
E2E: 288 passed (+2 fixed), 6 pre-existing LIE DETECTED failures.
- Raised ContentMemoryDB cache threshold from 0.95 to 0.98 to prevent cross-post poisoning.
- Implemented continuous resonance scoring by storing and retrieving 'resonance_score'
in ContentMemoryDB.
- ResonanceEngine now prioritizes high-fidelity raw scores from cache over
discrete 'high/medium/low' mapping.
TDD: 3 tests verifying threshold and scoring logic integrity.
- Fixed .gitignore to correctly handle __pycache__ even when inside whitelisted directories (like tests/).
- Moved pycache ignore patterns to the end of the file to ensure they take absolute precedence over any directory-level whitelists.
- Purged all previously tracked .pyc and __pycache__ files from the git index.
- Cleaned up .hypothesis and .pytest_cache artifacts.
This enforces 'Militärische Git-Disziplin' (Rule 7) and keeps the repo clean of environment-specific junk.
- Raised similarity_threshold from 0.90 to 0.95 in get_screen_type() to eliminate
POST_DETAIL false-positives caused by embedding saturation.
- Implemented purge_stale_screens() with 24h TTL to remove layout drift.
- Added collection size cap (200 points) to store_screen() with automatic wipe
when saturated to clear overfitting bias.
- Triggered purge_stale_screens() on ScreenIdentity initialization.
TDD: 3 new tests for threshold defaults and purge method integrity.
1. ScreenIdentity: Restructured priority cascade to prevent Qdrant semantic
cache from overriding deterministic structural heuristics. Cached types
now resolve AFTER structural checks (Priority 3) instead of before.
Story/Reels hallucinations from both cache and VLM are rejected if
structural markers are absent.
2. bot_flow: Added error handling for story ring avatar tap and curiosity
HomeFeed navigation failures — prevents silent continuation into
undefined states.
3. GOAP: Extended is_navigation detection to include ScreenTopology
structural actions, ensuring HD Map routes are correctly classified.
4. action_memory: Tightened _parse_yes_no to prevent JSON fall-through
into ambiguous text matching. Structured responses with 'success'
boolean are now handled directly.
The SAE perceive() had no structural fast-path for Instagram-internal
modal overlays (surveys, rating prompts, interstitials). These modals
live inside com.instagram.android and were invisible to the foreign-app
detector. The LLM fallback frequently misclassified them as NORMAL,
causing the bot to get trapped in survey dialogs.
Added two O(1) structural detection layers:
1. Resource-ID markers: survey_overlay_container, interstitial_container,
mystery_interstitial, nux_overlay, rating_prompt, feedback_dialog
2. Dismiss-button heuristic: cross-validates dismiss text with overlay
container structure to prevent caption false positives
Also removed dead code: xml_dump.lower() no-op.
Fixes: test_perceive_instagram_survey_modal
Zero regressions: 464 passed, 6 pre-existing failures
- device_emulator.py: Replace MagicMock(watcher) with explicit WatcherStub
that implements exact u2 watcher chain (when/click/start). Any API drift
now causes AttributeError instead of silent acceptance.
- test_system_sae.py: Inject XML into emulator state instead of bypassing
dump_hierarchy with lambda
- test_behavior_ad_guard.py: Pass XML to fixture, remove lambda override
- test_behavior_scrape_profile.py: Pass XML to fixture, remove lambda override
Result: ZERO unittest.mock imports, ZERO MagicMock instances,
ZERO dump_hierarchy lambdas across entire E2E suite (50 files).