Bug 1 — VLM Profile Tab Hallucination:
- VLM confused 'Profile' nav tab with post author username
- Added Author Tab Guard to filter_navigation_conflicts()
- Fixed mock LLM to use structural row_feed_photo_profile matching
instead of hardcoded username (was the test lie)
Bug 2 — Like Button 1-Byte Delta Kill:
- Toggle actions (like/save) produce 1-byte XML deltas
- GOAP's MIN_UI_CHANGE_BYTES=50 threshold killed them as 'no change'
- Split interaction gate: interactions use ANY xml diff, navigations
keep the 50-byte threshold
Bug 3 — Empty Username Silently Accepted:
- PostDataExtraction returned 'Post by @' with no warning
- Added 'username_missing' reliability flag to result dict
- Downstream consumers can now detect degraded data quality
Cleanup:
- Removed all debug print() statements from production code
- Replaced with structured logger.debug() calls
1. ScreenIdentity: Add structural Reels detection (clips_viewer_container,
root_clips_layout) for full-screen Reels where Instagram hides tab bar.
Without this, selected_tab=None → UNKNOWN → death spiral.
2. IntentResolver: Navigation Bar Zone Guard constrains tab intents
(tap profile/home/explore tab) to bottom 15% of screen. Prevents
VLM from selecting content profile pictures instead of nav tabs.
Also fixes abstract goal filter substring match blocking tab intents.
3. GOAP Executor: Wires unlearn_transition into HD Map validation failure.
When expected screen != actual screen, poisoned Qdrant vectors are
purged to prevent re-use of broken paths.
Cleanup: Replace all print(DEBUG...) with proper logger.debug() calls.
Cleanup: Fix ruff F841 unused variable goal_met.
TDD: 5 new E2E tests, 65 total passing, 0 regressions.